diff --git a/ACCOUNTS b/ACCOUNTS new file mode 100644 index 0000000..6fd1057 --- /dev/null +++ b/ACCOUNTS @@ -0,0 +1,6 @@ +List of accounts: + +banderson -> sysadmin for everything. Should be able to go everywhere...but maybe not canvas? +jclark484, janderson -> log in to canvas (at least right now) TODO: get some people based on the course groups later + +kbrown -> banned from the portal. (Math students and math students aren't allowed to use the portal) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bb5a04e --- /dev/null +++ b/Makefile @@ -0,0 +1,58 @@ +# -*- make -*- +# +# Makefile, DESCRIPTION +# +# Copyright (C) 2017 Jonathan J. Miner +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Jonathan J. Miner + +all: ldap-tgt mysql-tgt rabbit-tgt sis-tgt shib-idp-tgt grouper-tgt webapp-tgt canvas-tgt attribute-tgt + +# Build the dependency containers +ldap-tgt: + docker build deps/ldap -t tier-demo-ldap +mysql-tgt: + docker build deps/mysql -t tier-demo-mysql +rabbit-tgt: + docker build deps/rabbit -t tier-demo-rabbit + +# build the sis web app +sis-tgt: + docker build sis-app -t tier-sis-web + +# Build the Shib IDP +shib-idp-tgt: + docker build shib-idp -t tier-demo-idp + +# Build Grouper +grouper-tgt: + docker build grouper -t tier-demo-grouper + +# Build Midpoint +#docker build midpoint -t tier-demo-midpoint + +# build the demo app +webapp-tgt: + docker build test-app -t tier-demo-web-app + +# build the canvas provisioner +canvas-tgt: + docker build canvas -t tier-demo-canvas + +# build the attribute slammer +attribute-tgt: + docker build attribute-slammer -t tier-demo-attribute-slammer + + +# vim: set noet: diff --git a/README.md b/README.md new file mode 100644 index 0000000..9893977 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +## Overview +This set of docker images supports a demonstration of the TIER architecture, and +how it can be used for role-based access control (RBAC) in a complex setting. +For more information about this demo, see [Tier Canvas Provisioning Demo - +TechEx +2017](https://docs.google.com/presentation/d/1RT448nvR3gZ2hFUteqSQ6LgOYMwlgua0x0hQBZFrVWE/edit#slide=id.p) + +` +The Group Docker image is based on Unicon's work, and contains a fully built Ldap, MySql, and Grouper environment. The Grouper component has the Grouper UI, Grouper Web Services, and an active Grouper Daemon which runs the Grouper Loader and PSP modules. + +> This image does not follow best Docker practices. It is intended from demo/class usage. It can also be useful for use as a base image for Grouper development. + +## Building + +To build the demo: + +``` +./build.sh +``` +In order to configure the Canvas provisioning components, you'll need a Canvas +instance and will need to generate an API key. Please see [Getting Started With +the Canvas +API](https://canvas.instructure.com/courses/785215/pages/getting-started-with-the-api) +for more information about this. + +There are a number of containers in the demo, so you may need to increase RAM +devoted to Docker. The demo seems to run well with 4 CPUs and 4GB. + +## Running + +To run the demo: + +``` +$ [TODO: INSERT DOCKER COMPOSE COMMAND HERE] +``` + +You can log into the Grouper UI with "banderson/password". The account is a sysadmin. Also available is "jsmith/password", which has no explicit privs. There are lots of "user" accounts that have dumby course memberships. + +TODO: change admin account to "tieradmin"? + +The LDAP admin bind account is "cn=admin,dc=example,dc=edu/password". The MySql admin account is "root/". + +This will build each container needed. + +## Authors + * James Babb (james.babb@wisc.edu) + * Tom Jordan (tom.jordan@wisc.edu) + * TIER API & Entity Registry Working Group (tier-api@internet2.edu) + + * Based on Unicon Grouper Demo Container by: + * John Gasper (jgasper@unicon.net) + * David Langenberg (dlangenberg@unicon.net) + +## LICENSE + + diff --git a/attribute-slammer/Dockerfile b/attribute-slammer/Dockerfile new file mode 100644 index 0000000..27ca843 --- /dev/null +++ b/attribute-slammer/Dockerfile @@ -0,0 +1,23 @@ +FROM perl:latest + +MAINTAINER "TIER API & EntReg Working Group " + +# ENV PERL5LIB /usr/local/lib/perl5/site_perl/5.26.0/ + +RUN set -x; \ + apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y netcat vim \ + && apt-get clean + +RUN set -x; \ + cpanm App::cpanminus \ + && cpanm REST::Client \ + && cpanm JSON \ + && cpanm YAML \ + && cpanm Getopt::Long \ + && cpanm MIME::Base64 + + +COPY attributeSlammer /opt/attributeSlammer +WORKDIR /opt/attributeSlammer +CMD [ "./attribute_slam.sh" ] diff --git a/attribute-slammer/attributeSlammer/attribute_slam.pl b/attribute-slammer/attributeSlammer/attribute_slam.pl new file mode 100755 index 0000000..e746d8b --- /dev/null +++ b/attribute-slammer/attributeSlammer/attribute_slam.pl @@ -0,0 +1,209 @@ +#!/usr/bin/perl -w +# $Id$ +# +# Slams attributes on given stems in the config file. +# +# Author: James Babb +# $Date: 2016-07-05 11:43:20 -0500 (Tue, 05 Jul 2016) $ +# +use strict; +use warnings; +use Data::Dumper; +use JSON; +use REST::Client; +use YAML qw/LoadFile Dump/; +use Getopt::Long; +use MIME::Base64; + +# +# 1. Pull in the config +# 2. Set up the environment +# 3. for each slam: +# a. build out request to retrieve matching groups +# b. retrieve list of groups +# c. for each group: +# i. build out request to see if attribute already set with value +# ii. if value is already set: +# - next; +# iii. else: +# - build out request to slam attribute +# - set attribute with value +# +# + +my $config = LoadFile('attribute_slam.yaml'); +my $pw = LoadFile('attribute_slam.pw'); + +# track exit code. Change to something not 0 if a failure but we don't need to hard fail. +my $exit_code = 0; + +my $DEBUG = $config->{debug}; + +print Dumper($config) . "\n" . Dumper($pw) . "\n\n" if ($DEBUG); + +my $client = REST::Client->new(); +$client->setHost( $config->{grp_ws_endpoint} ); +$client->setTimeout( $config->{timeout} ); + +my $encoded_auth = encode_base64( $config->{grp_ws_user} . ":" . $pw->{password} ); + +foreach my $item ( @{ $config->{list} } ) { + + logit( "Working on " . $item->{stem} ); + + my %find_groups = ( + "WsRestFindGroupsLiteRequest" => { + "groupName" => $item->{stem}, + "stemName" => $item->{stem}, + "queryFilterType" => "FIND_BY_GROUP_NAME_APPROXIMATE" + } + ); + + # TODO: because we include the stem, will this match on like uw:domain:AWS and uw:domain:AWS2? + + my $find_groups_json = encode_json( \%find_groups ); + + logit("Sending find groups request with: $find_groups_json \n\n-------\n\n") if ($DEBUG); + + $client->POST( $config->{grp_ws_rest_groups}, + $find_groups_json, + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + + logit( 'Response: ' . $client->responseContent() . "\n" ) if ($DEBUG); + logit( 'Response status: ' . $client->responseCode() . "\n" ) if ($DEBUG); + + if ( $client->responseCode() != 200 ) { + logit("Did not get back a valid search for groups... Skipping\n"); + $exit_code = 255; + next; + } + + my $groups_to_process; + + eval { $groups_to_process = decode_json( $client->responseContent() ); }; + + if ( !defined($groups_to_process) ) { + logit("Did not get valid JSON from Grouper... Skipping\n"); + $exit_code = 255; + next; + } + + foreach my $group ( @{ $groups_to_process->{WsFindGroupsResults}->{groupResults} } ) { + logit( "Checking " . $group->{name} ); + + my %find_attr = ( + "WsRestGetAttributeAssignmentsLiteRequest" => { + "attributeAssignType" => "group", + "includeAssignmentsonAssignments" => "T", + "wsOwnerGroupName" => $group->{name}, + "wsAttributeDefNameName" => $item->{attribute_name} + } + ); + + my $find_attr_json = encode_json( \%find_attr ); + + logit("Sending find attributes request with: $find_attr_json \n\n-------\n\n") if ($DEBUG); + + $client->POST( $config->{grp_ws_rest_attributes}, + $find_attr_json, + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + + logit( 'Response: ' . $client->responseContent() . "\n" ) if ($DEBUG); + logit( 'Response status: ' . $client->responseCode() . "\n" ) if ($DEBUG); + + if ( $client->responseCode() != 200 ) { + logit("Did not get back a valid search for attributes... Skipping group....\n"); + $exit_code = 255; + next; + } + + my $attribute_search; + + eval { $attribute_search = decode_json( $client->responseContent() ); }; + + if ( !defined($attribute_search) ) { + logit("Did not get valid JSON from Grouper... Skipping group...\n"); + $exit_code = 255; + next; + } + + my $found = 0; + + foreach my $attr ( + @{ $attribute_search->{WsGetAttributeAssignmentsResults}->{wsAttributeAssigns} } ) + { + if ( $attr->{attributeDefNameName} eq $item->{attribute_name} ) { + foreach my $value ( @{ $attr->{wsAttributeAssignValues} } ) { + if ( $value->{valueSystem} eq $item->{attribute_value} ) { + logit( + "Attribute $item->{attribute_name} already has value $item->{attribute_value} for group $group->{name}" + ) if ($DEBUG); + $found = 1; + last; + } + } + logit( + "Attribute $item->{attribute_name} has a value but not correct value for group $group->{name}" + ) if ( !$found && $DEBUG ); + } + } + + if ( !$found ) { + logit( + "Need to set $item->{attribute_name} : $item->{attribute_value} for $group->{name}" + ); + + my %slam_attr = ( + "WsRestAssignAttributesLiteRequest" => { + "attributeAssignOperation" => "assign_attr", + "attributeAssignType" => "group", + "attributeAssignValueOperation" => "add_value", + "valueSystem" => $item->{attribute_value}, + "wsAttributeDefNameName" => $item->{attribute_name}, + "wsOwnerGroupName" => $group->{name} + } + ); + + my $slam_attr_json = encode_json( \%slam_attr ); + + $client->POST( $config->{grp_ws_rest_attributes}, + $slam_attr_json, + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + + logit( 'Response: ' . $client->responseContent() . "\n" ) if ($DEBUG); + logit( 'Response status: ' . $client->responseCode() . "\n" ) if ($DEBUG); + + if ( $client->responseCode() != 200 ) { + logit( + "Could not add $item->{attribute_name} : $item->{attribute_value} for $group->{name}. Response: " + . $client->responseContent() + . "\n\n--------\n\n" ); + $exit_code = 255; + } + else { + logit("Added $item->{attribute_name} : $item->{attribute_value} to $group->{name}"); + } + + } + + } + +} + +exit $exit_code; + +# Log a message to the log file specified in the config file. +sub logit { + my $msg = shift; + + # Timestamp + my $tstamp = ''; + my ( $sec, $min, $hr, $day, $mon, $year ) = localtime; + $tstamp = + sprintf( "%04d-%02d-%02d %02d:%02d:%02d", 1900 + $year, $mon + 1, $day, $hr, $min, $sec ); + my $file = $config->{logfile}; + open( my $fh, ">>", $file ) || die "Unable to open log file $file: $!"; + print $fh "$tstamp: $msg\n"; + close($fh); + print STDERR "$tstamp: $msg\n" if ($DEBUG); +} diff --git a/attribute-slammer/attributeSlammer/attribute_slam.pw b/attribute-slammer/attributeSlammer/attribute_slam.pw new file mode 100644 index 0000000..93166c8 --- /dev/null +++ b/attribute-slammer/attributeSlammer/attribute_slam.pw @@ -0,0 +1,2 @@ +# Password for account accessing grouper WS +password: 12345 diff --git a/attribute-slammer/attributeSlammer/attribute_slam.sh b/attribute-slammer/attributeSlammer/attribute_slam.sh new file mode 100755 index 0000000..3547442 --- /dev/null +++ b/attribute-slammer/attributeSlammer/attribute_slam.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Run the attribute slammer forever and ever running every 10 seconds + +cd /opt/attributeSlammer/ +touch slammer.log + +tail -f slammer.log & + +# wait for grouper ws to be available...typically only during first run while +# grouper is still boot strapping +until nc -vz tier-demo-grouper 8080 +do + echo "Grouper WS is unavailable - sleeping" + sleep 5 +done + +while true +do + perl attribute_slam.pl + sleep 10 +done diff --git a/attribute-slammer/attributeSlammer/attribute_slam.yaml b/attribute-slammer/attributeSlammer/attribute_slam.yaml new file mode 100644 index 0000000..015caea --- /dev/null +++ b/attribute-slammer/attributeSlammer/attribute_slam.yaml @@ -0,0 +1,34 @@ +# Config file for attribute slammer. +grp_ws_endpoint: http://tier-demo-grouper:8080 +grp_ws_rest_attributes: /grouper-ws/servicesRest/json/v2_2_000/attributeAssignments +grp_ws_rest_groups: /grouper-ws/servicesRest/json/v2_2_000/groups +grp_ws_user: tjordan +timeout: 10 +debug: 0 +verbose: 1 +logfile: "/opt/attributeSlammer/slammer.log" +list: + # Portal, Grouper, SIS, and ref tree are all released to portal SP + # since that is the proxy to all of those apps + # Ref released just for demonstration purposes + - stem: "app:grouper" + attribute_name: "etc:attribute:ShibEntityId:ShibEntityId" + attribute_value: "https://localhost:9443/shibboleth" + - stem: "app:sis" + attribute_name: "etc:attribute:ShibEntityId:ShibEntityId" + attribute_value: "https://localhost:9443/shibboleth" + - stem: "app:portal" + attribute_name: "etc:attribute:ShibEntityId:ShibEntityId" + attribute_value: "https://localhost:9443/shibboleth" + - stem: "ref" + attribute_name: "etc:attribute:ShibEntityId:ShibEntityId" + attribute_value: "https://localhost:9443/shibboleth" + # Nothing to TIER Canvas instance...but if you wanted to: +# - stem: "app:canvas" +# attribute_name: "etc:attribute:ShibEntityId:ShibEntityId" +# attribute_value: "http://tier.instructure.com/saml2" +# # The bundles such as "All Students" are default release to every SP: + - stem: "bundle" + attribute_name: "etc:attribute:ShibEntityId:ShibEntityId" + attribute_value: "DEFAULT" + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..d2e35ca --- /dev/null +++ b/build.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Build the dependency containers +docker build deps/ldap -t tier-demo-ldap +docker build deps/mysql -t tier-demo-mysql +docker build deps/rabbit -t tier-demo-rabbit + +# build the sis web app +docker build sis-app -t tier-sis-web + +# Build the Shib IDP +docker build shib-idp -t tier-demo-idp + +# Build Grouper +docker build grouper -t tier-demo-grouper + +# Build Midpoint +#docker build midpoint -t tier-demo-midpoint + +# build the demo app +docker build test-app -t tier-demo-web-app + +# build the canvas provisioner +docker build canvas -t tier-demo-canvas + +# build the attribute slammer +docker build attribute-slammer -t tier-attribute-slammer diff --git a/canvas/Dockerfile b/canvas/Dockerfile new file mode 100644 index 0000000..7bdee01 --- /dev/null +++ b/canvas/Dockerfile @@ -0,0 +1,22 @@ +FROM perl:latest + +MAINTAINER "TIER API & EntReg Working Group " + +# ENV PERL5LIB /usr/local/lib/perl5/site_perl/5.26.0/ + +RUN set -x; \ + apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y netcat vim \ + && apt-get clean + +RUN cpanm App::cpanminus +RUN cpanm Net::RabbitFoot +RUN cpanm Net::RabbitMQ --force +RUN cpanm Net::AMQP::RabbitMQ --force +RUN cpanm AnyEvent +RUN cpanm REST::Client +RUN cpanm JSON + +COPY . /usr/src/canvas_provisioner +WORKDIR /usr/src/canvas_provisioner +CMD [ "./run_canvas.sh" ] diff --git a/canvas/build.sh b/canvas/build.sh new file mode 100755 index 0000000..8f25855 --- /dev/null +++ b/canvas/build.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# build.sh, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan +docker build -t tier-demo-canvas . diff --git a/canvas/canvas.pl b/canvas/canvas.pl new file mode 100755 index 0000000..fc49a1e --- /dev/null +++ b/canvas/canvas.pl @@ -0,0 +1,480 @@ +#!/usr/local/bin/perl -w +# +# net_amqp_rabbit.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: net_amqp_rabbit.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use Net::AMQP::RabbitMQ; +use Data::Dumper; +use JSON; +use REST::Client; +use YAML qw/LoadFile Dump/; +use MIME::Base64; + +# load config +my $config = LoadFile('config.yml'); +my $debug = $config->{debug}; +print "Dumping config:\n" . Dumper($config) . "\n" if ($debug); + +my $channel = 1; +my $exchange = $config->{rabbit_exchange}; +my $routing_key = $config->{rabbit_routing_key}; + +my $mq = Net::AMQP::RabbitMQ->new(); +$mq->connect($config->{rabbit_host}, { user => $config->{rabbit_user}, password => $config->{rabbit_pass} }); +$mq->channel_open($channel); +# Declare queue, letting the server auto-generate one and collect the name +my $queuename = $mq->queue_declare($channel, ""); +print "Queuename: $queuename\n" if ($debug); +# Bind the new queue to the exchange using the routing key +#$mq->queue_bind($channel, $queuename, $exchange, $routing_key); +$mq->queue_bind($channel, $queuename, $exchange, $routing_key); +# Request that messages be sent and receive them until interrupted +$mq->consume($channel, $queuename); + +print "Waiting for ESB events to process...\n"; + +while ( my $message = $mq->recv(0) ) + { + print "Received message:\n" . Dumper($message) . "\n" if ($debug); + + my $body = from_json($message->{body}); + print "Body: \n" . Dumper($body) . "\n" if ($debug); + #print "Event Type: $body->{esbEvent}->[0]->{eventType}\n"; + #print "Group Name: $body->{esbEvent}->[0]->{groupName}\n"; + #print "SubjectId: $body->{esbEvent}->[0]->{subjectId}\n"; + + # TODO: + # 1. Determine message type (GROUP_ADD vs. MEMBERSHIP_ADD + # 2. Get user / group info from Grouper WS + # 3. Collect user memberships from Grouper WS + # 4. Check if user / course exists in canvas + # 5. Get course enrollments in canvas + # 6. Compare canvas course enrollments to grouper course enrollments + # 7. Enroll, Unenroll as needed + + if ($body->{esbEvent}->[0]->{eventType} eq 'GROUP_ADD') { + #my ($coursename) =~ m/^ref\.courses\.(.*)$/,$body->{esbEvent}->[0]->{name}; + my $fullCourseName = $body->{esbEvent}->[0]->{name}; + print "Full Course Name: $fullCourseName\n" if ($debug); + my ($coursename) = $fullCourseName =~ m/^ref:courses:(.*)$/; + print "Got Group Add for course: $coursename\n" if ($debug); + if (!(course_exists_in_canvas($coursename))) { + create_canvas_course($coursename); + } + } elsif ($body->{esbEvent}->[0]->{eventType} eq 'MEMBERSHIP_ADD' || + $body->{esbEvent}->[0]->{eventType} eq 'MEMBERSHIP_DELETE') { + if ($body->{esbEvent}->[0]->{sourceId} eq 'jdbc') { + my $uid = $body->{esbEvent}->[0]->{subjectId}; + print "Got $body->{esbEvent}->[0]->{eventType} for $uid\n" if ($debug); + # create user if they don't exist + my $user = get_subject_info($uid); + my $name = $user->{WsGetSubjectsResults}->{wsSubjects}->[0]->{name}; + if (!(user_exists_in_canvas($uid))) { + create_canvas_user($uid,$name); + } + # get course lists + print "Getting course lists..\n" if ($debug); + my $grouper_courses = get_grouper_courses($uid); + my $canvas_courses = get_canvas_courses($uid); + # now reconcile courses + print "Reconciling courses..\n" if ($debug); + reconcile_courses($uid, $grouper_courses, $canvas_courses); + } else { + print "*** SourceID not jdbc, skipping...\n" if ($debug); + } + } else { + print "Unexpected message type: $body->{esbEvent}->[0]->{eventType}\n" if ($debug); + } +} + + +$mq->disconnect(); + +sub get_subject_info { + my $uid = shift; + + print "Looking for subject: $uid\n" if ($debug); + + my $client = REST::Client->new(); + $client->setHost($config->{grouper_host}); + $client->setTimeout(10); + my $encoded_auth = encode_base64($config->{grouper_user} . ":" . $config->{grouper_pass}); + + $client->GET( "/grouper-ws/servicesRest/json/v2_2_000/subjects/$uid", + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + + print Dumper $client->responseContent() if ($debug); + + my $subject = from_json($client->responseContent()); + + return $subject; +} + +sub get_grouper_courses { + my $uid = shift; + my %courses; + + print "Finding group memberships for: $uid\n" if ($debug); + + my $client = REST::Client->new(); + $client->setHost($config->{grouper_host}); + $client->setTimeout(10); + my $encoded_auth = encode_base64($config->{grouper_user} . ":" . $config->{grouper_pass}); + + $client->GET( "/grouper-ws/servicesRest/json/v2_2_000/subjects/$uid/groups", + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + + print Dumper $client->responseContent() if ($debug); + + my $result = from_json($client->responseContent); + + my $groups = $result->{WsGetGroupsLiteResult}->{wsGroups}; + + foreach my $group (@$groups) { + my $groupName = $group->{name}; + print "Looking at group: $groupName\n" if ($debug); + if ($groupName =~ m/^ref\:courses/) { + my ($courseName) = $groupName =~ m/^ref:courses:(.*)$/; + print "Found $courseName\n" if ($debug); + $courses{$courseName} = 1; + } + } + + print "Returning courses:\n" if ($debug); + print Dumper %courses if ($debug); + + return \%courses; +} + +sub get_canvas_courses { + my $uid = shift; + my %courses; + + print "Finding canvas courses for: $uid\n"; + + my $canvas_login = $uid."@".$config->{email_suffix}; + my $canvas_token = $config->{canvas_token}; + my $client = REST::Client->new({ + host => $config->{canvas_url}, + timeout => 10 + }); + + $client->getUseragent()->ssl_opts(verify_hostname => 0); + $client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + + # get canvas ID + print "Getting canvas ID for canvas login $canvas_login\n" if ($debug); + $client->GET("/api/v1/accounts/1/users?access_token=$canvas_token&search_term=$canvas_login"); + my $response = from_json($client->responseContent()); + print Dumper $response if ($debug); + my $canvas_user_id = $response->[0]->{id}; + + # Get enrollments for that canvas user ID + print "Getting enrollments for canvas user id: $canvas_user_id\n" if ($debug); + $client->GET("/api/v1/users/$canvas_user_id/enrollments?access_token=$canvas_token"); + $response = from_json($client->responseContent()); + print Dumper $response if ($debug); + + foreach my $enrollment (@$response) { + # Turn canvas course IDs into course names + my $course_id = $enrollment->{course_id}; + print "Getting course name for course_id: $course_id\n" if ($debug); + $client->GET("/api/v1/accounts/1/courses/$course_id/?access_token=$canvas_token"); + $response = from_json($client->responseContent()); + print Dumper $response if ($debug); + # my $courseName = $response->[0]->{name}; + my $courseName = $response->{name}; + $courses{$courseName} = 1; + } + + return \%courses; +} + +sub user_exists_in_canvas { + my $uid = shift; + my $result; + + print "Finding $uid in canvas\n" if ($debug); + + my $canvas_token = $config->{canvas_token}; + + my $canvas_login = $uid."@".$config->{email_suffix}; + + my $client = REST::Client->new({ + host => $config->{canvas_url}, + timeout => 10 + }); + + $client->getUseragent()->ssl_opts(verify_hostname => 0); + $client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + + $client->GET("/api/v1/accounts/1/users?access_token=$canvas_token&search_term=$canvas_login"); + my $response = from_json($client->responseContent()); + print Dumper $response if ($debug); + if (defined($response->[0]->{id})) { + print "User found\n" if ($debug); + $result = 1; + } else { + print "User not found\n" if ($debug); + $result = 0; + } + return $result; +} + +sub course_exists_in_canvas { + my $coursename = shift; + my $result; + + print "Finding $coursename in canvas\n" if ($debug); + + my $canvas_token = $config->{canvas_token}; + + my $client = REST::Client->new({ + host => $config->{canvas_url}, + timeout => 10 + }); + + $client->getUseragent()->ssl_opts(verify_hostname => 0); + $client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + + $client->GET("/api/v1/accounts/1/courses?access_token=$canvas_token&search_term=$coursename"); + my $response = from_json($client->responseContent()); + print Dumper $response if ($debug); + if (defined($response->[0]->{id})) { + print "Course exists\n" if ($debug); + $result = 1; + } else { + print "Course does not exist\n" if ($debug); + $result = 0; + } + return $result; +} + +sub create_canvas_user { + my $uid = shift; + my $name = shift; + # my $sis_user_id = shift; + + print "Creating canvas user with uid: $uid, name: $name\n"; + + my $canvas_token = $config->{canvas_token}; + + my $canvas_login = $uid."@".$config->{email_suffix}; + + my $header; + + $header->{'Authorization'} = "Bearer: $canvas_token"; + $header->{'Content-type'} = "application/json"; + + my $client = REST::Client->new({ + host => $config->{canvas_url}, + timeout => 10 + }); + + $client->getUseragent()->ssl_opts(verify_hostname => 0); + $client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + + my $user; + $user->{pseudonym}->{unique_id} = $canvas_login; + $user->{pseudonym}->{unique_login} = $canvas_login; + $user->{user}->{name} = $name; + # $user->{pseudonym}->{sis_user_id} = $sis_user_id; + $user->{pseudonym}->{password} = $config->{default_password}; + $user->{user}->{skip_registration} = 'true'; + + my $json_user = to_json($user); + + $client->POST("/api/v1/accounts/1/users?access_token=$canvas_token",$json_user,$header); + + print Dumper $client->responseContent() if ($debug); + +} + +sub create_canvas_course { + my $courseName = shift; + + print "Creating $courseName in canvas\b" if ($debug); + + my $canvas_token = $config->{canvas_token}; + + my $header; + $header->{'Authorization'} = "Bearer: $canvas_token"; + $header->{'Content-type'} = "application/json"; + + my $client = REST::Client->new({ + host => $config->{canvas_url}, + timeout => 10 + }); + + $client->getUseragent()->ssl_opts(verify_hostname => 0); + $client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + + my $course; + $course->{course}->{name} = $courseName; + my $json_course = to_json($course); + + $client->POST("/api/v1/accounts/1/courses?access_token=$canvas_token",$json_course,$header); + + print Dumper $client->responseContent() if ($debug); + +} + +sub enroll_user_in_course { + my $user = shift; + my $course = shift; + + print "Enrolling $user in $course\n" if ($debug); + + my $canvas_token = $config->{canvas_token}; + my $header; + $header->{'Authorization'} = "Bearer: $canvas_token"; + $header->{'Content-type'} = "application/json"; + + my $client = REST::Client->new({ + host => $config->{canvas_url}, + timeout => 10 + }); + + $client->getUseragent()->ssl_opts(verify_hostname => 0); + $client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + + # get canvas user id + $client->GET("/api/v1/accounts/1/users?access_token=$canvas_token&search_term=$user"); + my $response = from_json($client->responseContent()); + my $user_id = @$response[0]->{id}; + print "Found user id: $user_id\n" if ($debug); + + # get canvas course id + print "looking for Course Name: $course\n" if $debug; + $client->GET("/api/v1/accounts/1/courses?access_token=$canvas_token&search_terms=$course"); + $response = from_json($client->responseContent()); + print $client->responseContent() if $debug; + # for some reason Canvas returns all courses on a name search.. + my $course_id; + foreach my $courses (@$response) { + if ($courses->{name} eq $course) { + print "Found $courses->{id} matching $course\n" if ($debug); + $course_id = $courses->{id}; + } + } + print "Found Course_ID: $course_id for $course\n" if $debug; + + # now do enrollment + my $enrollment; + $enrollment->{enrollment}->{type} = "StudentEnrollment"; + $enrollment->{enrollment}->{user_id} = $user_id; + $enrollment->{enrollment}->{enrollment_state} = "active"; + my $json_enrollment = to_json($enrollment); + + print "Adding enrollment: $json_enrollment\n" if $debug; + $client->POST("/api/v1/courses/$course_id/enrollments?access_token=$canvas_token",$json_enrollment,$header); + print Dumper $client->responseContent(); + $response = from_json($client->responseContent()); + print Dumper $response if $debug; + +} + +sub remove_user_from_course { + my $uid = shift; + my $course = shift; + print "Removing $course for: $uid\n" if ($debug); + + my $canvas_login = $uid."@".$config->{email_suffix}; + my $canvas_token = $config->{canvas_token}; + my $client = REST::Client->new({ + host => $config->{canvas_url}, + timeout => 10 + }); + + $client->getUseragent()->ssl_opts(verify_hostname => 0); + $client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + + # get canvas ID + print "Getting canvas ID for canvas login $canvas_login\n" if ($debug); + $client->GET("/api/v1/accounts/1/users?access_token=$canvas_token&search_term=$canvas_login"); + my $response = from_json($client->responseContent()); + print Dumper $response if ($debug); + my $canvas_user_id = $response->[0]->{id}; + + # Get enrollments for that canvas user ID + print "Getting enrollments for canvas user id: $canvas_user_id\n" if ($debug); + $client->GET("/api/v1/users/$canvas_user_id/enrollments?access_token=$canvas_token"); + $response = from_json($client->responseContent()); + print Dumper $response if ($debug); + + my $canvas_courseid; + my $enrollment_id; + foreach my $enrollment (@$response) { + # get name of course by course ID + $enrollment_id = $enrollment->{id}; + $client->GET("/api/v1/accounts/1/courses/$enrollment->{course_id}?access_token=$canvas_token&search_terms=$course"); + my $course_response = from_json($client->responseContent()); + # then check to see if the course name matches the one passed in + print "Found $course_response->{id} and $course_response->{name}\n" if ($debug); + if ($course_response->{name} eq $course) { + print "$course_response->{name} matches $course, so setting canvas_courseid\n" if ($debug); + $canvas_courseid = $course_response->{id}; + } + } + + if ($canvas_courseid) { + print "******* DELETING course_id [$canvas_courseid] for user [$canvas_user_id]" if ($debug); + #$client->DELETE("/api/v1/courses/$canvas_courseid/enrollments/$canvas_user_id?access_token=$canvas_token"); + $client->DELETE("/api/v1/courses/$canvas_courseid/enrollments/$enrollment_id?access_token=$canvas_token"); + print Dumper $client->responseContent() if ($debug); + print "****** DONE DELETING ***\n" if ($debug); + } + +} + +sub reconcile_courses { + my $user = shift; + my $grouper_courses = shift; + my $canvas_courses = shift; + + # spin through grouper courses to see which are not in canvas + my $in_grouper_not_canvas; + foreach my $grouper_course (keys %$grouper_courses) { + if (!(exists($canvas_courses->{$grouper_course}))) { + $in_grouper_not_canvas->{$grouper_course} = 1; + } + } + + # spin through canvas courses to see which are not in grouper + my $in_canvas_not_grouper; + foreach my $canvas_course (keys %$canvas_courses) { + if (!(exists($grouper_courses->{$canvas_course}))) { + $in_canvas_not_grouper->{$canvas_course} = 1; + } + } + + # add user to canvas courses + foreach my $course_add (keys %$in_grouper_not_canvas) { + enroll_user_in_course($user, $course_add); + } + + # remove users from canvas courses + foreach my $course_remove (keys %$in_canvas_not_grouper) { + remove_user_from_course($user, $course_remove); + } + +} diff --git a/canvas/canvas_provisioner.pl b/canvas/canvas_provisioner.pl new file mode 100755 index 0000000..2e26389 --- /dev/null +++ b/canvas/canvas_provisioner.pl @@ -0,0 +1,31 @@ +#!/usr/bin/perl -w +# +# receive_from_queue.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: receive_from_queue.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use warnings; + +while (1) { + + print STDOUT "Canvas provisioner container running...\n"; + sleep(60); +} diff --git a/canvas/canvas_token.txt b/canvas/canvas_token.txt new file mode 100644 index 0000000..da0494d --- /dev/null +++ b/canvas/canvas_token.txt @@ -0,0 +1 @@ +10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD diff --git a/canvas/config.yml b/canvas/config.yml new file mode 100644 index 0000000..a7a4967 --- /dev/null +++ b/canvas/config.yml @@ -0,0 +1,20 @@ +rabbit_host: tier-demo-rabbit +rabbit_port: 5672 +rabbit_user: guest +rabbit_pass: guest +rabbit_exchange: amq.topic +rabbit_routing_key: ref.courses.* +grouper_host: http://tier-demo-grouper:8080 +grouper_user: tjordan +grouper_pass: 12345 +debug: 1 +canvas_url: https://tier.instructure.com +canvas_token: **replace_with_generated_token** +default_password: Password12345 +email_suffix: example.edu +courses: + - CS101 + - CS102 + - TIER101 + - MATH101 + - ACCT101 diff --git a/canvas/coursename.pl b/canvas/coursename.pl new file mode 100755 index 0000000..7a8b4f8 --- /dev/null +++ b/canvas/coursename.pl @@ -0,0 +1,10 @@ +#!/usr/local/bin/perl + +use strict; +use warnings; + +my $fullCourseName = 'basis.courses.MATH101'; + +my ($coursename) = $fullCourseName =~ m/^basis\.courses\.(.*)$/; + +print "Coursename: $coursename\n"; diff --git a/canvas/create_courses.pl b/canvas/create_courses.pl new file mode 100755 index 0000000..0012608 --- /dev/null +++ b/canvas/create_courses.pl @@ -0,0 +1,59 @@ +#!/usr/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; +my $header; + +$header->{'Authorization'} = "Bearer: $canvas_token"; +$header->{'Content-type'} = "application/json"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +my $course; +$course->{course}->{name} = 'Test Course1'; + +my $json_course = to_json($course); + +print "About to call...\n"; +$client->POST("/api/v1/accounts/1/courses?access_token=$canvas_token",$json_course,$header); +print "after call...\n"; + +print Dumper $client->responseContent(); + +my $response = from_json($client->responseContent()); + +print Dumper $response; + diff --git a/canvas/create_enrollments.pl b/canvas/create_enrollments.pl new file mode 100755 index 0000000..a9401b0 --- /dev/null +++ b/canvas/create_enrollments.pl @@ -0,0 +1,66 @@ +#!/usr/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; +my $header; + +$header->{'Authorization'} = "Bearer: $canvas_token"; +$header->{'Content-type'} = "application/json"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +my $user; +$user->{pseudonym}->{unique_id} = 'testuser1@example.edu'; +$user->{pseudonym}->{unique_login} = 'testuser1@example.edu'; +$user->{user}->{name} = 'Test User1'; +$user->{pseudonym}->{sis_user_id} = 1; +$user->{pseudonym}->{password} = 'password'; +$user->{user}->{skip_registration} = 'true'; + +my $json_user = to_json($user); + +print Dumper $json_user; +print "About to call...\n"; +#$client->POST("/api/v1/accounts/1/users?access_token=$canvas_token",[$json_user]); +$client->POST("/api/v1/accounts/1/users?access_token=$canvas_token",$json_user,$header); +print "after call...\n"; + +print Dumper $client->responseContent(); + +my $response = from_json($client->responseContent()); + +print Dumper $response; + diff --git a/canvas/create_users.pl b/canvas/create_users.pl new file mode 100755 index 0000000..a9401b0 --- /dev/null +++ b/canvas/create_users.pl @@ -0,0 +1,66 @@ +#!/usr/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; +my $header; + +$header->{'Authorization'} = "Bearer: $canvas_token"; +$header->{'Content-type'} = "application/json"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +my $user; +$user->{pseudonym}->{unique_id} = 'testuser1@example.edu'; +$user->{pseudonym}->{unique_login} = 'testuser1@example.edu'; +$user->{user}->{name} = 'Test User1'; +$user->{pseudonym}->{sis_user_id} = 1; +$user->{pseudonym}->{password} = 'password'; +$user->{user}->{skip_registration} = 'true'; + +my $json_user = to_json($user); + +print Dumper $json_user; +print "About to call...\n"; +#$client->POST("/api/v1/accounts/1/users?access_token=$canvas_token",[$json_user]); +$client->POST("/api/v1/accounts/1/users?access_token=$canvas_token",$json_user,$header); +print "after call...\n"; + +print Dumper $client->responseContent(); + +my $response = from_json($client->responseContent()); + +print Dumper $response; + diff --git a/canvas/delete_courses.pl b/canvas/delete_courses.pl new file mode 100755 index 0000000..ca4b9f6 --- /dev/null +++ b/canvas/delete_courses.pl @@ -0,0 +1,55 @@ +#!/usr/local/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION + +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $course = shift; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +$client->GET("/api/v1/accounts/1/courses?access_token=$canvas_token"); +my $response = from_json($client->responseContent()); +print Dumper $response; +my $id = @$response[0]->{id}; +print "ID: $id\n"; + +foreach my $course (@$response) { + $client->DELETE("/api/v1/accounts/1/courses/$course->{id}?access_token=$canvas_token"); + my $delete_response = from_json($client->responseContent()); + print Dumper $delete_response; +} + + diff --git a/canvas/find_course.pl b/canvas/find_course.pl new file mode 100755 index 0000000..5ee8603 --- /dev/null +++ b/canvas/find_course.pl @@ -0,0 +1,50 @@ +#!/usr/local/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION + +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $course = shift; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +$client->GET("/api/v1/accounts/1/courses?access_token=$canvas_token&name=$course"); +my $response = from_json($client->responseContent()); +print Dumper $response; +my $id = @$response[0]->{id}; +print "ID: $id\n"; + + + diff --git a/canvas/find_no_user.pl b/canvas/find_no_user.pl new file mode 100755 index 0000000..2e86403 --- /dev/null +++ b/canvas/find_no_user.pl @@ -0,0 +1,48 @@ +#!/usr/local/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +$client->GET("/api/v1/accounts/1/users?access_token=$canvas_token&search_term=not_tom.jordan\@wisc.edu"); +my $response = from_json($client->responseContent()); +print Dumper $response; +my $id = @$response[0]->{id}; +print "ID: $id\n"; + + + diff --git a/canvas/find_user.pl b/canvas/find_user.pl new file mode 100755 index 0000000..6bf0b74 --- /dev/null +++ b/canvas/find_user.pl @@ -0,0 +1,48 @@ +#!/usr/local/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +$client->GET("/api/v1/accounts/1/users?access_token=$canvas_token&search_term=tom.jordan\@wisc.edu"); +my $response = from_json($client->responseContent()); +print Dumper $response; +my $id = @$response[0]->{id}; +print "ID: $id\n"; + + + diff --git a/canvas/find_user_enrollments.pl b/canvas/find_user_enrollments.pl new file mode 100755 index 0000000..b2c5bc8 --- /dev/null +++ b/canvas/find_user_enrollments.pl @@ -0,0 +1,53 @@ +#!/usr/local/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $user = shift; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +$client->GET("/api/v1/accounts/1/users?access_token=$canvas_token&search_term=$user\@example.edu"); +my $response = from_json($client->responseContent()); +print Dumper $response; +my $id = @$response[0]->{id}; + +$client->GET("/api/v1/users/$id/enrollments?access_token=$canvas_token"); +$response = from_json($client->responseContent()); +print Dumper $response; + + + diff --git a/canvas/get_grouper_attribute.pl b/canvas/get_grouper_attribute.pl new file mode 100755 index 0000000..88145b5 --- /dev/null +++ b/canvas/get_grouper_attribute.pl @@ -0,0 +1,46 @@ +#!/usr/local/bin/perl -w +# +# get_grouper_subject.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: get_grouper_subject.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use warnings; +use Data::Dumper; +use JSON; +use REST::Client; +use MIME::Base64; + +my $uid = shift; + +print "Searching for: $uid\n"; + +my $client = REST::Client->new(); +$client->setHost('http://tier-demo-grouper:8080'); +$client->setTimeout(10); +my $encoded_auth = encode_base64( 'tjordan' . ":" . '12345' ); + +$client->GET( "/grouper-ws/servicesRest/json/v2_2_000/subjects/$uid/attributeAssignments", + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + +print Dumper $client->responseCode(); +print Dumper $client->responseContent(); + + diff --git a/canvas/get_grouper_memberships.pl b/canvas/get_grouper_memberships.pl new file mode 100755 index 0000000..97a6bc4 --- /dev/null +++ b/canvas/get_grouper_memberships.pl @@ -0,0 +1,56 @@ +#!/usr/local/bin/perl -w +# +# get_grouper_subject.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: get_grouper_subject.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use warnings; +use Data::Dumper; +use JSON; +use REST::Client; +use MIME::Base64; + +my $uid = shift; + +print "Searching for: $uid\n"; + +my $client = REST::Client->new(); +$client->setHost('http://tier-demo-grouper:8080'); +$client->setTimeout(10); +my $encoded_auth = encode_base64( 'tjordan' . ":" . '12345' ); + +$client->GET( "/grouper-ws/servicesRest/json/v2_2_000/subjects/$uid/memberships", + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + +print Dumper $client->responseCode(); +print Dumper $client->responseContent(); + +my $result = from_json($client->responseContent()); + +my $groups = $result->{WsGetMembershipsResults}->{wsGroups}; + +foreach my $group (@$groups) { + print "*************************\n"; + print Dumper $group; + print "Name: $group->{name}\n"; +} + + diff --git a/canvas/get_grouper_subject.pl b/canvas/get_grouper_subject.pl new file mode 100755 index 0000000..5e10cd4 --- /dev/null +++ b/canvas/get_grouper_subject.pl @@ -0,0 +1,46 @@ +#!/usr/local/bin/perl -w +# +# get_grouper_subject.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: get_grouper_subject.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use warnings; +use Data::Dumper; +use JSON; +use REST::Client; +use MIME::Base64; + +my $uid = shift; + +print "Searching for: $uid\n"; + +my $client = REST::Client->new(); +$client->setHost('http://tier-demo-grouper:8080'); +$client->setTimeout(10); +my $encoded_auth = encode_base64( 'tjordan' . ":" . '12345' ); + +$client->GET( "/grouper-ws/servicesRest/json/v2_2_000/subjects/$uid", + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + +print Dumper $client->responseCode(); +print Dumper $client->responseContent(); + + diff --git a/canvas/grouper_ws.pl b/canvas/grouper_ws.pl new file mode 100755 index 0000000..d92b110 --- /dev/null +++ b/canvas/grouper_ws.pl @@ -0,0 +1,47 @@ +#!/usr/local/bin/perl -w +# +# get_grouper_subject.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: get_grouper_subject.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use warnings; +use Data::Dumper; +use JSON; +use REST::Client; +use MIME::Base64; + +my $uid = shift; +my $query = shift; + +print "Searching for: $uid\n"; + +my $client = REST::Client->new(); +$client->setHost('http://tier-demo-grouper:8080'); +$client->setTimeout(10); +my $encoded_auth = encode_base64( 'tjordan' . ":" . '12345' ); + +$client->GET( "/grouper-ws/servicesRest/json/v2_2_000/subjects/$uid/$query", + { "Content-Type" => "text/x-json", 'Authorization' => "Basic $encoded_auth" } ); + +print Dumper $client->responseCode(); +print Dumper $client->responseContent(); + + diff --git a/canvas/list_users.pl b/canvas/list_users.pl new file mode 100755 index 0000000..1c77b77 --- /dev/null +++ b/canvas/list_users.pl @@ -0,0 +1,47 @@ +#!/usr/bin/perl -w +# +# canvas_test_user.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: canvas_test_user.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Data::Dumper; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +#$client->addHeader("Authorization","Bearer: $canvas_token"); + +$client->GET("/api/v1/accounts/1/users?access_token=$canvas_token"); +my $response = from_json($client->responseContent()); + +print Dumper $response; + diff --git a/canvas/net_amqp_rabbit.pl b/canvas/net_amqp_rabbit.pl new file mode 100755 index 0000000..9d85368 --- /dev/null +++ b/canvas/net_amqp_rabbit.pl @@ -0,0 +1,54 @@ +#!/usr/local/bin/perl -w +# +# net_amqp_rabbit.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: net_amqp_rabbit.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use Net::AMQP::RabbitMQ; +use Data::Dumper; + +my $channel = 1; +my $exchange = "amq.topic"; # This exchange must exist already +my $routing_key = "basis.courses.TIER101"; + +my $mq = Net::AMQP::RabbitMQ->new(); +$mq->connect("tier-demo-rabbit", { user => "guest", password => "guest" }); +$mq->channel_open($channel); + +# Declare queue, letting the server auto-generate one and collect the name +my $queuename = "TIER101"; + +#$mq->queue_declare($channel, ""); + +# Bind the new queue to the exchange using the routing key +#$mq->queue_bind($channel, $queuename, $exchange, $routing_key); +$mq->queue_bind($channel, $queuename, $exchange, $routing_key); + +# Request that messages be sent and receive them until interrupted +$mq->consume($channel, $queuename); + +while ( my $message = $mq->recv(0) ) + { + print "Received message:\n"; + print Dumper($message); + } + +$mq->disconnect(); diff --git a/canvas/provision_canvas.pl b/canvas/provision_canvas.pl new file mode 100755 index 0000000..e8b80e8 --- /dev/null +++ b/canvas/provision_canvas.pl @@ -0,0 +1,197 @@ +#!/usr/bin/perl -w +# +# provision_canvas.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: provision_canvas.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use REST::Client; +use JSON; +use Net::LDAP; +use Data::Dumper; + +my $debug = 1; + +my $canvas_url = "https://tier.instructure.com"; +my $canvas_token = "10675~b1IIAPh31TCIBMRsmEqLUL436htu5Q7CP8JPMhRncRpKVh9uWYIDxbkCNWN7vSKD"; +my $header; + +$header->{'Authorization'} = "Bearer: $canvas_token"; +$header->{'Content-type'} = "application/json"; + +my $client = REST::Client->new({ + host => $canvas_url, + timeout => 10 + }); + +# disable certificate checking +$client->getUseragent()->ssl_opts(verify_hostname => 0); +$client->getUseragent()->ssl_opts(SSL_verify_mode => "SSL_VERIFY_NONE"); + +my $ldap_host = "127.0.0.1"; +my $ldap_admin = "cn=admin,dc=example,dc=edu"; +my $ldap_password = "password"; +my $course_groups_dn = "ou=groups,dc=example,dcu=edu"; + +my $ldap = Net::LDAP->new( $ldap_host, port => 389) or die $@; + +my $mesg = $ldap->bind($ldap_admin, password => $ldap_password); + + +die "unable to bind to ldap: $@\n" if (!(defined($mesg))); + +my $course_groups = get_course_groups($course_groups_dn); + +foreach my $course_group (@$course_groups) { + print "About to process enrollments for $course_group\n" if $debug; + process_enrollments($course_group); +} + + +sub get_course_groups { + my $groups_dn = shift; + print "Fetching Course Groups\n" if $debug; + + my @course_groups; + push @course_groups,"cn=app:canvas:users,ou=groups,dc=example,dc=edu"; + push @course_groups,"cn=app:canvas:class_cs251,ou=groups,dc=example,dc=edu"; + push @course_groups,"cn=app:canvas:class_cs252,ou=groups,dc=example,dc=edu"; + print "Done fetching course groups\n" if $debug; + return \@course_groups; +} + +sub process_enrollments { + my $course_group = shift; + + print "processing enrollments for course group: $course_group\n" if $debug; + + # TODO: Add the course to canvas + + my $course_id = add_course_to_canvas($course_group); + print "COURSE_ID: $course_id\n" if $debug; + + # TODO: Get current members + print "searching ldap for group: $course_group\n" if $debug; + $mesg = $ldap->search(base => $course_group, + filter => '(objectclass=*)'); + + my $entry = $mesg->entry(0); + my @members = $entry->get_value('member'); + + # TODO: Get user details for each member + + foreach my $member (@members) { + # TODO: Validate whether or not the user needs to be added to canvas + my $member_details = get_member_details($member); + add_user_to_canvas($member_details); + # TODO: Add the users to the course + add_user_to_course($member_details,$course_group,$course_id); + } +} + +sub get_member_details { + my $member_dn = shift; + print "Getting member details for $member_dn\n" if $debug; + $mesg = $ldap->search(base => $member_dn, + filter => '(objectclass=*)'); + my $entry = $mesg->entry(0); + + my $member_details; + + # TODO: Get name and uid, and set a default password + my $uid = $entry->get_value('uid'); + $member_details->{user}->{name} = $entry->get_value('cn'); + $member_details->{user}->{skip_registration} = "true"; + $member_details->{pseudonym}->{unique_id} = $uid."\@example.edu"; + $member_details->{pseudonym}->{password} = "password"; + + print "Dumping user details..\n" if $debug; + print Dumper $member_details if $debug; + + return $member_details; + +} + +sub add_user_to_canvas { + my $member_details = shift; + + my $json_user = to_json($member_details); + print "Adding user: $json_user\n" if $debug; + $client->POST("/api/v1/accounts/1/users?access_token=$canvas_token",$json_user,$header); + my $response = from_json($client->responseContent()); + print Dumper $response if $debug; +} + +sub add_course_to_canvas { + my $course_group = shift; + + print "Adding course $course_group to Canvas\n" if $debug; + + my ($course_name) = ($course_group =~ m/cn=(.*),ou=groups,dc=example,dc=edu/); + + print "Modified course_name: $course_name\n" if $debug; + + my $course; + $course->{course}->{name} = $course_name; + my $json_course = to_json($course); + print "Adding course: $json_course\n" if $debug; + $client->POST("/api/v1/accounts/1/courses?access_token=$canvas_token",$json_course,$header); + my $response = from_json($client->responseContent()); + my $course_id = $response->{id}; + print "*** COURSE_ID: $course_id\n" if $debug; + print "Returning Course_ID: $course_id\n" if $debug; + return $course_id; +} + +sub add_user_to_course { + my $member_details = shift; + my $course_group = shift; + my $course_id = shift; + + # TODO: Get user's user_id + my $login_id = $member_details->{pseudonym}->{unique_id}; + $client->GET("/api/v1/accounts/1/users?access_token=$canvas_token&search_term=$login_id"); + my $response = from_json($client->responseContent()); + my $user_id = @$response[0]->{id}; + + # TODO: Get Course ID + + #my ($course_name) = ($course_group =~ m/cn=(.*),ou=groups,dc=example,dc=edu/); + #print "looking for Course Name: $course_name\n" if $debug; + #$client->GET("/api/v1/accounts/1/courses?access_token=$canvas_token&search_terms=$course_name"); + #$response = from_json($client->responseContent()); + #print $client->responseContent() if $debug; + #my $course_id = @$response[0]->{id}; + #print "Found Course_ID: $course_id\n" if $debug; + + # TODO: Add user to course + my $enrollment; + $enrollment->{enrollment}->{type} = "StudentEnrollment"; + $enrollment->{enrollment}->{user_id} = $user_id; + $enrollment->{enrollment}->{enrollment_state} = "active"; + + my $json_enrollment = to_json($enrollment); + print "Adding enrollment: $json_enrollment\n" if $debug; + $client->POST("/api/v1/courses/$course_id/enrollments?access_token=$canvas_token",$json_enrollment,$header); + print Dumper $client->responseContent(); + $response = from_json($client->responseContent()); + print Dumper $response if $debug; +} + diff --git a/canvas/rabbit_connect.pl b/canvas/rabbit_connect.pl new file mode 100755 index 0000000..35d66dd --- /dev/null +++ b/canvas/rabbit_connect.pl @@ -0,0 +1,57 @@ +#!/usr/local/bin/perl -w +# +# receive_from_queue.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: receive_from_queue.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +use warnings; + +$|++; +use AnyEvent; +use Net::RabbitFoot; + +my $conn = Net::RabbitFoot->new()->load_xml_spec()->connect( + host => 'tier-demo-rabbit', + port => 5672, + user => 'guest', + pass => 'guest', + vhost => '/', +); + +my $ch = $conn->open_channel(); + +$ch->declare_queue(queue => 'TIER101'); + +print " [*] Waiting for messages. To exit press CTRL-C\n"; + +sub callback { + my $var = shift; + my $body = $var->{body}->{payload}; + print " [x] Received $body\n"; +} + +$ch->consume( + on_consume => \&callback, + no_ack => 1, +); + +# Wait forever +AnyEvent->condvar->recv; diff --git a/canvas/run.sh b/canvas/run.sh new file mode 100755 index 0000000..8b777c8 --- /dev/null +++ b/canvas/run.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# run.sh, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan +docker run -it --rm --name tier-demo-canvas tier-demo-canvas diff --git a/canvas/run_canvas.sh b/canvas/run_canvas.sh new file mode 100755 index 0000000..eb18db5 --- /dev/null +++ b/canvas/run_canvas.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# +# run_canvas.sh, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +# wait until rabbit is up +until nc -vz tier-demo-rabbit 5672 +do + echo "Rabbit is unavailable - sleeping" + sleep 1 +done +echo "Rabbit is up!" + +perl ./canvas.pl diff --git a/canvas/saml_settings.txt b/canvas/saml_settings.txt new file mode 100644 index 0000000..18df9ef --- /dev/null +++ b/canvas/saml_settings.txt @@ -0,0 +1,8 @@ +------- do not use ---- IdP Metadata URL: https://babb-www.cs.wisc.edu/tier-demo-metadata.xml +IdP Entity ID: https://localhost/idp/shibboleth +Log On URL: https://localhost/idp/profile/SAML2/Redirect/SSO +Cert Fingerprint: 67b3add4d6bd52c5d573b2843083cf39fb509a58 +Login Attribute: eduPersonPrincipalName +Identifier Format: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified +Auth Context: no value +JIT Provisioning: not checked. diff --git a/canvas/string.pl b/canvas/string.pl new file mode 100755 index 0000000..84e5e8c --- /dev/null +++ b/canvas/string.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl -w +# +# string.pl, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan + +use vars qw/$VERSION $FILE/; +($VERSION) = q$Revision: 1.1 $ =~ /([\d.]+)/; +($FILE) = q$RCSfile: string.pl,v $ =~ /^[^:]+: ([^\$]+),v $/; + +use strict; +my $long = "cn=ref:affiliation:community,ou=groups,dc=example,dc=edu"; +print "long: $long\n"; +my ($short) = ($long =~ /cn=(.*),ou=groups,dc=example,dc=edu/); +print "short: $short\n"; diff --git a/clean.sh b/clean.sh new file mode 100755 index 0000000..05a32a8 --- /dev/null +++ b/clean.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +docker stop tier-demo-ldap +docker stop tier-demo-mysql +docker stop tier-demo-idp +docker stop tier-demo-grouper +docker stop tier-demo-web-app +docker stop tier-demo-rabbit + +docker rm tier-demo-ldap +docker rm tier-demo-mysql +docker rm tier-demo-idp +docker rm tier-demo-grouper +docker rm tier-demo-web-app +docker rm tier-demo-rabbit diff --git a/deps/ldap/Dockerfile b/deps/ldap/Dockerfile new file mode 100644 index 0000000..037914a --- /dev/null +++ b/deps/ldap/Dockerfile @@ -0,0 +1,32 @@ +FROM ubuntu:trusty + +MAINTAINER "TIER API & EntReg Working Group " + +RUN set -x; \ + apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y slapd ldap-utils libnet-ldap-perl libauthen-sasl-perl libuuid-perl perl-doc \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && echo 'slapd/root_password password password' | debconf-set-selections \ + && echo 'slapd/root_password_again password password' | debconf-set-selections + +COPY bootstrap /opt/bootstrap +COPY slapdconf/* /usr/local/bin/ + +RUN set -x; \ + service slapd start \ + && mkdir -p /var/ldap/example \ + && chown -R openldap /var/ldap \ + && ldapadd -Y EXTERNAL -H ldapi:/// -f /opt/bootstrap/00_init.ldif \ + && ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bootstrap/10_groupOfUniqueNames.ldif \ + && ldapmodify -Y EXTERNAL -H ldapi:/// -f /opt/bootstrap/15_groupOfNames.ldif \ + && ldapadd -Y EXTERNAL -H ldapi:/// -f /opt/bootstrap/20_eduperson_schema.ldif \ + && ldapadd -H ldapi:/// -f /opt/bootstrap/30_users.ldif -x -D "cn=admin,dc=example,dc=edu" -w password 1>/dev/null \ + && openldap_midpoint.sh \ + && service slapd stop + +EXPOSE 389 + +VOLUME ["/etc/ldap", "/var/lib/ldap"] + +CMD ["slapd", "-d", "32768", "-u", "openldap", "-g", "openldap"] diff --git a/deps/ldap/bootstrap/00_init.ldif b/deps/ldap/bootstrap/00_init.ldif new file mode 100644 index 0000000..8e12fe4 --- /dev/null +++ b/deps/ldap/bootstrap/00_init.ldif @@ -0,0 +1,21 @@ +dn: olcDatabase=hdb,cn=config +objectClass: olcDatabaseConfig +objectClass: olcHdbConfig +olcDatabase: hdb +olcDbDirectory: /var/ldap/example +olcSuffix: dc=example,dc=edu +olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=example,dc=edu" write by * none +olcAccess: {1}to dn.base="" by * read +olcAccess: {2}to * by self write by dn="cn=admin,dc=example,dc=edu" write by * read +olcLastMod: TRUE +olcRootDN: cn=admin,dc=example,dc=edu +olcRootPW: password +olcDbCheckpoint: 512 30 +olcDbConfig: {0}set_cachesize 0 2097152 0 +olcDbConfig: {1}set_lk_max_objects 1500 +olcDbConfig: {2}set_lk_max_locks 1500 +olcDbConfig: {3}set_lk_max_lockers 1500 +olcDbIndex: objectClass eq +olcDbIndex: uid eq + + diff --git a/deps/ldap/bootstrap/10_groupOfUniqueNames.ldif b/deps/ldap/bootstrap/10_groupOfUniqueNames.ldif new file mode 100644 index 0000000..3e0fa6c --- /dev/null +++ b/deps/ldap/bootstrap/10_groupOfUniqueNames.ldif @@ -0,0 +1,9 @@ +dn: cn={0}core,cn=schema,cn=config +changetype: modify +delete: olcObjectClasses +olcObjectClasses: ( 2.5.6.17 NAME 'groupOfUniqueNames' DESC 'RFC2256: a group of unique names (DN and Unique Identifier)' SUP top STRUCTURAL MUST ( uniqueMember $ cn ) MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) ) +- +add: olcObjectClasses +olcObjectClasses: ( 2.5.6.17 NAME 'groupOfUniqueNames' DESC 'RFC2256: a group of unique names (DN and Unique Identifier)' SUP top STRUCTURAL MUST cn MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description $ uniqueMember ) ) + + diff --git a/deps/ldap/bootstrap/15_groupOfNames.ldif b/deps/ldap/bootstrap/15_groupOfNames.ldif new file mode 100644 index 0000000..9fa8066 --- /dev/null +++ b/deps/ldap/bootstrap/15_groupOfNames.ldif @@ -0,0 +1,8 @@ +dn: cn={0}core,cn=schema,cn=config +changetype: modify +delete: olcObjectClasses +olcObjectClasses: ( 2.5.6.9 NAME 'groupOfNames' DESC 'RFC2256: a group of names (DNs)' SUP top STRUCTURAL MUST ( member $ cn ) MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) ) +- +add: olcObjectClasses +olcObjectClasses: ( 2.5.6.9 NAME 'groupOfNames' DESC 'RFC2256: a group of names (DNs)' SUP top STRUCTURAL MUST cn MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description $ member) ) + diff --git a/deps/ldap/bootstrap/20_eduperson_schema.ldif b/deps/ldap/bootstrap/20_eduperson_schema.ldif new file mode 100644 index 0000000..d467914 --- /dev/null +++ b/deps/ldap/bootstrap/20_eduperson_schema.ldif @@ -0,0 +1,44 @@ +dn: cn=eduPerson,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: eduPerson +olcAttributeTypes: {0}( 1.3.6.1.4.1.5923.1.1.1.1 NAME 'eduPersonAffiliation' D + ESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: {1}( 1.3.6.1.4.1.5923.1.1.1.2 NAME 'eduPersonNickname' DESC + 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SUBSTR caseI + gnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: {2}( 1.3.6.1.4.1.5923.1.1.1.3 NAME 'eduPersonOrgDN' DESC 'e + duPerson per Internet2 and EDUCAUSE' EQUALITY distinguishedNameMatch SYNTAX 1 + .3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +olcAttributeTypes: {3}( 1.3.6.1.4.1.5923.1.1.1.4 NAME 'eduPersonOrgUnitDN' DES + C 'eduPerson per Internet2 and EDUCAUSE' EQUALITY distinguishedNameMatch SYNT + AX 1.3.6.1.4.1.1466.115.121.1.12 ) +olcAttributeTypes: {4}( 1.3.6.1.4.1.5923.1.1.1.5 NAME 'eduPersonPrimaryAffilia + tion' DESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SY + NTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +olcAttributeTypes: {5}( 1.3.6.1.4.1.5923.1.1.1.6 NAME 'eduPersonPrincipalName' + DESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SYNTAX + 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +olcAttributeTypes: {6}( 1.3.6.1.4.1.5923.1.1.1.7 NAME 'eduPersonEntitlement' D + ESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseExactMatch SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: {7}( 1.3.6.1.4.1.5923.1.1.1.8 NAME 'eduPersonPrimaryOrgUnit + DN' DESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY distinguishedNameMat + ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 SINGLE-VALUE ) +olcAttributeTypes: {8}( 1.3.6.1.4.1.5923.1.1.1.9 NAME 'eduPersonScopedAffiliat + ion' DESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SYN + TAX 1.3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: {9}( 1.3.6.1.4.1.5923.1.1.1.10 NAME 'eduPersonTargetedID' D + ESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: {10}( 1.3.6.1.4.1.5923.1.1.1.11 NAME 'eduPersonAssurance' D + ESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SYNTAX 1. + 3.6.1.4.1.1466.115.121.1.15 ) +olcAttributeTypes: {11}( 1.3.6.1.4.1.5923.1.1.1.12 NAME 'grouperMemberOf' D + ESC 'eduPerson per Internet2 and EDUCAUSE' EQUALITY caseIgnoreMatch SYNTAX 1.3 + .6.1.4.1.1466.115.121.1.15 ) +olcObjectClasses: {0}( 1.3.6.1.4.1.5923.1.1.2 NAME 'eduPerson' DESC 'eduPerson + per Internet2 and EDUCAUSE' AUXILIARY MAY ( eduPersonAffiliation $ eduPerson + Nickname $ eduPersonOrgDN $ eduPersonOrgUnitDN $ eduPersonPrimaryAffiliation + $ eduPersonPrincipalName $ eduPersonEntitlement $ eduPersonPrimaryOrgUnitDN $ + eduPersonScopedAffiliation $ eduPersonTargetedID $ eduPersonAssurance $ grouperMemberOf ) ) diff --git a/deps/ldap/bootstrap/30_users.ldif b/deps/ldap/bootstrap/30_users.ldif new file mode 100644 index 0000000..ef22d2a --- /dev/null +++ b/deps/ldap/bootstrap/30_users.ldif @@ -0,0 +1,1284 @@ +dn: dc=example,dc=edu +dc: example +objectClass: dcObject +objectClass: top +objectClass: organization +o: example.edu + +dn: cn=admin,dc=example,dc=edu +objectClass: simpleSecurityObject +objectClass: organizationalRole +cn: admin +userPassword: password +description: LDAP administrator + +dn: ou=People,dc=example,dc=edu +objectClass: organizationalUnit +objectClass: top +ou: People + +dn: uid=jsmith,ou=People,dc=example,dc=edu +objectClass: organizationalPerson +objectClass: person +objectClass: top +objectClass: inetOrgPerson +givenName: Joe +uid: jsmith +sn: Smith +cn: John Smith +userPassword: password + +dn: uid=banderson,ou=People,dc=example,dc=edu +objectClass: organizationalPerson +objectClass: person +objectClass: top +objectClass: inetOrgPerson +objectClass: eduPerson +givenName: Bob +uid: banderson +sn: Anderson +cn: Bob Anderson +userPassword: password + +dn: ou=Groups,dc=example,dc=edu +objectClass: organizationalUnit +objectClass: top +ou: Groups + +dn: uid=tjordan,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Tom +uid: tjordan +sn: Jordan +cn: Tom Jordan +userPassword: 12345 + +dn: uid=jjminer,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Jon +uid: jjminer +sn: Miner +cn: Jon Miner +userPassword: 12345 + +dn: uid=jbabb,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: James +uid: jbabb +sn: Babb +cn: James Babb +userPassword: 12345 + +dn: uid=rdavis805,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Robert +uid: rdavis805 +sn: Davis +cn: Robert Davis +userPassword: 12345 + +dn: uid=kbrown599,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Karl +uid: kbrown599 +sn: Brown +cn: Karl Brown +userPassword: 12345 + +dn: uid=dmorrison676,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: David +uid: dmorrison676 +sn: Morrison +cn: David Morrison +userPassword: 12345 + +dn: uid=jwalters336,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: James +uid: jwalters336 +sn: Walters +cn: James Walters +userPassword: 12345 + +dn: uid=broberts,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Bill +uid: broberts +sn: Roberts +cn: Bill Roberts +userPassword: 12345 + +dn: uid=manderson752,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Michael +uid: manderson752 +sn: Anderson +cn: Michael Anderson +userPassword: 12345 + +dn: uid=wmartinez,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: William +uid: wmartinez +sn: Martinez +cn: William Martinez +userPassword: 12345 + +dn: uid=escott,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Eric +uid: escott +sn: Scott +cn: Eric Scott +userPassword: 12345 + +dn: uid=kgonazles778,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Karoline +uid: kgonazles778 +sn: Gonazles +cn: Karoline Gonazles +userPassword: 12345 + +dn: uid=mprice775,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Michael +uid: mprice775 +sn: Price +cn: Michael Price +userPassword: 12345 + +dn: uid=hwhite640,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Heather +uid: hwhite640 +sn: White +cn: Heather White +userPassword: 12345 + +dn: uid=bgrady,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Betty +uid: bgrady +sn: Grady +cn: Betty Grady +userPassword: 12345 + +dn: uid=jdoe,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: James +uid: jdoe +sn: Doe +cn: James Doe +userPassword: 12345 + +dn: uid=dlangenberg61,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Donna +uid: dlangenberg61 +sn: Langenberg +cn: Donna Langenberg +userPassword: 12345 + +dn: uid=lroberts776,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lori +uid: lroberts776 +sn: Roberts +cn: Lori Roberts +userPassword: 12345 + +dn: uid=mlewis,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Michael +uid: mlewis +sn: Lewis +cn: Michael Lewis +userPassword: 12345 + +dn: uid=ganderson555,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Greg +uid: ganderson555 +sn: Anderson +cn: Greg Anderson +userPassword: 12345 + +dn: uid=ldavis540,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lisa +uid: ldavis540 +sn: Davis +cn: Lisa Davis +userPassword: 12345 + +dn: uid=cdavis900,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Colin +uid: cdavis900 +sn: Davis +cn: Colin Davis +userPassword: 12345 + +dn: uid=bwhite551,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Bill +uid: bwhite551 +sn: White +cn: Bill White +userPassword: 12345 + +dn: uid=jclark826,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Jennifer +uid: jclark826 +sn: Clark +cn: Jennifer Clark +userPassword: 12345 + +dn: uid=jhenderson,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: John +uid: jhenderson +sn: Henderson +cn: John Henderson +userPassword: 12345 + +dn: uid=tprice,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Thomas +uid: tprice +sn: Price +cn: Thomas Price +userPassword: 12345 + +dn: uid=tbrown767,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Thomas +uid: tbrown767 +sn: Brown +cn: Thomas Brown +userPassword: 12345 + +dn: uid=ewalters,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Erik +uid: ewalters +sn: Walters +cn: Erik Walters +userPassword: 12345 + +dn: uid=bmorrison655,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Betty +uid: bmorrison655 +sn: Morrison +cn: Betty Morrison +userPassword: 12345 + +dn: uid=mgasper,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Mary +uid: mgasper +sn: Gasper +cn: Mary Gasper +userPassword: 12345 + +dn: uid=lmartinez,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lori +uid: lmartinez +sn: Martinez +cn: Lori Martinez +userPassword: 12345 + +dn: uid=ethompson628,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Erik +uid: ethompson628 +sn: Thompson +cn: Erik Thompson +userPassword: 12345 + +dn: uid=mwhite227,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Marie +uid: mwhite227 +sn: White +cn: Marie White +userPassword: 12345 + +dn: uid=tgasper854,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Thomas +uid: tgasper854 +sn: Gasper +cn: Thomas Gasper +userPassword: 12345 + +dn: uid=lhenderson949,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lisa +uid: lhenderson949 +sn: Henderson +cn: Lisa Henderson +userPassword: 12345 + +dn: uid=rbutler,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Robert +uid: rbutler +sn: Butler +cn: Robert Butler +userPassword: 12345 + +dn: uid=banderson971,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Betty +uid: banderson971 +sn: Anderson +cn: Betty Anderson +userPassword: 12345 + +dn: uid=jlewis917,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: James +uid: jlewis917 +sn: Lewis +cn: James Lewis +userPassword: 12345 + +dn: uid=lwalters703,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lori +uid: lwalters703 +sn: Walters +cn: Lori Walters +userPassword: 12345 + +dn: uid=mprice764,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Marie +uid: mprice764 +sn: Price +cn: Marie Price +userPassword: 12345 + +dn: uid=lwilliams,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lisa +uid: lwilliams +sn: Williams +cn: Lisa Williams +userPassword: 12345 + +dn: uid=amorrison30,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Ann +uid: amorrison30 +sn: Morrison +cn: Ann Morrison +userPassword: 12345 + +dn: uid=plee719,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Paul +uid: plee719 +sn: Lee +cn: Paul Lee +userPassword: 12345 + +dn: uid=klopez326,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Kiersten +uid: klopez326 +sn: Lopez +cn: Kiersten Lopez +userPassword: 12345 + +dn: uid=nlangenberg820,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Nancy +uid: nlangenberg820 +sn: Langenberg +cn: Nancy Langenberg +userPassword: 12345 + +dn: uid=klewis712,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Karl +uid: klewis712 +sn: Lewis +cn: Karl Lewis +userPassword: 12345 + +dn: uid=dclark720,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Donna +uid: dclark720 +sn: Clark +cn: Donna Clark +userPassword: 12345 + +dn: uid=jjohnson735,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Jennifer +uid: jjohnson735 +sn: Johnson +cn: Jennifer Johnson +userPassword: 12345 + +dn: uid=bwhite,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Blake +uid: bwhite +sn: White +cn: Blake White +userPassword: 12345 + +dn: uid=jdavis904,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Jo +uid: jdavis904 +sn: Davis +cn: Jo Davis +userPassword: 12345 + +dn: uid=jwhite265,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: James +uid: jwhite265 +sn: White +cn: James White +userPassword: 12345 + +dn: uid=edavis809,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Eric +uid: edavis809 +sn: Davis +cn: Eric Davis +userPassword: 12345 + +dn: uid=swalters,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Sarah +uid: swalters +sn: Walters +cn: Sarah Walters +userPassword: 12345 + +dn: uid=svales,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Sarah +uid: svales +sn: Vales +cn: Sarah Vales +userPassword: 12345 + +dn: uid=mgonazles,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Michael +uid: mgonazles +sn: Gonazles +cn: Michael Gonazles +userPassword: 12345 + +dn: uid=kwalters,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Karl +uid: kwalters +sn: Walters +cn: Karl Walters +userPassword: 12345 + +dn: uid=bwalters,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Betty +uid: bwalters +sn: Walters +cn: Betty Walters +userPassword: 12345 + +dn: uid=jbutler545,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Jennifer +uid: jbutler545 +sn: Butler +cn: Jennifer Butler +userPassword: 12345 + +dn: uid=jdoe780,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Jo +uid: jdoe780 +sn: Doe +cn: Jo Doe +userPassword: 12345 + +dn: uid=abrown,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Ann +uid: abrown +sn: Brown +cn: Ann Brown +userPassword: 12345 + +dn: uid=ggasper836,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Greg +uid: ggasper836 +sn: Gasper +cn: Greg Gasper +userPassword: 12345 + +dn: uid=emartinez,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Erik +uid: emartinez +sn: Martinez +cn: Erik Martinez +userPassword: 12345 + +dn: uid=jprice340,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: John +uid: jprice340 +sn: Price +cn: John Price +userPassword: 12345 + +dn: uid=bgrady203,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Bill +uid: bgrady203 +sn: Grady +cn: Bill Grady +userPassword: 12345 + +dn: uid=kwhite283,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Kim +uid: kwhite283 +sn: White +cn: Kim White +userPassword: 12345 + +dn: uid=blee483,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Betty +uid: blee483 +sn: Lee +cn: Betty Lee +userPassword: 12345 + +dn: uid=wdavis,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: William +uid: wdavis +sn: Davis +cn: William Davis +userPassword: 12345 + +dn: uid=egasper497,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Erik +uid: egasper497 +sn: Gasper +cn: Erik Gasper +userPassword: 12345 + +dn: uid=mwhite,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Mark +uid: mwhite +sn: White +cn: Mark White +userPassword: 12345 + +dn: uid=dbrown,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: David +uid: dbrown +sn: Brown +cn: David Brown +userPassword: 12345 + +dn: uid=nlee,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Nancy +uid: nlee +sn: Lee +cn: Nancy Lee +userPassword: 12345 + +dn: uid=sdavis,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Sarah +uid: sdavis +sn: Davis +cn: Sarah Davis +userPassword: 12345 + +dn: uid=cwalters,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Colin +uid: cwalters +sn: Walters +cn: Colin Walters +userPassword: 12345 + +dn: uid=nwalters,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Nancy +uid: nwalters +sn: Walters +cn: Nancy Walters +userPassword: 12345 + +dn: uid=kdoe490,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Kim +uid: kdoe490 +sn: Doe +cn: Kim Doe +userPassword: 12345 + +dn: uid=wscott,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: William +uid: wscott +sn: Scott +cn: William Scott +userPassword: 12345 + +dn: uid=nwilliams,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Nancy +uid: nwilliams +sn: Williams +cn: Nancy Williams +userPassword: 12345 + +dn: uid=dbrown739,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: David +uid: dbrown739 +sn: Brown +cn: David Brown +userPassword: 12345 + +dn: uid=wlopez,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: William +uid: wlopez +sn: Lopez +cn: William Lopez +userPassword: 12345 + +dn: uid=mhenderson959,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Mark +uid: mhenderson959 +sn: Henderson +cn: Mark Henderson +userPassword: 12345 + +dn: uid=khenderson874,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Karoline +uid: khenderson874 +sn: Henderson +cn: Karoline Henderson +userPassword: 12345 + +dn: uid=rdavis,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Robert +uid: rdavis +sn: Davis +cn: Robert Davis +userPassword: 12345 + +dn: uid=plopez,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Paul +uid: plopez +sn: Lopez +cn: Paul Lopez +userPassword: 12345 + +dn: uid=kjohnson,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Kiersten +uid: kjohnson +sn: Johnson +cn: Kiersten Johnson +userPassword: 12345 + +dn: uid=ksmith708,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Karl +uid: ksmith708 +sn: Smith +cn: Karl Smith +userPassword: 12345 + +dn: uid=dlewis327,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: David +uid: dlewis327 +sn: Lewis +cn: David Lewis +userPassword: 12345 + +dn: uid=mdavis897,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Michael +uid: mdavis897 +sn: Davis +cn: Michael Davis +userPassword: 12345 + +dn: uid=mmorrison,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Mark +uid: mmorrison +sn: Morrison +cn: Mark Morrison +userPassword: 12345 + +dn: uid=wwhite,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: William +uid: wwhite +sn: White +cn: William White +userPassword: 12345 + +dn: uid=klopez520,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Karoline +uid: klopez520 +sn: Lopez +cn: Karoline Lopez +userPassword: 12345 + +dn: uid=jlangenberg373,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: James +uid: jlangenberg373 +sn: Langenberg +cn: James Langenberg +userPassword: 12345 + +dn: uid=dpeterson613,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: David +uid: dpeterson613 +sn: Peterson +cn: David Peterson +userPassword: 12345 + +dn: uid=mdoe270,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Michael +uid: mdoe270 +sn: Doe +cn: Michael Doe +userPassword: 12345 + +dn: uid=wwilliams808,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: William +uid: wwilliams808 +sn: Williams +cn: William Williams +userPassword: 12345 + +dn: uid=mvales501,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Marie +uid: mvales501 +sn: Vales +cn: Marie Vales +userPassword: 12345 + +dn: uid=ppeterson,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Paul +uid: ppeterson +sn: Peterson +cn: Paul Peterson +userPassword: 12345 + +dn: uid=ldavis,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lori +uid: ldavis +sn: Davis +cn: Lori Davis +userPassword: 12345 + +dn: uid=bgasper28,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Bill +uid: bgasper28 +sn: Gasper +cn: Bill Gasper +userPassword: 12345 + +dn: uid=bprice745,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Betty +uid: bprice745 +sn: Price +cn: Betty Price +userPassword: 12345 + +dn: uid=ddoe,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Donna +uid: ddoe +sn: Doe +cn: Donna Doe +userPassword: 12345 + +dn: uid=lvales817,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lisa +uid: lvales817 +sn: Vales +cn: Lisa Vales +userPassword: 12345 + +dn: uid=wthompson675,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: William +uid: wthompson675 +sn: Thompson +cn: William Thompson +userPassword: 12345 + +dn: uid=landerson906,ou=people,dc=example,dc=edu +objectclass: organizationalPerson +objectclass: person +objectclass: top +objectclass: inetOrgPerson +objectclass: eduPerson +givenName: Lori +uid: landerson906 +sn: Anderson +cn: Lori Anderson +userPassword: 12345 + + diff --git a/deps/ldap/build.sh b/deps/ldap/build.sh new file mode 100755 index 0000000..cf52e68 --- /dev/null +++ b/deps/ldap/build.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker build . -t tier-demo-ldap diff --git a/deps/ldap/slapdconf/.gitignore b/deps/ldap/slapdconf/.gitignore new file mode 100644 index 0000000..43cdd53 --- /dev/null +++ b/deps/ldap/slapdconf/.gitignore @@ -0,0 +1,21 @@ +/blib/ +/.build/ +_build/ +cover_db/ +inc/ +Build +!Build/ +Build.bat +.last_cover_stats +/Makefile +/Makefile.old +/MANIFEST.bak +/META.yml +/META.json +/MYMETA.* +nytprof.out +/pm_to_blib +*.o +*.bs +*~ +DEADJOE diff --git a/deps/ldap/slapdconf/INSTALL b/deps/ldap/slapdconf/INSTALL new file mode 100644 index 0000000..178ab2d --- /dev/null +++ b/deps/ldap/slapdconf/INSTALL @@ -0,0 +1,17 @@ +SLAPDCONF INSTALLATION +---------------------- + +slapdconf is a set of Perl scripts. Unfortunatelly currently there are no +packages for any Linux distribution (help with packaging is highly +appreciated). Therefore simply copy the scripts to /usr/local/bin or +/usr/local/sbin. You will also need Perl libraries that these scrips +depend on: + +Net::LDAP +Authen::SASL +UUID +and perldoc + +In debian/ubuntu you can install those libraries by running: + +sudo apt-get install libnet-ldap-perl libauthen-sasl-perl libuuid-perl perl-doc diff --git a/deps/ldap/slapdconf/LICENSE b/deps/ldap/slapdconf/LICENSE new file mode 100644 index 0000000..5c304d1 --- /dev/null +++ b/deps/ldap/slapdconf/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/deps/ldap/slapdconf/README.md b/deps/ldap/slapdconf/README.md new file mode 100644 index 0000000..1329823 --- /dev/null +++ b/deps/ldap/slapdconf/README.md @@ -0,0 +1,86 @@ +Slapdconf Project +================= + +OpenLDAP configuration utilities. +These utilities make configuration of OpenLDAP easier - especially after the +switch to the OLC-stype configuration which uses the cn=config LDAP suffix. + +Synopsis +======== + +``` +$ sudo slapdconf list-suffixes +dc=evolveum,dc=com +dc=example,dc=com + +$ sudo slapdconf get-suffix-prop dc=example,dc=com +olcDatabase : {2}mdb +olcDbDirectory : /var/lib/ldap/example +.... (shorted for clarity) .... + +$ sudo slapdconf set-server-prop idle-timeout:120 + +$ sudo slapdconf get-server-prop +olcIdleTimeout : 120 +olcLogLevel : + stats + stats2 +``` + +Description +=========== + +There are two utilities in this project: + +slapdconf - Command-line tool to configure a running OpenLDAP. +slapdadm - Command-line tool to configure stopped OpenLDAP. + +slapdconf +========= + +This command-line tool is used to configure a runnint OpenLDAP server instance. +It uses LDAP protocol to change the cn=config subtree of an OpenLDAP server. +The configuration changes are applied without a server restart. + +It can reconfigure the sever, create new directory suffixes, setup +replication, etc. + +Examples: +--------- +``` +slapdconf -h myserver.example.com -D "uid=admin,ou=people,dc=example,dc=com" -w secret get-server-prop +slapdconf -Y EXTERNAL list-suffixes +slapdconf -Y EXTERNAL create-suffix dc=example,dc=com --dbDir /var/lib/ldap/dc=example,dc=com --rootPassword supersecret +``` + + +slapdadm +======== + +This command-line tool is used to configure a stopped OpenLDAP instance. The configuration +is done by direct manipulation of files in C directory and the database +files. + +It can be used for operations that slapdconf cannot do. E.g. it can claen-up the OpenLDAP +configuration that is provided by your Linux distribution and that somehow never quite +fits. Then a slapdconf tool can be used to replace it with a proper setup. + +Examples: +--------- +``` +slapdadm delete-suffix dc=example,dc=com +slapdadm delete-all +``` + +Notes +===== + +This is work in progress. Some commands are not yet implemented or implemented partially. Any kind of +contribution to make these tools a more complete solution is greatly appreciated. The primary source +code repository for these tools is at Github: + +[https://github.com/Evolveum/slapdconf] + +The tools are written in Perl. The slapdconf uses Net::LDAP module which is easy to use LDAP client. +The Perl was chosen because of its flexibility. It also looks like it is kind of a tradition to use +Perl for LDAP server administration tools. diff --git a/deps/ldap/slapdconf/delschema b/deps/ldap/slapdconf/delschema new file mode 100644 index 0000000..485f59c --- /dev/null +++ b/deps/ldap/slapdconf/delschema @@ -0,0 +1,199 @@ +#!/usr/bin/perl -w +# +# Copyright (c) 2010-2015 Radovan Semancik +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# delschema +# ----------- +# A tool to delete a custom schema or parts of the schema from LDAP server +# + +use strict; +use Net::LDAP; +use Data::Dumper; + +my $verbose = 0; +my $hostname = "localhost"; +my $port = "389"; +my $schemaDn = "cn=schema"; +my $pattern = undef; +my $bindDn = undef; +my $bindPassword = undef; + +# ===[ Command-line processing ]================================== + +while (@ARGV) { + + my $param = shift @ARGV; + + if (substr($param,0,1) eq '-') { + + if ($param eq '-h') { + usage(); + exit(0); + + } elsif ($param eq '-v') { + $verbose++; + + } elsif ($param eq '-h') { + $hostname = shift @ARGV; + + if (!defined($hostname)) { + print STDERR "Missing value for the -h switch\n"; + usage(); + exit(-1); + } + + } elsif ($param eq '-p') { + $port = shift @ARGV; + + if (!defined($port)) { + print STDERR "Missing value for the -p switch\n"; + usage(); + exit(-1); + } + + } elsif ($param eq '-D') { + $bindDn = shift @ARGV; + + if (!defined($bindDn)) { + print STDERR "Missing value for the -D switch\n"; + usage(); + exit(-1); + } + + } elsif ($param eq '-w') { + $bindPassword = shift @ARGV; + + if (!defined($bindPassword)) { + print STDERR "Missing value for the -w switch\n"; + usage(); + exit(-1); + } + + } else { + print STDERR "Unknown switch $param\n"; + usage(); + exit(-1); + } + } else { + unshift(@ARGV,$param); + last; + } + +} + +if ($verbose > 1) { + # Print configuration + + print "CONFIGURATION:\n"; + print " verbose: $verbose\n"; + print " hostname: $hostname\n"; + print " port: $port\n"; + print "\n"; + +} + +# ===[ MAIN Part of the Script ]================================== + +print "Starting script ...\n" if $verbose; +print "Command line after pocessing the switches: @ARGV\n" if ($verbose > 1); + +my $ldap = Net::LDAP->new( $hostname, + port => $port, + ) or die "$@"; + +print "Connected to $hostname:$port\n" if ($verbose > 1); + + +if (defined($bindDn)) { + my $mesg = $ldap->bind($bindDn, password => $bindPassword); + if ($mesg->code) { die "Bind error: ".$mesg->error." (".$mesg->code.")"; }; + print "Bound as $bindDn\n" if $verbose; +} else { + print "Anonymous bind\n" if $verbose; +} + +my $mesg = $ldap->search(base => $schemaDn, + filter => "objectclass=*", + scope => "base", + attrs => ["objectClasses", "attributeTypes"]); + +if ($mesg->code) { die "Search error: ".$mesg->error." (".$mesg->code.")"; }; + +my %toDelete = (); + +print "Found:\n" if $verbose; +foreach my $entry ($mesg->entries) { + foreach my $attr ($entry->attributes) { + my @values = $entry->get_value($attr); + print " $attr:".scalar(@values)."\n" if $verbose; + $toDelete{$attr} = []; + foreach my $value (@values) { + if (defined($pattern)) { + # TODO + } else { + if ($value =~ /X-ORIGIN 'user defined'/) { + print "$attr: $value\n" if ($verbose > 1); + push(@{$toDelete{$attr}},$value); + } + } + } + } +} + +print Dumper(\%toDelete) if ($verbose > 2); + +if ($verbose) { + print "Going to delete:\n"; + foreach my $attr (keys %toDelete) { + print " $attr:".scalar(@{$toDelete{$attr}})."\n" if $verbose; + } +} + + +foreach my $attr (keys %toDelete) { + if (scalar(@{$toDelete{$attr}}) == 0 ) { + delete $toDelete{$attr}; + } +} + +if (%toDelete) { + + $mesg = $ldap->modify($schemaDn, + delete => \%toDelete, + ); + if ($mesg->code) { die "Modify error: ".$mesg->error." (".$mesg->code.")"; }; + + print "Deleted\n" if $verbose; + +} else { + print "Nothing to delete\n" if $verbose; +} + +print "Finishing script ...\n" if $verbose; + +# ===[ Display Usage Message ]================================== +# +# Displays script description with a short usage summary + +sub usage { + print "A tool to delete a custom schema or parts of the schema from LDAP server\n"; + print "Usage: $0 [-h] [-v] [-v ...] [-s ] []\n"; + print " -h Help message\n"; + print " -v Verbose operation\n"; + print " (use multiple times to increase verbosity)\n"; + print " -s Set new value for separator\n"; + print "If no input file is specified, standard input is used\n"; +} diff --git a/deps/ldap/slapdconf/ldapgenerate b/deps/ldap/slapdconf/ldapgenerate new file mode 100755 index 0000000..d90c913 --- /dev/null +++ b/deps/ldap/slapdconf/ldapgenerate @@ -0,0 +1,427 @@ +#!/usr/bin/perl +# +# Copyright (c) 2014 Evolveum +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Author: Radovan Semancik +# +# Required packages: +# Ubuntu: libnet-ldap-perl libauthen-sasl-perl + +use strict; +use warnings; + +use Net::LDAP; +use Net::LDAP::LDIF; +use Net::LDAP::Util qw(ldap_explode_dn); +use Authen::SASL; +use Digest::SHA qw(sha1); +use MIME::Base64; +use Getopt::Long qw(:config bundling no_auto_abbrev pass_through); +use Pod::Usage; +use Data::Dumper; + +my ($verbose,$optHelp); +my $hostname; +my $port; +my $uri; +my ($bindDn,$bindPassword,$bindSaslMechanism); + +my $debug = 0; + +# my $defaultTLSCipherSuite = "TLSv1+RSA:!EXPORT:!NULL"; # OpenSSL +my $defaultTLSCipherSuite = "NORMAL"; # GnuTLS +my $suffix = "dc=example,dc=com"; +my $peopleContainer = "ou=people"; +my $groupsContainer = "ou=groups"; +my $defaultNamingAttribute="uid"; +my $defaultNameFormat="u%08d"; +my $defaultPasswordFormat="p%08d"; +my $defaultObjectClasses = [ qw(top person organizationalPerson inetOrgPerson) ]; +my $noPersonAttrs = 0; +my $notReally = 0; +my $continuous = 0; +my $initialize = 0; +my $quiet = 0; +my $startIndex = 0; +my $passwordHash = 'SSHA'; +my $outFilename; +my $displayCountAfter = 100; +my @saltChars = ('.','/',0..9,'A'..'Z','a'..'z'); +my @consonants = (qw(b c d f g h j k l m n p r s t v w x z)); +my @vowels = (qw(a e i o u)); + +$SIG{__DIE__} = sub { Carp::confess(@_) }; + +my $numEntries; +if (defined $ARGV[0] && $ARGV[0] !~ /^-/) { + $numEntries = shift; +} + +GetOptions ( + "hostname|h=s" => \$hostname, + "port|p=i" => \$port, + "uri|H=s" => \$uri, + "bindDn|D=s" => \$bindDn, + "bindPassword|w=s" => \$bindPassword, + "saslMechanism|Y=s" => \$bindSaslMechanism, + "suffix|s=s" => \$suffix, + "init|i" => \$initialize, + "startIndex=i" => \$startIndex, + "passwordHash=s" => \$passwordHash, + "file|f=s" => \$outFilename, + "notReally|n" => \$notReally, + "continuous|c" => \$continuous, + "quiet|q" => \$quiet, + "verbose|v" => \$verbose, + "help" => \$optHelp, + ) or usage(); +usage() if $optHelp; + +if (!defined($numEntries)) { + $numEntries = shift; +} + +if (!$numEntries && !$initialize) { usage(); } +if (defined $numEntries && $numEntries eq "--help") { usage(); } + +if (!$hostname && !$port && !$uri) { + $uri = "ldapi:///"; +} elsif ($hostname && !$port) { + $port = 389; +} elsif (!$hostname && $port) { + $hostname = "localhost"; +} + +if (!$bindDn && !$bindPassword && !$bindSaslMechanism) { + $bindSaslMechanism = "EXTERNAL"; +} + +print("DEBUG: $numEntries: hostname: $hostname, port: $port\n") if $debug; + +run(); + +sub run { + + my $conn = ldapConnectBind(); + + if ($initialize) { + initialize($conn); + } + + if ($numEntries) { + generateEntries($conn); + } + + ldapDisconnect($conn); +} + +sub initialize { + my ($conn) = @_; + + my $explodedSuffix = ldap_explode_dn($suffix); + my $suffixFirst = $explodedSuffix->[0]; + + ldapAddSimple($conn, $suffix, "domain"); + ldapAddSimple($conn, "$peopleContainer,$suffix", "organizationalunit"); + ldapAddSimple($conn, "$groupsContainer,$suffix", "organizationalunit"); +} + +sub ldapAddSimple { + my ($conn, $dn, $objectclass) = @_; + my $explodedDn = ldap_explode_dn($dn); + ldapAdd($conn, $dn, + objectClass => $objectclass, + %{$explodedDn->[0]}, + ); + +} + +sub generateEntries { + my ($conn) = @_; + + my $startTime = time(); + my $entryNum = 0; + my $entryIndex = $startIndex; + for (; $entryNum < $numEntries; $entryNum++) { + + my $name = sprintf($defaultNameFormat, $entryIndex); + my $readableName; + my %personAttrs = (); + if (!$noPersonAttrs) { + my $sn = randomName(); + my $givenName = randomName(); + my $cn = sprintf("%s %s (%08d)", $givenName, $sn, $entryIndex); + my $password = sprintf($defaultPasswordFormat, $entryIndex); + %personAttrs = ( + 'cn' => $cn, + 'sn' => $sn, + 'givenName' => $givenName, + 'userPassword' => hashPassword($password), + ); + $readableName = "$givenName $sn"; + } + + my $dn = "$defaultNamingAttribute=$name,$peopleContainer,$suffix"; + my %entryData = ( + 'objectClass' => $defaultObjectClasses, + $defaultNamingAttribute => $name, + %personAttrs, + ); + + if ($verbose) { + print "Adding entry $entryIndex: $dn"; + print " ($readableName)" if $readableName; + print "\n"; + } + + ldapAdd($conn, $dn, %entryData); + + if (!$quiet && $entryNum != 0 && ( $entryNum % $displayCountAfter == 0 )) { + my $nowTime = time(); + my $durSec = $nowTime - $startTime; + my $etaSec = ($durSec*($numEntries-$entryNum))/$entryNum; + my $rate = "INF"; + if ($durSec != 0) { + $rate = $entryNum/$durSec; + } + my $etaEnd = localtime($nowTime + $etaSec); + print "$entryIndex: Added $entryNum entries in $durSec seconds ($rate entries per second). ETA in $etaSec sec ($etaEnd)\n"; + } + $entryIndex++; + } + + my $stopTime = time(); + my $durSec = $stopTime - $startTime; + if (!$quiet) { + my $rate; + if ($durSec) { + $rate = $entryNum/$durSec; + } else { + $rate = "more than ".$entryNum; + } + print "Added $entryNum entries in $durSec seconds ($rate entries per second).\n"; + } + +} + +##### UTIL functions + + +sub randomName { + my $numsyl = int(rand(2)) + 2; + my $out = ""; + for (1..$numsyl) { + $out .= $consonants[rand(@consonants)]; + $out .= $vowels[rand(@vowels)]; + if (rand(2) > 1) { + $out .= $consonants[rand(@consonants)]; + } + } + return ucfirst($out); +} + +sub hashPassword { + my ($clearPassword) = @_; + + if (!$passwordHash || uc($passwordHash) eq 'NONE') { + return $clearPassword; + } elsif (uc($passwordHash) eq 'SSHA') { + my $salt = generateSalt(); + my $hash = "{SSHA}".encode_base64(sha1($clearPassword.$salt).$salt, ""); + return $hash; + } else { + die ("Unknown password hash algorithm '$passwordHash'\n"); + } +} + +sub generateSalt { + return join('',map {$saltChars[rand(64)]} (1..4)); +} + +####### LDAP functions + +sub ldapConnect { + my $conn; + if ($uri) { + $conn = Net::LDAP->new($uri) or die("Error connecting to $uri: ".$@."\n"); + } else { + $conn = Net::LDAP->new($hostname, + port => $port, + ) or die("Error connecting to $hostname:$port: ".$@."\n"); + } + return $conn; +} + +sub ldapBind { + my ($conn,$die) = @_; + + my $resp; + my $desc; + if ($bindDn) { + $desc = "$bindDn (simple bind)"; + $resp = $conn->bind($bindDn, + password => $bindPassword, + ); + } elsif ($bindSaslMechanism) { + $desc = "(SASL $bindSaslMechanism)"; + $resp = $conn->bind($bindDn, + sasl => Authen::SASL->new( + mechanism => $bindSaslMechanism, + ), + ); + } else { + $desc = "(anonymous bind)"; + $resp = $conn->bind(); + } + if ($die && $resp->code) { + die("Error binding as $desc: ".$resp->error." (".$resp->code.")\n"); + } + return ($resp,$desc); +} + +sub ldapConnectBind { + if ($outFilename) { + open my $outFile, '>', $outFilename or die("Cannot open output file $outFilename: $!\n"); + return $outFile; + } + + my $conn = ldapConnect(); + ldapBind($conn,1); + return $conn; +} + +sub ldapAdd { + my ($conn,$dn,%attrs) = @_; + + my $entry = Net::LDAP::Entry->new($dn, %attrs); + + if ($outFilename) { + print $conn $entry->ldif(); + return; + } + + if (!$notReally) { + my $resp = $conn->add($entry); + if ($resp->code) { + if ($continuous) { + print STDERR "Error adding $dn: ".$resp->error." (".$resp->code.")\n"; + } else { + die("Error adding $dn: ".$resp->error." (".$resp->code.")\n"); + } + } + } else { + print "Would add entry:"; + print $entry->ldif; + print "\n"; + } +} + +sub ldapDisconnect { + my ($conn) = @_; + + if ($outFilename) { + close $conn; + return; + } + + my $resp = $conn->unbind; + if ($resp->code) { + die("Unbind: ERROR: ".$resp->error." (".$resp->code.")\n"); + } + + $conn->disconnect; +} + +### USAGE and DOCUMENTATION + +sub usage { + pod2usage(-verbose => 2); + exit(1); +} + +sub man { + pod2usage(-verbose => 3); + exit(0); +} + +__END__ + +=head1 NAME + +ldapgenerate - LDAP entry generator + +=head1 SYNOPSIS + +ldapgenerate [options] numentries + + +=head1 OPTIONS + +=over 8 + +=item [ B<-h> | B<--hostname> ] I + +Specifies hostname of the LDAP server. + +=item [ B<-p> | B<--port> ] I + +Specifies port number of the LDAP server. Defaults to 389. + +=item [ B<-H> | B<--uri> ] I + +Specifies complete URI for LDAP server connection. ldap://, ldaps:// and ldapi:// URIs can be used. +Defaults to C + +=item [ B<-D> | B<--bindDn> ] I + +Specifies DN which will be used for LDAP Bind operation. + +=item [ B<-w> | B<--bindPassword> ] I + +Specifies password which will be used for LDAP Bind operation. + +=item [ B<-Y> | B<--saslMechanism> ] I + +Specifies a SASL mechanism to used for LDAP Bind operation. + +=item [ B<-v> | B<--verbose> ] + +Increases verbosity. + +=item B<--help> + +Displays help message. + +=back + +=head1 DESCRIPTION + +TODO + +=head1 EXAMPLES + + ldapgenerate -h myserver.example.com -D "uid=admin,ou=people,dc=example,dc=com" -w secret 100 + + slapdconf -Y EXTERNAL 1000 + +=head1 NOTES + +This is still work in progress. Please feel free to contribute. + +=head1 AUTHOR + +Radovan Semancik + +=cut diff --git a/deps/ldap/slapdconf/ldaptest b/deps/ldap/slapdconf/ldaptest new file mode 100755 index 0000000..5ceeebc --- /dev/null +++ b/deps/ldap/slapdconf/ldaptest @@ -0,0 +1,432 @@ +#!/usr/bin/perl +# +# Copyright (c) 2014 Evolveum +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Author: Radovan Semancik +# +# Required packages: +# Ubuntu: libnet-ldap-perl libauthen-sasl-perl + +use strict; +use warnings; + +use Net::LDAP; +use Net::LDAP::LDIF; +use Net::LDAP::Util qw(ldap_explode_dn); +use Net::LDAP::Control::VLV; +use Net::LDAP::Control::Sort; +use Net::LDAP::Constant qw( LDAP_CONTROL_VLVRESPONSE ); +use Authen::SASL; +use Digest::SHA qw(sha1); +use MIME::Base64; +use Getopt::Long qw(:config bundling no_auto_abbrev pass_through); +use Pod::Usage; +use Data::Dumper; + +my ($verbose,$optHelp); +my $hostname; +my $port; +my $uri; +my ($bindDn,$bindPassword,$bindSaslMechanism); + +my $debug = 0; + +# my $defaultTLSCipherSuite = "TLSv1+RSA:!EXPORT:!NULL"; # OpenSSL +my $defaultTLSCipherSuite = "NORMAL"; # GnuTLS +my $suffix = "dc=example,dc=com"; +my $peopleContainer = "ou=people"; +my $groupsContainer = "ou=groups"; +my $defaultNamingAttribute="uid"; +my $defaultNameFormat="u%08d"; +my $defaultPasswordFormat="p%08d"; +my $defaultObjectClasses = [ qw(top person organizationalPerson inetOrgPerson) ]; +my $noPersonAttrs = 0; +my $continuous = 0; +my $quiet = 0; +my $numEntries = "100000"; +my $cycles = "10000"; + +my $displayCountAfter = 1000; + +$SIG{__DIE__} = sub { Carp::confess(@_) }; + +my $test; +if (defined $ARGV[0] && $ARGV[0] !~ /^-/) { + $test = shift; +} + +GetOptions ( + "hostname|h=s" => \$hostname, + "port|p=i" => \$port, + "uri|H=s" => \$uri, + "bindDn|D=s" => \$bindDn, + "bindPassword|w=s" => \$bindPassword, + "saslMechanism|Y=s" => \$bindSaslMechanism, + "suffix|s=s" => \$suffix, + "continuous|c" => \$continuous, + "entries|e=i" => \$numEntries, + "cycles|C=i" => \$cycles, + "quiet|q" => \$quiet, + "verbose|v" => \$verbose, + "help" => \$optHelp, + ) or usage(); +usage() if $optHelp; + +if (!defined($test)) { + $test = shift; +} + +if (!$test) { usage(); } +if ($test eq "--help") { usage(); } + +if (!$hostname && !$port && !$uri) { + $uri = "ldapi:///"; +} elsif ($hostname && !$port) { + $port = 389; +} elsif (!$hostname && $port) { + $hostname = "localhost"; +} + +if (!$bindDn && !$bindPassword && !$bindSaslMechanism) { + $bindSaslMechanism = "EXTERNAL"; +} + +print("DEBUG: $test: hostname: $hostname, port: $port\n") if $debug; + +run(); + +sub run { + + my $conn = ldapConnectBind(); + + if ($test eq "searchBase") { + runTest($conn,"base search", + sub { + my $index = int(rand($numEntries)); + my $name = sprintf($defaultNameFormat, $index); + my $dn = "$defaultNamingAttribute=$name,$peopleContainer,$suffix"; + my $entry = ldapSeachSingle($conn, + base => $dn, + filter => "(objectclass=*)", + scope => "base", + ); + return $entry; + } + ); + + } elsif ($test eq "searchUid") { + runTest($conn,"search by uid", + sub { + my $index = int(rand($numEntries)); + my $name = sprintf($defaultNameFormat, $index); + my $dn = "$peopleContainer,$suffix"; + my $entry = ldapSeachSingle($conn, + base => $dn, + filter => "($defaultNamingAttribute=$name)", + scope => "sub", + ); + return $entry; + } + ); + + } elsif ($test eq "searchCnSubstr") { + runTest($conn,"substring search by cn", + sub { + my $index = int(rand($numEntries)); + my $substr = sprintf("%07d", $index/10); + my $dn = "$peopleContainer,$suffix"; + my $resp = ldapSeach($conn, + base => $dn, + filter => "(cn=*$substr*)", + scope => "sub", + ); + if ($resp->count < 10 || $resp->count > 11) { + print STDERR "Got ".$resp->count.", expected 10 or 11: ".$substr."\n"; + return undef; + } + return $resp; + } + ); + + } elsif ($test eq "searchUidVlv") { + vlvSearch($conn, 'uid', 9); + + } elsif ($test eq "searchCnVlv") { + vlvSearch($conn, 'cn', 9); + + } else { + die("Unknown test $test\n"); + } + + ldapDisconnect($conn); +} + +sub vlvSearch { + my ($conn, $sortAttr, $after) = @_; + my $vlv = Net::LDAP::Control::VLV->new( + before => 0, + after => $after, + content => 0, + offset => 1, + ); + my $sort = Net::LDAP::Control::Sort->new( order => 'uid:2.5.13.3' ); + my $dn = "$peopleContainer,$suffix"; + + runTest($conn,"VLV search by ".$sortAttr, + sub { + my $index = int(rand($numEntries)); + $vlv->offset($index); + my $resp = ldapSeach($conn, + base => $dn, + filter => "(objectclass=inetorgperson)", + scope => "sub", + control => [ $sort, $vlv], + ); + if ($resp->count < 1 || $resp->count > $after + 1) { + print STDERR "Got ".$resp->count.", expected max ".($after+1).": ".$index."\n"; + return undef; + } + my $vlvresp = $resp->control( LDAP_CONTROL_VLVRESPONSE ) or die; + $vlv->response($vlvresp); + return $resp; + } + ); +} + +sub runTest { + my ($conn,$testName,$searchClosure) = @_; + + if (!$quiet) { + print "Staring $testName test, $cycles cycles\n"; + } + + my $startTime = time(); + my $try = 1; + my $errors = 0; + for (; $try <= $cycles; $try++) { + + my $testResult = &$searchClosure($try); + + if ($testResult) { + # TODO: check entry + } else { + $errors++; + } + + if (!$quiet && ( $try % $displayCountAfter == 0 )) { + my $nowTime = time(); + my $durSec = $nowTime - $startTime; + my $etaSec = ($durSec*($cycles-$try))/$try; + my $rate = "INF"; + if ($durSec != 0) { + $rate = $try/$durSec; + } + my $etaEnd = localtime($nowTime + $etaSec); + print "$try ops in $durSec seconds ($rate ops per second). ETA in $etaSec sec ($etaEnd)\n"; + } + } + + my $stopTime = time(); + my $durSec = $stopTime - $startTime; + if (!$quiet) { + my $rate = $try/$durSec; + print "$try $testName ops in $durSec seconds\n"; + print "$rate ops per second\n"; + print "average op duration ".(($durSec/$try)*1000)."ms\n"; + print "errors: $errors\n"; + } + +} + +##### UTIL functions + +####### LDAP functions + +sub ldapConnect { + my $conn; + if ($uri) { + $conn = Net::LDAP->new($uri) or die("Error connecting to $uri: ".$@."\n"); + } else { + $conn = Net::LDAP->new($hostname, + port => $port, + ) or die("Error connecting to $hostname:$port: ".$@."\n"); + } + return $conn; +} + +sub ldapBind { + my ($conn,$die) = @_; + + my $resp; + my $desc; + if ($bindDn) { + $desc = "$bindDn (simple bind)"; + $resp = $conn->bind($bindDn, + password => $bindPassword, + ); + } elsif ($bindSaslMechanism) { + $desc = "(SASL $bindSaslMechanism)"; + $resp = $conn->bind($bindDn, + sasl => Authen::SASL->new( + mechanism => $bindSaslMechanism, + ), + ); + } else { + $desc = "(anonymous bind)"; + $resp = $conn->bind(); + } + if ($die && $resp->code) { + die("Error binding as $desc: ".$resp->error." (".$resp->code.")\n"); + } + return ($resp,$desc); +} + +sub ldapConnectBind { + my $conn = ldapConnect(); + ldapBind($conn,1); + return $conn; +} + +sub ldapSeach { + my ($conn,%params) = @_; + + my $resp = $conn->search(%params); + + if ($resp->code) { + if ($continuous) { + print STDERR "Error searching ".$params{base}.": ".$resp->error." (".$resp->code.")\n"; + return undef; + } else { + die("Error searching ".$params{base}.": ".$resp->error." (".$resp->code.")\n"); + } + } + + return $resp; +} + +sub ldapSeachSingle { + my ($conn,%params) = @_; + my $resp = ldapSeach($conn,%params); + if ($resp->count == 0) { + if ($continuous) { + print STDERR "Error searching ".$params{base}.": no object found\n"; + return undef; + } else { + die("Error searching ".$params{base}.": no object found\n"); + } + } + if ($resp->count > 1) { + if ($continuous) { + print STDERR "Error searching ".$params{base}.": ".$resp->count." entries found, expected just one\n"; + return undef; + } else { + die("Error searching ".$params{base}.": ".$resp->count." entries found, expected just one\n"); + } + } + return $resp->entry(0); +} + +sub ldapDisconnect { + my ($conn) = @_; + + my $resp = $conn->unbind; + if ($resp->code) { + die("Unbind: ERROR: ".$resp->error." (".$resp->code.")\n"); + } + + $conn->disconnect; +} + +### USAGE and DOCUMENTATION + +sub usage { + pod2usage(-verbose => 2); + exit(1); +} + +sub man { + pod2usage(-verbose => 3); + exit(0); +} + +__END__ + +=head1 NAME + +ldapgenerate - LDAP entry generator + +=head1 SYNOPSIS + +ldapgenerate [options] numentries + + +=head1 OPTIONS + +=over 8 + +=item [ B<-h> | B<--hostname> ] I + +Specifies hostname of the LDAP server. + +=item [ B<-p> | B<--port> ] I + +Specifies port number of the LDAP server. Defaults to 389. + +=item [ B<-H> | B<--uri> ] I + +Specifies complete URI for LDAP server connection. ldap://, ldaps:// and ldapi:// URIs can be used. +Defaults to C + +=item [ B<-D> | B<--bindDn> ] I + +Specifies DN which will be used for LDAP Bind operation. + +=item [ B<-w> | B<--bindPassword> ] I + +Specifies password which will be used for LDAP Bind operation. + +=item [ B<-Y> | B<--saslMechanism> ] I + +Specifies a SASL mechanism to used for LDAP Bind operation. + +=item [ B<-v> | B<--verbose> ] + +Increases verbosity. + +=item B<--help> + +Displays help message. + +=back + +=head1 DESCRIPTION + +TODO + +=head1 EXAMPLES + + ldapgenerate -h myserver.example.com -D "uid=admin,ou=people,dc=example,dc=com" -w secret 100 + + slapdconf -Y EXTERNAL 1000 + +=head1 NOTES + +This is still work in progress. Please feel free to contribute. + +=head1 AUTHOR + +Radovan Semancik + +=cut diff --git a/deps/ldap/slapdconf/openldap_midpoint.sh b/deps/ldap/slapdconf/openldap_midpoint.sh new file mode 100755 index 0000000..ebe646c --- /dev/null +++ b/deps/ldap/slapdconf/openldap_midpoint.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# openldap_midpoint.sh, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan +echo "Configuring LDAP for Midpoint.." +set -x +slapdconf add-module sssvlv +slapdconf add-overlay dc=example,dc=edu sssvlv +slapdconf add-module ppolicy +ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif +slapdconf add-overlay dc=example,dc=edu ppolicy +slapdconf add-module memberof +slapdconf add-overlay dc=example,dc=edu memberof +slapdconf add-module refint +slapdconf add-overlay dc=example,dc=edu refint olcRefintConfig 'olcRefintAttribute:memberof member manager owner' +slapdconf set-suffix-prop dc=example,dc=edu 'olcLimits:dn.exact="cn=admin,dc=example,dc=edu" size.prtotal=unlimited' +ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/local/bin/pwpolicy.ldif +rm /usr/local/bin/pwpolicy.ldif +slapdconf set-overlay-prop dc=example,dc=edu ppolicy olcPPolicyDefault:cn=pwpolicy,dc=example,dc=edu +set +x +echo "Done configuring LDAP for Midpoint" diff --git a/deps/ldap/slapdconf/pwpolicy.ldif b/deps/ldap/slapdconf/pwpolicy.ldif new file mode 100644 index 0000000..e970e5a --- /dev/null +++ b/deps/ldap/slapdconf/pwpolicy.ldif @@ -0,0 +1,9 @@ +dn: cn=pwpolicy,dc=example,dc=com +objectclass: pwdPolicy +objectClass: person +cn: pwpolicy +sn: pwpolicy +pwdAttribute: userPassword +pwdMaxFailure: 3 +pwdLockout: TRUE +pwdLockoutDuration: 60 diff --git a/deps/ldap/slapdconf/samples/piracy/piracy-schema-modify.ldif b/deps/ldap/slapdconf/samples/piracy/piracy-schema-modify.ldif new file mode 100644 index 0000000..136dfc8 --- /dev/null +++ b/deps/ldap/slapdconf/samples/piracy/piracy-schema-modify.ldif @@ -0,0 +1,16 @@ +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.1 NAME 'piracyShipName' DESC 'The name of thar vessel' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.2 NAME 'piracyStatus' DESC 'Current whereabouts of a pirate.' EQUALITY caseExactIA5Match SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.3 NAME 'piracyScarNumber' DESC 'The number of pirate's scars.' EQUALITY integerMatch ORDERING integerOrderingMatch SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.4 NAME 'piracyCaptainship' DESC 'Whether the pirate honors himself with a capitain title.' SINGLE-VALUE SUP name X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.5 NAME 'piracyEnrollmentTimestamp' DESC 'Piratical enrollment date' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.6 NAME 'piracyTreasureSecret' DESC 'A secret code that a pirate keeps for tharself.' EQUALITY octetStringMatch SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.7 NAME 'piracyNickname' DESC 'Piratical nickname' SUP name X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.8 NAME 'piracyBestWeapon' DESC 'Pirates best weapon' SUP name X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.9 NAME 'piracyQuote' DESC 'Pirates most infamous quote' SINGLE-VALUE SUP name X-ORIGIN 'user defined' ) +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.10 NAME 'piracyDrink' DESC 'Pirates best drink' SUP name X-ORIGIN 'user defined' ) +- +add: objectClasses +objectClasses: ( 1.3.6.1.4.1.23611.4.1.1.1 NAME 'piracyPerson' DESC 'Piratical person. A pirate. Mighty pirate.' SUP inetOrgPerson STRUCTURAL MAY ( piracyShipName $ piracyStatus $ piracyScarNumber $ piracyCaptainship $ piracyEnrollmentTimestamp $ piracyTreasureSecret $ piracyNickname $ piracyBestWeapon $ piracyQuote $ piracyDrink ) X-ORIGIN 'user defined' ) diff --git a/deps/ldap/slapdconf/samples/piracy/piracy-schema.ldif b/deps/ldap/slapdconf/samples/piracy/piracy-schema.ldif new file mode 100644 index 0000000..7cb2d52 --- /dev/null +++ b/deps/ldap/slapdconf/samples/piracy/piracy-schema.ldif @@ -0,0 +1,168 @@ +dn: cn=schema +objectClass: top +objectClass: ldapSubentry +objectClass: subschema +cn: schema +# Piracy LDAP Schema Example +# +# Copyright (c) 2011-2015 Radovan Semancik +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#---------------------------------------------------------------------- +# Attributes +#---------------------------------------------------------------------- +# +# All attribute values conform exatly to LDAP schema definition unless +# specified otherwise. For example, all Strings with directory string +# syntax may have national characters (any valid unicode codepoint), may +# contain spaces, etc. - unless that is explicitly constrained by +# comments in this schema definition. +# +# Case sensitivity is determined by EQUALITY matching rule (unless +# explicitly specified otherwise). +# +# piracyShipName +# +# Description: +# The name of thar vessel +# +# Format: String +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.1 NAME 'piracyShipName' DESC 'The name of thar vessel' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) +# piracyStatus +# +# Description: +# Current whereabouts of a pirate. +# +# Format: Choose one from: +# alive +# dead +# undead +# drunk +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.2 NAME 'piracyStatus' DESC 'Current whereabouts of a pirate.' EQUALITY caseExactIA5Match SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'user defined' ) +# piracyScarNumber +# +# Description: +# The number of pirate's scars. +# +# Format: Integer +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.3 NAME 'piracyScarNumber' DESC 'The number of pirate's scars.' EQUALITY integerMatch ORDERING integerOrderingMatch SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 X-ORIGIN 'user defined' ) +# piracyCaptainship +# +# Description: +# Whether the pirate honors himself with a capitain title. +# +# Format: Boolean encoded as string +# "0", "false": not a captain +# "1", "true": is a captain +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.4 NAME 'piracyCaptainship' DESC 'Whether the pirate honors himself with a capitain title.' SINGLE-VALUE SUP name X-ORIGIN 'user defined' ) +# piracyEnrollmentTimestamp +# +# Description: +# The date and time of a pirate stopping to be a landluber and becomming +# a mighty pirate. +# +# Format: generalized time (absolute timestamp) in UTC +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.5 NAME 'piracyEnrollmentTimestamp' DESC 'Piratical enrollment date' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 X-ORIGIN 'user defined' ) +# piracyTreasureSecret +# +# Description: +# A secret code that a pirate keeps for tharself. +# +# Format: OctetString (binary) +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.6 NAME 'piracyTreasureSecret' DESC 'A secret code that a pirate keeps for tharself.' EQUALITY octetStringMatch SINGLE-VALUE SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 X-ORIGIN 'user defined' ) +# piracyNickname +# +# Description: +# A piratical name that pirate's maties will call the pirate. +# Thar might be many such names. +# +# Format: String (Multivalued) +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.7 NAME 'piracyNickname' DESC 'Piratical nickname' SUP name X-ORIGIN 'user defined' ) +# piracyBestWeapon +# +# Description: +# A weapon that the pirate likes the most. +# Thar might be many such weapons. +# +# Format: String (Multivalued) +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.8 NAME 'piracyBestWeapon' DESC 'Pirates best weapon' SUP name X-ORIGIN 'user defined' ) +# piracyQuote +# +# Description: +# The most infamous words a pirate has ever uttered. +# +# Format: String +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.9 NAME 'piracyQuote' DESC 'Pirates most infamous quote' SINGLE-VALUE SUP name X-ORIGIN 'user defined' ) +# piracyDrink +# +# Description: +# The most lovely drink of a pirate. Might that be a rum or grog or there +# might be many such drinks. +# +# Format: String +# +attributeTypes: ( 1.3.6.1.4.1.23611.4.1.2.10 NAME 'piracyDrink' DESC 'Pirates best drink' SUP name X-ORIGIN 'user defined' ) +#---------------------------------------------------------------------- +# Object Classes +#---------------------------------------------------------------------- +# +# piracyPerson +# +# Descripton: +# Piratical person also known as a Pirate. Arr! +# +# Naming Attribute: uid +# +# Important Attributes: +# uid(from inetOrgPerson): User name (login name) of a pirate. Uid is +# considered immutable and must be unique for all pirates. +# Uid is considered to be case insensitive. +# Uid must not contain national characters and white characters +# (e.g. spaces). +# Even though this attribute is defined as multivalued by LDAP, +# it must contain at most a SINGLE VALUE when using this schema. +# cn(from person): Full name of a pirate. Chosen by the pirate. Must be +# printable. This is how the pirate wants to formally be called by his maties. +# Even though this attribute is defined as multivalued by LDAP, it must contain at most a +# SINGLE VALUE when using this schema. +# sn(from person): Last name (surname) of a Pirate. Usually from a family, +# if such a family is worth being mentioned in a piratical person's name. +# Even though this attribute is defined as multivalued by LDAP, it must contain at most a +# SINGLE VALUE when using this schema. +# givenName(from person):First name (given name) of a pirate. Usually a name +# given to a pirate at birth, unless it is changed later. +# Even though this attribute is defined as multivalued by LDAP, it must contain at most a +# SINGLE VALUE when using this schema. +# telephoneNumber: Pirate's devilish parrot number. Should in inter-piratical format +# without the leading evil sign of "+". +# Even though this attribute is defined as multivalued by LDAP, it must contain at most a +# SINGLE VALUE when using this schema. +# piracyShipName: Name of the pirate's vessel. Unless sunk. +# piracyStatus: Current whereabouts of a pirate. See the attribute scroll for +# more details. +# piracyScarNumber: The number of pirate's scars. +# +objectClasses: ( 1.3.6.1.4.1.23611.4.1.1.1 NAME 'piracyPerson' DESC 'Piratical person. A pirate. Mighty pirate.' SUP inetOrgPerson STRUCTURAL MAY ( piracyShipName $ piracyStatus $ piracyScarNumber $ piracyCaptainship $ piracyEnrollmentTimestamp $ piracyTreasureSecret $ piracyNickname $ piracyBestWeapon $ piracyQuote $ piracyDrink ) X-ORIGIN 'user defined' ) +#---------------------------------------------------------------------- +# End of PiracyExample schema +#---------------------------------------------------------------------- diff --git a/deps/ldap/slapdconf/samples/piracy/piracy.schema b/deps/ldap/slapdconf/samples/piracy/piracy.schema new file mode 100644 index 0000000..89f81e1 --- /dev/null +++ b/deps/ldap/slapdconf/samples/piracy/piracy.schema @@ -0,0 +1,253 @@ +# Piracy LDAP Schema Example +# +# Copyright (c) 2011-2015 Radovan Semancik +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +objectIdentifier NLight 1.3.6.1.4.1.23611 + +objectIdentifier Examples NLight:4 +objectIdentifier PiracyExample Examples:1 +objectIdentifier PiracyObjectClass PiracyExample:1 +objectIdentifier PiracyAttributeType PiracyExample:2 + +#---------------------------------------------------------------------- +# Attributes +#---------------------------------------------------------------------- + +# +# All attribute values conform exatly to LDAP schema definition unless +# specified otherwise. For example, all Strings with directory string +# syntax may have national characters (any valid unicode codepoint), may +# contain spaces, etc. - unless that is explicitly constrained by +# comments in this schema definition. +# +# Case sensitivity is determined by EQUALITY matching rule (unless +# explicitly specified otherwise). +# + +# piracyShipName +# +# Description: +# The name of thar vessel +# +# Format: String +# + +attributetype ( PiracyAttributeType:1 + NAME 'piracyShipName' + DESC 'The name of thar vessel' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) + + +# piracyStatus +# +# Description: +# Current whereabouts of a pirate. +# +# Format: Choose one from: +# alive +# dead +# undead +# drunk +# + +attributetype ( PiracyAttributeType:2 + NAME 'piracyStatus' + DESC 'Current whereabouts of a pirate.' + EQUALITY caseExactIA5Match + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + + +# piracyScarNumber +# +# Description: +# The number of pirate's scars. +# +# Format: Integer +# + +attributetype ( PiracyAttributeType:3 + NAME 'piracyScarNumber' + DESC 'The number of pirates scars.' + EQUALITY integerMatch + ORDERING integerOrderingMatch + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) + +# piracyCaptainship +# +# Description: +# Whether the pirate honors himself with a capitain title. +# +# Format: Boolean encoded as string +# "0", "false": not a captain +# "1", "true": is a captain +# + +attributetype ( PiracyAttributeType:4 + NAME 'piracyCaptainship' + DESC 'Whether the pirate honors himself with a capitain title.' + SINGLE-VALUE + SUP name ) + + +# piracyEnrollmentTimestamp +# +# Description: +# The date and time of a pirate stopping to be a landluber and becomming +# a mighty pirate. +# +# Format: generalized time (absolute timestamp) in UTC +# + +attributetype ( PiracyAttributeType:5 + NAME 'piracyEnrollmentTimestamp' + DESC 'Piratical enrollment date' + EQUALITY generalizedTimeMatch + ORDERING generalizedTimeOrderingMatch + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 ) + + +# piracyTreasureSecret +# +# Description: +# A secret code that a pirate keeps for tharself. +# +# Format: OctetString (binary) +# + +attributetype ( PiracyAttributeType:6 + NAME 'piracyTreasureSecret' + DESC 'A secret code that a pirate keeps for tharself.' + EQUALITY octetStringMatch + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) + +# piracyNickname +# +# Description: +# A piratical name that pirate's maties will call the pirate. +# Thar might be many such names. +# +# Format: String (Multivalued) +# + +attributetype ( PiracyAttributeType:7 + NAME 'piracyNickname' + DESC 'Piratical nickname' + SUP name ) + +# piracyBestWeapon +# +# Description: +# A weapon that the pirate likes the most. +# Thar might be many such weapons. +# +# Format: String (Multivalued) +# + +attributetype ( PiracyAttributeType:8 + NAME 'piracyBestWeapon' + DESC 'Pirates best weapon' + SUP name ) + + +# piracyQuote +# +# Description: +# The most infamous words a pirate has ever uttered. +# +# Format: String +# + +attributetype ( PiracyAttributeType:9 + NAME 'piracyQuote' + DESC 'Pirates most infamous quote' + SINGLE-VALUE + SUP name ) + + +# piracyDrink +# +# Description: +# The most lovely drink of a pirate. Might that be a rum or grog or there +# might be many such drinks. +# +# Format: String +# + +attributetype ( PiracyAttributeType:10 + NAME 'piracyDrink' + DESC 'Pirates best drink' + SUP name ) + + +#---------------------------------------------------------------------- +# Object Classes +#---------------------------------------------------------------------- + +# +# piracyPerson +# +# Descripton: +# Piratical person also known as a Pirate. Arr! +# +# Naming Attribute: uid +# +# Important Attributes: +# uid(from inetOrgPerson): User name (login name) of a pirate. Uid is +# considered immutable and must be unique for all pirates. +# Uid is considered to be case insensitive. +# Uid must not contain national characters and white characters +# (e.g. spaces). +# Even though this attribute is defined as multivalued by LDAP, +# it must contain at most a SINGLE VALUE when using this schema. +# cn(from person): Full name of a pirate. Chosen by the pirate. Must be +# printable. This is how the pirate wants to formally be called by his maties. +# Even though this attribute is defined as multivalued by LDAP, it must contain at most a +# SINGLE VALUE when using this schema. +# sn(from person): Last name (surname) of a Pirate. Usually from a family, +# if such a family is worth being mentioned in a piratical person's name. +# Even though this attribute is defined as multivalued by LDAP, it must contain at most a +# SINGLE VALUE when using this schema. +# givenName(from person):First name (given name) of a pirate. Usually a name +# given to a pirate at birth, unless it is changed later. +# Even though this attribute is defined as multivalued by LDAP, it must contain at most a +# SINGLE VALUE when using this schema. +# telephoneNumber: Pirate's devilish parrot number. Should in inter-piratical format +# without the leading evil sign of "+". +# Even though this attribute is defined as multivalued by LDAP, it must contain at most a +# SINGLE VALUE when using this schema. +# piracyShipName: Name of the pirate's vessel. Unless sunk. +# piracyStatus: Current whereabouts of a pirate. See the attribute scroll for +# more details. +# piracyScarNumber: The number of pirate's scars. +# + +objectClass ( PiracyObjectClass:1 + NAME 'piracyPerson' + DESC 'Piratical person. A pirate. Mighty pirate.' + SUP inetOrgPerson + STRUCTURAL + MAY ( piracyShipName $ piracyStatus $ piracyScarNumber $ piracyCaptainship $ + piracyEnrollmentTimestamp $ piracyTreasureSecret $ piracyNickname $ + piracyBestWeapon $ piracyQuote $ piracyDrink ) ) + +#---------------------------------------------------------------------- +# End of PiracyExample schema +#---------------------------------------------------------------------- + diff --git a/deps/ldap/slapdconf/samples/piracy/pirate-jack.ldif b/deps/ldap/slapdconf/samples/piracy/pirate-jack.ldif new file mode 100644 index 0000000..b610076 --- /dev/null +++ b/deps/ldap/slapdconf/samples/piracy/pirate-jack.ldif @@ -0,0 +1,13 @@ +dn: uid=jack,ou=people,dc=example,dc=com +objectclass: piracyPerson +objectclass: inetOrgPerson +objectclass: organizationalPerson +objectclass: person +uid: jack +givenName: Jack +sn: Sparrow +cn: cpt. Jack Sparrow +description: A mighty pirate, the mightiest pirate sailing the seven seas. +mail: jack@blackpearl.com +piracyNickname: Jack +piracyShipName: Black Pearl diff --git a/deps/ldap/slapdconf/schema2ldif b/deps/ldap/slapdconf/schema2ldif new file mode 100755 index 0000000..f746a18 --- /dev/null +++ b/deps/ldap/slapdconf/schema2ldif @@ -0,0 +1,343 @@ +#!/usr/bin/perl +# +# Copyright (c) 2005-2015 Radovan Semancik +# Copyright (c) 2014-2015 Evolveum +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# schema2ldif: Tool for converting OpenLDAP-style schemas to the LDIF format +# ----------- +# +# The LDIF-formated LDAP schemas are difficult to edit and maintain. OpenLDAP +# defined a similar schema format that is more free-form and easier to edit. +# This tool converts the OpenLDAP-formatted schema files to the LDIF. +# +# Original author: Radovan Semancik +# +# Usage +# ----- +# +# schema2ldif < foo.schema > foo.ldif +# +# OpenLDAP schema format +# ---------------------- +# +# objectIdentifier nLight 1.3.6.1.4.1.23611 +# objectIdentifier nLightLdap nLight:1 +# +# attributetype ( oid-my-attr-1 +# NAME 'my-attr-1' +# DESC 'description of my-attr-1 attribute' +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 +# ) +# +# attributetype ( nLightLdap:2 +# NAME 'my-attr-2' +# DESC 'description of my-attr-2 attribute' +# SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 +# ) +# +# objectclass ( oid-my-person +# NAME 'my-person' +# DESC 'description of my-person attribute' +# SUP 'inetOrgPerson' +# MAY ( my-attr-1 ) +# ) +# +# LDIF schema format +# ------------------ +# +# dn: cn=schema +# objectClass: top +# objectClass: ldapSubentry +# objectClass: subschema +# cn: schema +# attributeTypes: ( oid-my-attr-1 NAME 'my-attr-1' DESC 'description of my-attr-1 attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) +# attributeTypes: ( 1.3.6.1.4.1.23611.1.2 NAME 'my-attr-2' DESC 'description of my-attr-2 attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) +# objectClasses: ( oid-my-person NAME 'my-person' DESC 'description of my-person attribute' SUP 'inetOrgPerson' MAY ( my-attr-1 ) X-ORIGIN 'user defined' ) +# + +use strict; + +my $mode = "static"; +my $flavor = "schema"; +my $flavorName = undef; +my $origin = 'user defined'; + +# Turns on debug mode (for development purposes only) +my $debug = 0; + +# Process command-line + +while ($ARGV[0] =~ /^-/) { + my $arg = shift; + if ($arg eq "-h") { + usage(); + exit(); + } elsif ($arg eq "-m") { + $mode = "modify"; + } elsif ($arg eq "-s") { + $flavor = "openldap"; + $flavorName = shift; + } elsif ($arg eq "-o") { + $origin = shift; + } else { + print STDERR "Unknown option $arg\n"; + usage(); + exit(-1); + } +} + + +my $attrNameMap = undef; + +my %ldifAttrNameMap = ( + 'attributetype' => 'attributeTypes', + 'objectclass' => 'objectClasses', +); + +my %openLdapAttrNameMap = ( + 'attributetype' => 'olcAttributeTypes', + 'objectclass' => 'olcObjectClasses', +); + +my @definitionOrder = qw(attributetype objectclass); + +my %oidMapping = (); +my %definitions = (); + +# Print proper LDIF header + +if ($flavor eq "openldap") { + + print "dn: cn=".$flavorName.",cn=schema,cn=config\n"; + + if ($mode eq "modify") { + print "changetype: add\n"; + } + + print "objectClass: olcSchemaConfig\n"; + print "cn: ".$flavorName."\n"; + + $attrNameMap = \%openLdapAttrNameMap; + + +} else { + + # schema (pure) flavor + + if ($mode eq "static") { + # Header for static schema + # used to drop into a file that server picks up on start + print "dn: cn=schema\n"; + print "objectClass: top\n"; + print "objectClass: ldapSubentry\n"; + print "objectClass: subschema\n"; + print "cn: schema\n"; + + } elsif ($mode eq "modify") { + # Header for schema that is being uploaded to running server + print "dn: cn=schema\n"; + print "changetype: modify\n"; + + } else { + die ("Unknown mode $mode\n"); + } + + $attrNameMap = \%ldifAttrNameMap; + +} + +# Reading the input schema file in loop +# processing definitions + +READLOOP: +while (<>) { + + # Comments + if (/^\s*#/) { + # In static mode pass the comments to output file + print if ($mode eq "static"); + # the comments are ignored in other modes as they make + # problems when used with some LDAP clients + next; + } + + chomp; + + if ( /^\s*objectIdentifier\s+(\S+)\s+(\S+)\s*$/) { + # We have got objectIdentifier macro here. + # Parse it and process to the %oidMapping map + + my ($name,$oidExpression) = ($1,$2); + print STDERR "[P] objectIdentifier: $name -> $oidExpression\n" if $debug; + + if (isOid($oidExpression)) { + $oidMapping{$name} = $oidExpression; + print STDERR " adding mapping $name -> $oidExpression\n" if $debug; + } else { + my $oid = expandOidMacro($oidExpression); + if (defined $oid) { + $oidMapping{$name} = $oid; + print STDERR " adding mapping $name -> $oid\n" if $debug; + } else { + print STDERR "Error processing objectIdentifier macro: $_\n"; + } + } + } + + if ( /^\s*(attributetype)\s*\(/i || + /^\s*(objectclass)\s*\(/i ) { + + my $type = lc($1); + my $ldifLine = $attrNameMap->{$type}.": ("; + + $_ = $'; + my $level = 1; + my $foundOrigin = undef; + my $oid = undef; + + while ($level) { + + # raise or lower parenthesis level as necessary + + while ( /\(/g ) { $level++ } + while ( /\)/g ) { $level-- } + + + # OID expression should be the very first token + # therefore process if it was not processed yet + + if (! defined $oid && /^\s*(\S+)\s*/) { + my $oidExpression = $1; + + if (isOid($oidExpression)) { + # OID expression is OID, no transformation needed + $oid = $oidExpression; + + } else { + # Try if OID expression is macro + $oid = expandOidMacro($oidExpression); + + if (! defined $oid) { + # OID expression is not macro, copy it verbatim to output + # This is used if symbolic names are used instead of OIDs + $oid = $oidExpression; + } + } + + $ldifLine .= " $oid"; + $_ = $'; + } + + # find X-ORIGIN clause in the input + + if (/X\-ORIGIN\s+\'([^\'*])\'/) { + $foundOrigin = $1; + } + + # if we are at the end (level 0) and there was no + # X-ORIGIN clause, insert the default one + # just before the last parenthesis + + if ($level == 0 && !defined($foundOrigin)) { + s/\)\s*$/ X-ORIGIN \'$origin\' \)/; + } + + $ldifLine .= $_; + + # is we are at the end, check if the SINGLE-VALUE is in correct place + if ($level == 0) { + if ($ldifLine =~ /SINGLE-VALUE/ && $ldifLine !~ /SINGLE-VALUE\s+X-ORIGIN/) { + warn("The SINGLE-VALUE must be the last clause before X-ORIGIN (oid $oid)\n"); + } + } + + $_ = <>; + last unless defined $_; + + # trim whitespaces + chomp; + s/^\s+/ /; + s/\s+$//; + + } + + print STDERR "[P] $type: $oid\n" if $debug; + + + if ($mode eq "static") { + print $ldifLine . "\n"; + } else { + if (!$definitions{$type}) { + $definitions{$type} = []; + } + + push @{$definitions{$type}},$ldifLine; + } + + last unless defined $_; + } +} + +if ($mode eq "modify") { + my $first = 1; + foreach my $type (@definitionOrder) { + + next unless ($definitions{$type}); + + if ($flavor eq "schema") { + if ($first) { + $first = 0; + } else { + print "-\n"; + } + print "add: ".$attrNameMap->{$type}."\n"; + } + + foreach my $line (@{$definitions{$type}}) { + print $line."\n"; + } + } +} + +sub isOid { + my ($s) = @_; + + return ($s =~ /^[\.\d]+$/); +} + +sub expandOidMacro { + my ($macro) = @_; + + if ($macro =~ /:/) { + my $key = $`; + my $suffix = $'; + if (exists $oidMapping{$key}) { + return $oidMapping{$key}.".".$suffix; + } else { + return undef; + } + } + return $oidMapping{$macro}; +} + +sub usage { + print STDERR "Usage: $0 [-h ] [-m] [-o ] in.schema > out.ldif\n"; + print STDERR "\t-h\t\tThis help message.\n"; + print STDERR "\t-m\t\tGenerate \"modify\" LDIF instead of \"static\"\n"; + print STDERR "\t-s \t\tGenerate OpenLDAP LDIF flavor\n"; + print STDERR "\t-o \tSpecify X-ORIGIN to inject (default: user defined)\n"; + print STDERR "(c) 2000-2015 Radovan Semancik, Evolveum \n"; +} diff --git a/deps/ldap/slapdconf/slapdadm b/deps/ldap/slapdconf/slapdadm new file mode 100755 index 0000000..11f63ff --- /dev/null +++ b/deps/ldap/slapdconf/slapdadm @@ -0,0 +1,550 @@ +#!/usr/bin/perl +# +# Copyright (c) 2014-2015 Evolveum +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Author: Radovan Semancik +# +# Required packages: +# Ubuntu: libnet-ldap-perl libauthen-sasl-perl libuuid-perl + +use strict; +use warnings; + +use Net::LDAP::LDIF; +use Date::Format; +use UUID; +use Getopt::Long qw(:config bundling no_auto_abbrev pass_through); +use Pod::Usage; + +my @userDbTypes = qw(hdb bdb mdb); + +my ($verbose,$optHelp,$optYes,$optRc,$optDoNothing); +my ($configDir,$dbDir,$serviceName,$ldapUser,$ldapGroup); + +my $debug = 0; + +$SIG{__DIE__} = sub { Carp::confess(@_) }; + +my $command; +if ($ARGV[0] !~ /^-/) { + $command = shift; +} + +GetOptions ( + "rc" => \$optRc, + "do-nothing|n" => \$optDoNothing, + "yes|y" => \$optYes, + "verbose|v" => \$verbose, + "debug|d" => \$debug, + "help|h" => \$optHelp, + ) or usage(); +usage() if $optHelp; + +$configDir = "/etc/ldap" unless $configDir; +$dbDir = "/var/lib/ldap" unless $dbDir; +$serviceName = "slapd" unless $serviceName; +$ldapUser = "openldap" unless $ldapUser; +$ldapGroup = "openldap" unless $ldapGroup; + +my $cnConfigDir; + +if (!defined($command)) { + $command = shift; +} + +if (!$command) { usage(); } +if ($command eq "--help") { usage(); } + +if ($command eq "list-suffixes") { listSuffixes() } +elsif ($command eq "delete-suffix") { deleteSuffix() } +elsif ($command eq "create-suffix") { createSuffix() } +elsif ($command eq "delete-schema") { deleteSchema() } +elsif ($command eq "delete-all") { deleteAll() } +elsif ($command eq "help") { usage() } +else { usage() } + +sub listSuffixes { + checkConfigDirs(); + + # TODO + +} + +sub createSuffix { + my $suffix; + if ($ARGV[0] !~ /^-/) { + $suffix = shift @ARGV; + } + + my ($dbDirectory,$rootDn,$rootPassword,$dbType); + GetOptions ( + "dbDir|B=s" => \$dbDirectory, + "rootDn=s" => \$rootDn, + "rootPassword=s" => \$rootPassword, + ) or usage(); + + if (!defined($suffix)) { + $suffix = shift @ARGV; + } + if (!$suffix) { + die("No suffix name specified\n"); + } + $dbDirectory = "/var/lib/ldap/$suffix" unless $dbDirectory; + $rootDn = "cn=admin,".$suffix unless $rootDn; + $rootPassword = "secret" unless $rootPassword; + $dbType = "hdb" unless $dbType; + + checkConfigDirs(); + stopSlapd(); + + my $entry = findConfigObjectBySuffix($suffix); + if ($entry) { + die("Suffix $suffix already exists\n"); + } + + my $index = findLastDbConfigFileIndex(); + my $olcDatabaseName = "{".($index+1)."}$dbType"; + my $olcDatabaseRdn = "olcDatabase=$olcDatabaseName"; + my $dbConfigPath = "$cnConfigDir/$olcDatabaseRdn.ldif"; +# print("Max: $index, file: $dbConfigPath\n"); + my $nowTimestamp = time2str("%Y%m%d%k%M%SZ",time()); + my ($uuid,$uuidStr); + UUID::generate($uuid); + UUID::unparse($uuid,$uuidStr); + + $entry = Net::LDAP::Entry->new($olcDatabaseRdn, + objectClass => [ 'olcDatabaseConfig', 'olcHdbConfig' ], + olcDatabase => $olcDatabaseName, + olcDbDirectory => $dbDirectory, + olcSuffix => $suffix, + olcRootDN => $rootDn, + olcRootPW => $rootPassword, + olcDbCheckpoint => '512 30', + olcDbConfig => [ + '{0}set_cachesize 0 2097152 0', + '{1}set_lk_max_objects 1500', + '{2}set_lk_max_locks 1500', + '{3}set_lk_max_lockers 1500' ], + structuralObjectClass => 'olcHdbConfig', + entryUUID => $uuidStr, + creatorsName => 'gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth', + createTimestamp => $nowTimestamp, + olcAccess => [ + '{0}to attrs=userPassword,shadowLastChange by dn="'.$rootDn.'" write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth write by anonymous auth by self write by * none', + '{1}to dn.base="" by * read', + '{2}to * by dn="'.$rootDn.'" write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth write by anonymous auth by self write by * none', + ], + olcDbIndex => [ 'objectClass eq' ], + ); + + my $entryLdif = $entry->ldif; + $entryLdif =~ s/^\n*//m; + + if ($optDoNothing) { + print("Would create file $dbConfigPath with the following content:\n"); + print($entryLdif."<<\n"); + } else { + open(LDIF,">$dbConfigPath"); + print LDIF $entryLdif; + close(LDIF); + chownName($ldapUser, $ldapGroup, $dbConfigPath); + } + + if (! -e $dbDirectory) { + if ($optDoNothing) { + print("Would create directory $dbDirectory\n"); + } else { + mkdir($dbDirectory); + chownName($ldapUser, $ldapGroup, $dbDirectory); + } + } + + startSlapd(); +} + +sub chownName { + my ($user,$group,@files) = @_; + + my ($ulogin,$upass,$uid,$ugid) = getpwnam($user); + my ($glogin,$gpass,$gid) = getgrnam($group); + + chown($uid,$gid,@files); +} + +sub findLastDbConfigFileIndex { + my (@cnConfigNodes) = listDir($cnConfigDir); + my @dbNodes = grep { /^olcDatabase=/ } @cnConfigNodes; + my $max = 0; + foreach my $dbNode (@dbNodes) { + if (my ($num,$name) = ($dbNode =~ /^olcDatabase=\{(-?\d+)\}([^\s]+)\.ldif$/)) { + if (-f "$cnConfigDir/$dbNode") { + if ($num > $max) { + $max = $num; + } + } else { + die("What the heck is $cnConfigDir/$dbNode?\n"); + } + } + } + return $max; +} + +sub findConfigObjectBySuffix { + my ($suffix) = @_; + + my (@cnConfigNodes) = listDir($cnConfigDir); + my @dbNodes = grep { /^olcDatabase=/ } @cnConfigNodes; + OUTER: foreach my $dbNode (@dbNodes) { + if (my ($num,$name) = ($dbNode =~ /^olcDatabase=\{(-?\d+)\}([^\s]+)\.ldif$/)) { + if (-f "$cnConfigDir/$dbNode") { + my $file="$cnConfigDir/$dbNode"; + print "Processing file $file\n" if $verbose; + my $ldif = Net::LDAP::LDIF->new($file,"r"); + while( not $ldif->eof()) { + my $entry = $ldif->read_entry(); + if ($ldif->error()) { + die("LDIF error in $file:".$ldif->error_lines().": ".$ldif->error()."\n"); + } + my $olcSuffix = $entry->get_value('olcSuffix'); + if (!defined($olcSuffix) || $suffix ne $olcSuffix) { + print("Skipping DB $name because suffix does not match\n") if $verbose; + $ldif->done(); + next OUTER; + } + $ldif->done(); + return $entry; + } + $ldif->done(); + } else { + die("What the heck is $cnConfigDir/$dbNode?\n"); + } + } + } + return undef; +} + +sub deleteSuffix { + my $suffix = shift @ARGV; + if (!$suffix) { + die("No suffix name specified\n"); + } + + deleteDbAndConfigFiles($suffix); +} + +sub deleteAll { + deleteDbAndConfigFiles(); +} + +sub deleteDbAndConfigFiles { + my ($suffix) = @_; + + checkConfigDirs(); + +# if (! -d $dbDir) { +# die("$dbDir is not a directory\n"); +# } + + stopSlapd(); + + #print("C: $cnConfigDir\n"); + my (@cnConfigNodes) = listDir($cnConfigDir); + #print("N: ".join(", ",@cnConfigNodes)."\n"); + my @dbNodes = grep { /^olcDatabase=/ } @cnConfigNodes; + #print("D: ".join(", ",@dbNodes)."\n"); + my @deletedNodeNames; + OUTER: foreach my $dbNode (@dbNodes) { + if (my ($num,$name) = ($dbNode =~ /^olcDatabase=\{(-?\d+)\}([^\s\.]+)(\.ldif)?$/)) { + #print ("$num - $name\n"); + if ($num < 1) { + print("Skipping DB $name because num is $num\n") if $verbose; + next; + } + if (!(grep{$_ eq $name} @userDbTypes)) { + print("Skipping DB $name because it is not know to be user DB type\n") if $verbose; + next; + } + if (-d "$cnConfigDir/$dbNode") { + # skip dirs for now. We will deal with them later + } elsif (-f "$cnConfigDir/$dbNode") { + my $file="$cnConfigDir/$dbNode"; + print "Processing file $file\n" if $verbose; + my $ldif = Net::LDAP::LDIF->new($file,"r"); + while( not $ldif->eof()) { + my $entry = $ldif->read_entry(); + if ($ldif->error()) { + die("LDIF error in $file:".$ldif->error_lines().": ".$ldif->error()."\n"); + } + my $olcSuffix = $entry->get_value('olcSuffix'); + if ($suffix && ($suffix ne $olcSuffix)) { + print("Skipping DB $name because suffix does not match ($olcSuffix vs $suffix)\n") if $verbose; + $ldif->done(); + next OUTER; + } + my $dbdir = $entry->get_value('olcDbDirectory'); + print("Cleaning up DB directory $dbdir\n") if $verbose; + cleanupDbDir($dbdir); + } + $ldif->done(); + deleteFile($file); + push @deletedNodeNames,"olcDatabase={$num}$name"; + } else { + die("What the heck is $cnConfigDir/$dbNode?\n"); + } + } + } + + foreach my $dbNodeName (@deletedNodeNames) { + if (-d "$cnConfigDir/$dbNodeName") { + deleteDir("$cnConfigDir/$dbNodeName"); + } + } + + startSlapd(); + + if ($suffix && !@deletedNodeNames) { + die("Suffix $suffix not found\n"); + } +} + +sub deleteSchema { + my $schemaName = shift @ARGV; + if (!$schemaName) { + die("No schema name specified\n"); + } + + checkConfigDirs(); + + stopSlapd(); + + my $schemaIndex = undef; + ($schemaName, $schemaIndex) = parseIndexedName($schemaName); + + print "schemaName=$schemaName, schemaIndex=$schemaIndex\n" if $debug; + + my $file = undef; + my (@schemaNodes) = listDir($cnConfigDir."/cn=schema"); + foreach my $schemaNode (@schemaNodes) { + if (my ($entryIndex, $entryName) = ($schemaNode =~ /^cn=\{(-?\d+)\}([^\s\.]+)(\.ldif)?$/)) { + if ($entryName eq $schemaName) { + if (defined $schemaIndex && $schemaIndex != $entryIndex) { + die("Schema $schemaName present, but it does have index $entryIndex and not $schemaIndex\n"); + } + $file="$cnConfigDir/cn=schema/$schemaNode"; + last; + } + } + } + + if (!$file) { + die("Schema $schemaName does not exist\n"); + } + + print "Deleting $file\n" if $debug; + deleteFile($file); + + startSlapd(); + +} + + + +### RC + +sub stopSlapd { + if ($optRc) { + system("service $serviceName stop") == 0 or die("Service stop failed: $! ($?)\n"); + } else { + my $out = `service $serviceName status`; + chomp($out); + if ($out !~ /is not running/i) { + die("slapd seems to be running ($out)\n"); + } + } +} + +sub startSlapd { + if ($optRc) { + system("service $serviceName start") == 0 or die("Service start failed: $! ($?)\n"); + } +} + +### Util + +sub parseIndexedName { + my ($val) = @_; + if ($val =~ /^{(\d+)}/) { + return ($', $1); + } else { + return ($val, undef); + } +} + +sub checkConfigDirs { + if (! -d $configDir) { + die("$configDir is not a directory\n"); + } + + my $slapdDDir = "$configDir/slapd.d"; + if (! -d $slapdDDir) { + die("$configDir does not contain slapd.d subdirectory\n"); + } + + $cnConfigDir = "$slapdDDir/cn=config"; + if (! -d $cnConfigDir) { + die("$configDir does not contain slapd.d/cn=config subdirectory\n"); + } +} + +sub deleteDir { + my ($dirpath) = @_; + my @nodes = listDir($dirpath); + foreach my $node (@nodes) { + my $nodepath = "$dirpath/$node"; + if (-f $nodepath) { + deleteFile($nodepath); + } else { + die("Unexpected thing $nodepath, aborting\n"); + } + } + if ($optDoNothing) { + print "Would delete directory $dirpath\n"; + } else { + print "Deleting directory $dirpath\n" if $verbose; + rmdir($dirpath) or die("Error deleting directory $dirpath: $!\n"); + } +} + +sub cleanupDbDir { + my ($dirpath) = @_; + + my @nodes = listDir($dirpath); + foreach my $node (@nodes) { + my $nodepath = "$dirpath/$node"; + if (-f $nodepath) { + deleteFile($nodepath); + } else { + die("Unexpected thing $nodepath, aborting\n"); + } + } + # do NOT delete the directory. we need it. +} + +sub deleteFile { + my ($path) = @_; + if ($optDoNothing) { + print "Would delete file $path\n"; + } else { + print "Deleting file $path\n" if $verbose; + unlink($path) or die("Error deleting file $path: $!\n"); + } +} + +sub listDir { + my ($dirpath) = @_; + + opendir(my $dh, $dirpath) || die "can't opendir $dirpath: $!"; + my @nodes = grep { /^[^\.]/ && "$dirpath/$_" } readdir($dh); + closedir $dh; + + return @nodes; +} + + +### USAGE and DOCUMENTATION + +sub usage { + pod2usage(-verbose => 2); + exit(1); +} + +__END__ + +=head1 NAME + +slapdadm - a command-line tool to configure stopped OpenLDAP instance. + +=head1 SYNOPSIS + +slapdadm [global options] command [command options] + +=head1 OPTIONS + +=head2 COMMANDS + +=over 8 + +=item B + +List directory suffixes configured on the server. + +=item B I + +Creates new directory suffix with an associated database. +It will create empty database without any entry - even without a root entry. This needs to be populated. +But it creates a default configuration for the suffix including root user and default ACLs. + +=item B I + +Deletes an existing directory suffix together with an associated database and the data. + +=item B + +Deletes all suffixes and databases. This comes handy if your OpenLDAP comes pre-configured from your +distribution and you want it to be configured differently. + +=item B + +Displays command usage summary. + +=back + +=head2 GLOBAL OPTIONS + +=over 8 + +=item [ B<-v> | B<--verbose> ] + +Increases verbosity. + +=item B<--help> + +Displays help message. + +=back + +=head1 DESCRIPTION + +This command-line tool is used to configure a stopped OpenLDAP instance. The configuration +is done by direct manipulation of files in C directory and the database +files. + +=head1 EXAMPLES + + slapdadm delete-suffix dc=example,dc=com + +=head1 NOTES + +This is still work in progress. Please feel free to contribute. + +=head1 AUTHOR + +Radovan Semancik + +=head1 SEE ALSO + +C + +=cut diff --git a/deps/ldap/slapdconf/slapdconf b/deps/ldap/slapdconf/slapdconf new file mode 100755 index 0000000..635ee0d --- /dev/null +++ b/deps/ldap/slapdconf/slapdconf @@ -0,0 +1,1929 @@ +#!/usr/bin/perl +# +# Copyright (c) 2014-2016 Evolveum +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Author: Radovan Semancik +# +# Required packages: +# Ubuntu: libnet-ldap-perl libauthen-sasl-perl perl-doc + +use strict; +use warnings; + +use Net::LDAP; +use Net::LDAP::LDIF; +use Authen::SASL; +use Digest::SHA qw(sha1); +use MIME::Base64; +use Getopt::Long qw(:config bundling no_auto_abbrev pass_through); +use Pod::Usage; +use File::Basename; +use File::Temp; +use IPC::Open3; +use Data::Dumper; + +my ($verbose,$optHelp); +my $hostname; +my $port; +my $uri; +my ($bindDn,$bindPassword,$bindSaslMechanism); +my ($filename); + +my $debug = 0; + +my $defaultIndexes = [ 'objectClass eq', 'uid eq,sub', 'cn eq,sub', 'sn eq,sub', 'givenName eq,sub', 'mail eq,sub', + 'member eq', ]; +# my $defaultTLSCipherSuite = "TLSv1+RSA:!EXPORT:!NULL"; # OpenSSL +my $defaultTLSCipherSuite = "NORMAL"; # GnuTLS +my %defaultOlcSuffix = ( + 'olcAccess' => [ + 'to attrs=userPassword,shadowLastChange '. + 'by dn="%%%ROOT_DN%%%" write '. + 'by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth write '. + 'by anonymous auth '. + 'by self write '. + 'by * none', + 'to dn.base="" by * read', + 'to * '. + 'by dn="%%%ROOT_DN%%%" write '. + 'by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth write '. + 'by * read', + ], + ); +my $defaultReplicationManagerNamingAttribute = "cn"; +my $defaultReplicationManagerName="replication manager"; +my $defaultReplicationManagerPassword="rsecret"; +my @replicationProviderIndexes = ('entryUUID eq', 'entryCSN eq'); +my @replicationConsumerIndexes = ('entryUUID eq', 'entryCSN eq'); +my %defaultSyncprovOlcConfig = ( + 'olcSpCheckpoint' => '100 10', + 'olcSpSessionlog' => '100', +); + +my $databases = { + hdb => { + objectClass => "olcHdbConfig", + initialConfig => { + 'olcDbConfig' => [ + "set_cachesize 0 2097152 0", + "set_lk_max_objects 1500", + "set_lk_max_locks 1500", + "set_lk_max_lockers 1500", + ], + 'olcDbIndex' => $defaultIndexes, + 'olcDbCheckpoint' => '512 30', + }, + }, + mdb => { + objectClass => "olcMdbConfig", + initialConfig => { + 'olcDbIndex' => $defaultIndexes, + }, + }, +}; + +my @olcServerProps = qw(olcIdleTimeout olcLogLevel olcReferral olcTLSCACertificateFile olcTLSCertificateFile olcTLSCertificateKeyFile olcTLSCipherSuite); +my @olcSuffixProps = qw(olcDatabase olcDbDirectory olcRootDN olcRootPW olcAccess olcLimits olcDb.*); +my @syncreplConfOrder = qw(rid provider type searchbase bindmethod binddn credentials); +my @saltChars = ('.','/',0..9,'A'..'Z','a'..'z'); + +my %overlayObjectClasses = ( + sssvlv => 'olcSssVlvConfig', + ppolicy => 'olcPPolicyConfig', + memberof => 'olcMemberOf', +); +$SIG{__DIE__} = sub { Carp::confess(@_) }; + +my $command; +if (defined $ARGV[0] && $ARGV[0] !~ /^-/) { + $command = shift; +} + +GetOptions ( + "hostname|h=s" => \$hostname, + "port|p=i" => \$port, + "uri|H=s" => \$uri, + "bindDn|D=s" => \$bindDn, + "bindPassword|w=s" => \$bindPassword, + "saslMechanism|Y=s" => \$bindSaslMechanism, + "file|f=s" => \$filename, + "verbose|v" => \$verbose, + "debug|d" => \$debug, + "help" => \$optHelp, + ) or usage(); +usage() if $optHelp; + +if (!defined($command)) { + $command = shift; +} + +if (!$command) { usage(); } +if ($command eq "--help") { usage(); } + + +if (!$hostname && !$port && !$uri) { + $uri = "ldapi:///"; +} elsif ($hostname && !$port) { + $port = 389; +} elsif (!$hostname && $port) { + $hostname = "localhost"; +} + +if (!$bindDn && !$bindPassword && !$bindSaslMechanism) { + $bindSaslMechanism = "EXTERNAL"; +} + +print("DEBUG: $command: hostname: $hostname, port: $port\n") if $debug; + +if ($command eq "root-dse") { rootDse() } +elsif ($command eq "test") { testConnection() } +elsif ($command eq "get-server-prop") { getServerProp() } +elsif ($command eq "set-server-prop") { setServerProp() } +elsif ($command eq "get-log-level") { getLogLevel() } +elsif ($command eq "set-log-level") { setLogLevel() } +elsif ($command eq "dump-configuration") { dumpConfiguration() } +elsif ($command eq "list-databases") { listDatabases() } +elsif ($command eq "list-suffixes") { listSuffixes() } +elsif ($command eq "create-suffix") { createSuffix() } +elsif ($command eq "delete-suffix") { deleteSuffix() } +elsif ($command eq "get-suffix-prop") { getSuffixProp() } +elsif ($command eq "set-suffix-prop") { setSuffixProp() } +elsif ($command eq "get-suffix-acis") { getSuffixAcis() } +elsif ($command eq "set-suffix-acis") { setSuffixAcis() } +elsif ($command eq "edit-suffix-acis") { editSuffixAcis() } +elsif ($command eq "set-tls") { setTls() } +elsif ($command eq "list-schemas") { listSchemas() } +elsif ($command eq "add-schema") { addSchema() } +elsif ($command eq "delete-schema") { deleteSchema() } +elsif ($command eq "list-modules") { listModules() } +elsif ($command eq "add-module") { addModule() } +elsif ($command eq "delete-module") { deleteModule() } +elsif ($command eq "list-suffix-overlays") { listSuffixOverlays() } +elsif ($command eq "add-overlay") { addOverlay() } +elsif ($command eq "get-overlay-prop") { getOverlayProp() } +elsif ($command eq "set-overlay-prop") { setOverlayProp() } +elsif ($command eq "enable-repl-provider") { enableReplProvider() } +elsif ($command eq "disable-repl-provider") { disableReplProvider() } +elsif ($command eq "get-repl-provider") { getReplProvider() } +elsif ($command eq "enable-repl-consumer") { enableReplConsumer() } +elsif ($command eq "disable-repl-consumer") { disableReplConsumer() } +elsif ($command eq "get-repl-consumer") { getReplConsumer() } +elsif ($command eq "help") { usage() } +else { usage() } + +########## PROPERTY GETTERS AND SETTERS + +sub getServerProp { + my $conn = ldapConnectBind(); + + my ($entry) = getConfigEntriesByDn($conn,"cn=config","base"); + $entry->dump if $verbose; + foreach my $prop (@olcServerProps) { + displayProp($entry,$prop); + } + + ldapDisconnect($conn); +} + +sub setServerProp { + my @propvals = @ARGV; + my $conn = ldapConnectBind(); + + my %replace = (); + my %add = (); + parsePropVals(\@propvals, \%replace, \%add, \@olcServerProps); + + ldapModify($conn,"cn=config", + replace => \%replace, + add => \%add); + + ldapDisconnect($conn); +} + +sub parsePropVals { + my ($propvals, $replace, $add, $allowedValues) = @_; + + foreach my $propval (@$propvals) { + my ($prop,$val) = ($propval =~ /^\s*(\+?[^:]+)\s*:\s*(.*)\s*$/); + if (!$prop) { die("No property name specified\n"); } +# print "$prop -> $val\n"; + my ($propName,$hash); + if ($prop =~ /^\+/) { + $propName = substr($prop,1); + $hash = $add; + } else { + $propName = $prop; + $hash = $replace; + } + if ($propName !~ /^olc/) { + $propName = olcizeName($propName); + } + if ($propName eq 'olcRootPW') { + $val = hashPassword($val); + } + collectPropToHash($hash,$propName,$val,$allowedValues); + } +# print Dumper(\%add); + +} + +sub olcizeName { + my ($origName) = @_; + return "olc" . join('', map {ucfirst($_)} split('-',$origName)); +} + +sub collectPropToHash { + my ($mods,$prop,$val,$allowedValues) = @_; + if ($allowedValues) { + if (!grep {$prop =~ /^$_$/} @$allowedValues) { die("Unknown property $prop\n"); } + } + if (ref $mods->{$prop}) { + push @{$mods->{$prop}},$val; + } elsif ($mods->{$prop}) { + $mods->{$prop} = [ $mods->{$prop}, $val ]; + } else { + $mods->{$prop} = $val; + } +} + +sub displayProp { + my ($entry,$propName) = @_; + + my @values = $entry->get_value($propName); + if (@values) { + if (scalar(@values) == 1) { + print "$propName : @values\n"; + } else { + print "$propName :\n ".join("\n ",@values)."\n"; + } + } +} + +sub getSuffixProp { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + + my $entry = getConfigObjectBySuffix($conn,$suffix,1); + $entry->dump if $verbose; + foreach my $prop ($entry->attributes) { + if (grep {$prop =~ /^$_$/} @olcSuffixProps) { + displayProp($entry,$prop); + } + } + + ldapDisconnect($conn); +} + +sub setSuffixProp { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + my @propvals = @ARGV; + + my $entry = getConfigObjectBySuffix($conn,$suffix,1); + + my %replace = (); + my %add = (); + parsePropVals(\@propvals, \%replace, \%add, \@olcSuffixProps); + + ldapModify($conn,$entry->dn, + replace => \%replace, + add => \%add); + + ldapDisconnect($conn); +} + +sub getSuffixAcis { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + + print join("\n", getSuffixAcisToList($conn, $suffix)); + + ldapDisconnect($conn); +} + +sub getSuffixAcisToList { + my ($conn, $suffix) = @_; + + my $entry = getConfigObjectBySuffix($conn,$suffix,1); + $entry->dump if $verbose; + my @acis = $entry->get_value('olcAccess'); + @acis = sort { getOrdinal($a) <=> getOrdinal($b) } @acis; + map { s/^{\d+}// } @acis; + return @acis; +} + +sub getOrdinal { + if ($_[0] =~ /^{(\d+)}/) { + return $1; + } else { + return 0; + } +} + +sub setSuffixAcis { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + my @propvals = @ARGV; + + my @acis; + while (<>) { + chomp; + push @acis,$_; + } + + setSuffixAcisFromList($conn, $suffix, @acis); + + ldapDisconnect($conn); +} + +sub setSuffixAcisFromList { + my ($conn, $suffix, @acis) = @_; + + my $entry = getConfigObjectBySuffix($conn,$suffix,1); + ldapModify($conn,$entry->dn, + replace => { + olcAccess => \@acis + }, + ); + +} + +sub editSuffixAcis { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + + my @acis = getSuffixAcisToList($conn, $suffix); + my @newAcis = editLines(@acis); + + if (@newAcis) { + + @newAcis = grep { $_ !~ /^\s*$/ } @newAcis; + + if ($verbose) { + print "Setting ACIs:\n"; + print join("\n", @newAcis); + } + + setSuffixAcisFromList($conn, $suffix, @newAcis); + + } else { + print "The editor output was empty. Not changing any ACIs\n"; + } + + ldapDisconnect($conn); +} + + +sub getSuffixArg { + my ($conn) = @_; + + my $suffix = shift @ARGV; + if (!$suffix) { + my @suffixes = getSuffixDns($conn); + if (!@suffixes) { + die("No suffixes configures\n"); + } + if (scalar(@suffixes) > 1) { + die("More than one suffix configured. Please specify suffix name.\nAvailable Suffixes:\n".join("\n",@suffixes)); + } + $suffix = shift @suffixes; + } + return $suffix; +} + +sub listSuffixOverlays { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + my $sentry = getConfigObjectBySuffix($conn,$suffix,1); + + my (@entries) = getConfigEntriesByDn($conn,$sentry->dn,"sub","(objectclass=olcOverlayConfig)"); + + foreach my $entry (@entries) { + my $olcOverlay = $entry->get_value('olcOverlay'); + my ($objectClass) = grep { $_ ne "olcOverlayConfig" } $entry->get_value('objectClass'); + print "$olcOverlay ($objectClass)\n"; + } + + ldapDisconnect($conn); +} + +sub getOverlayProp { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + my $overlayName = shift @ARGV; + if (!$overlayName) { + die("No overlay name specified\n"); + } + my $sentry = getConfigObjectBySuffix($conn,$suffix,1); + my $oentry = getOverlayEntry($conn,$overlayName,$suffix,$sentry,1); + + $oentry->dump if $verbose; + # Guesswork. TODO: work with schema here + + foreach my $attr ($oentry->attributes) { + if ($attr !~ /^olc/) { next; } + if ($attr eq "olcOverlay") { next; } + displayProp($oentry,$attr); + } + + ldapDisconnect($conn); +} + +sub setOverlayProp { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + my $overlayName = shift @ARGV; + if (!$overlayName) { + die("No overlay name specified\n"); + } + my @propvals = @ARGV; + + my $sentry = getConfigObjectBySuffix($conn,$suffix,1); + my $oentry = getOverlayEntry($conn,$overlayName,$suffix,$sentry,1); + + my %replace = (); + my %add = (); + parsePropVals(\@propvals, \%replace, \%add); + + ldapModify($conn,$oentry->dn, + replace => \%replace, + add => \%add); + + ldapDisconnect($conn); +} + +sub addOverlay { + my $conn = ldapConnectBind(); + my $suffix = getSuffixArg($conn); + my $overlayName = shift @ARGV; + if (!$overlayName) { + die("No overlay name specified\n"); + } + my $overlayClass = shift @ARGV; + if (!$overlayClass) { + $overlayClass = $overlayObjectClasses{$overlayName}; + } + if (!$overlayClass) { + die("No overlay objectClass specified\n"); + } + my @propvals = @ARGV; + + my $sentry = getConfigObjectBySuffix($conn,$suffix,1); + my $oentry = getOverlayEntry($conn,$overlayName,$suffix,$sentry,0); + if ($oentry) { + die("Overlay $overlayName already exists in suffix $suffix\n"); + } + + my %replace = (); + my %add = (); + parsePropVals(\@propvals, \%replace, \%add); + + ldapAdd($conn, "olcOverlay=$overlayName,".$sentry->dn, + 'objectClass' => [ 'olcOverlayConfig', $overlayClass ], + 'olcOverlay' => $overlayName, + %replace, + %add); + + ldapDisconnect($conn); +} + + +######### SUFFIX CREATE AND DELETE + +sub createSuffix { + + my $suffix; + if ($ARGV[0] !~ /^-/) { + $suffix = shift @ARGV; + } + + my ($dbDirectory,$dbType,$rootDn,$rootPassword); + GetOptions ( + "dbDir|B=s" => \$dbDirectory, + "dbType=s" => \$dbType, + "rootDn=s" => \$rootDn, + "rootPassword=s" => \$rootPassword, + ) or usage(); + + if (!defined($suffix)) { + $suffix = shift @ARGV; + } + if (!$suffix) { + die("No suffix name specified\n"); + } + $dbDirectory = "/var/lib/ldap" unless $dbDirectory; + $rootDn = "cn=admin,".$suffix unless $rootDn; + $rootPassword = "secret" unless $rootPassword; + $dbType = "mdb" unless $dbType; + + my $dbconf = $databases->{$dbType}; + if (!$dbconf) { + die("Unknown database type $dbType\n"); + } + + my $conn = ldapConnectBind(); + + my $entry = getConfigObjectBySuffix($conn,$suffix,0); + if ($entry) { + die("Suffix $suffix already exists\n"); + } + + my $resp = $conn->search( + base => "cn=config", + filter => "(&(objectclass=olcDatabaseConfig)(olcDbDirectory=$dbDirectory))", + scope => "sub", + attrs => ['*','+'], + ); + if ($resp->code) { + die("Error searching configuration object for database $dbDirectory: ".$resp->error." (".$resp->code.")\n"); + } + if ($resp->count > 0) { + die("The database directory $dbDirectory is already used by database ".$resp->entry(0)->get_value('olcDatabase'). + ", suffix ".$resp->entry(0)->get_value('olcSuffix')."\n"); + } + + $entry = Net::LDAP::Entry->new("olcDatabase=$dbType,cn=config", + 'objectClass' => ['olcDatabaseConfig', $dbconf->{objectClass}], + 'olcDatabase' => $dbType, + 'olcSuffix' => $suffix, + 'olcDbDirectory' => $dbDirectory, + 'olcRootDN' => $rootDn, + 'olcRootPW' => hashPassword($rootPassword), + %{$dbconf->{initialConfig}}, + 'olcAccess' => replaceAdmin($rootDn, $defaultOlcSuffix{olcAccess}), + ); + + $entry->dump if $verbose; + + $resp = $conn->add($entry); + if ($resp->code) { + die("Error creating configuration object for suffix $suffix: ".$resp->error." (".$resp->code.")\n"); + } + + ldapDisconnect($conn); +} + +sub deleteSuffix { + my $suffix = shift @ARGV; + if (!$suffix) { + die("No suffix name specified\n"); + } + + my $conn = ldapConnectBind(); + + my $entry = getConfigObjectBySuffix($conn,$suffix,0); + if (!$entry) { + die("Suffix $suffix not found\n"); + } + + ldapDelete($conn,$entry->dn); + + ldapDisconnect($conn); +} + + +sub replaceAdmin { + my ($rootDn, $valuesRef) = @_; + my @res = map {my $x = $_; $x =~ s/%%%ROOT_DN%%%/$rootDn/g; $x} @$valuesRef; + return \@res; +} + +sub listDatabases { + my $conn = ldapConnectBind(); + + my @entries = getConfigEntriesByObjectclass($conn,"cn=config","sub","olcDatabaseConfig"); + print "DATABASE SUFFIX\n"; + print "------------------------------------------------------\n"; + foreach my $entry (@entries) { + my $database = $entry->get_value("olcDatabase"); + my $suffix = $entry->get_value("olcSuffix") || ""; + printf("%-25s %-40s\n",$database,$suffix); + } + + ldapDisconnect($conn); +} + +sub listSuffixes { + my $conn = ldapConnectBind(); + + foreach my $suffix (getSuffixDns($conn)) { + print("$suffix\n"); + } + + ldapDisconnect($conn); +} + +sub getSuffixDns { + my ($conn) = @_; + + my @entries = getConfigEntriesByObjectclass($conn,"cn=config","sub","olcDatabaseConfig"); + my @suffixes; + foreach my $entry (@entries) { + my $suffix = $entry->get_value("olcSuffix"); + if ($suffix) { + push @suffixes,$suffix; + } + } + return @suffixes; +} + + +##### Schema + +sub listSchemas { + my $conn = ldapConnectBind(); + + foreach my $entry (getSchemaEntries($conn)) { + print $entry->get_value("cn"); + if ($verbose) { + my @attrTypes = $entry->get_value("olcAttributeTypes"); + my @objectClasses = $entry->get_value("olcObjectClasses"); + print (" (".scalar(@attrTypes)." attribute types, ".scalar(@objectClasses)." object classes)"); + } + print "\n"; + } + + ldapDisconnect($conn); +} + +sub addSchema { + my $schemaName = shift @ARGV; + my $schemaFilename = $filename; + print "schemaName=$schemaName, schemaFilename=$schemaFilename\n" if $debug; + my $schemaType = "schema"; + if ($schemaFilename) { + my ($baseFileName, $dirs, $suffix) = fileparse($schemaFilename,"ldif","schema"); + print ("schemaFilename=$schemaFilename, baseFileName=$baseFileName, dirs=$dirs, suffix=$suffix\n") if $debug; + $baseFileName = substr($baseFileName,0,-1); + $schemaType = $suffix; + if (!$schemaName) { + $schemaName = $baseFileName; + } + } + if (!$schemaName) { + die("Schema name not provided\n"); + } + + my $schemaIndex = undef; + ($schemaName, $schemaIndex) = parseIndexedName($schemaName); + + print "schemaName=$schemaName, schemaIndex=$schemaIndex, schemaFilename=$schemaFilename, schemaType=$schemaType\n" if $debug; + + my $conn = ldapConnectBind(); + + foreach my $entry (getSchemaEntries($conn)) { + my $entryCn = $entry->get_value("cn"); + my ($entryName, $entryIndex) = parseIndexedName($entryCn); + if ($entryName eq $schemaName) { + ldapDisconnect($conn); + die("Schema $schemaName already present\n"); + } + if ($schemaIndex && $schemaIndex eq $entryIndex) { + die("Index $schemaIndex already present (schema $entryName)\n"); + } + } + + my $entry; + if ($schemaType eq "schema") { + # need to convert to LDIF + $entry = schema2ldif($schemaName, $schemaFilename); + } elsif ($schemaType eq "ldif") { + open(LDIF, $schemaFilename) or die("Cannot open $schemaFilename: $!\n"); + $entry = parseLdifEntry(\*LDIF); + } else { + die ("Unknown schema type $schemaType\n"); + } + + print ("Adding entry:\n".$entry->ldif."\n") if $debug; + + my $resp = $conn->add($entry); + if ($resp->code) { + ldapDisconnect($conn); + die("Error adding schema entry: ".$resp->error." (".$resp->code.")\n"); + } + + print ("Added schema entry ".$entry->dn.", response code ".$resp->code."\n") if $debug; + + ldapDisconnect($conn); +} + +sub schema2ldif { + my ($schemaName, $fileName) = @_; + + my ($baseFileName, $path, $suffix) = fileparse($0); + my $schema2ldifCommand = $path . "/schema2ldif -m -s '$schemaName'"; + + print ("schema2ldifCommand=$schema2ldifCommand\n") if $debug; + + my $pid = open3(\*WRITE, \*READ, \*ERR, $schema2ldifCommand); + + if ($fileName) { + open(SCHEMA,$fileName) or die("Cannot open $fileName: $!\n"); + while () { + print WRITE $_; + } + close(SCHEMA); + } else { + while () { + print WRITE $_; + } + } + close(WRITE); + + select(undef,undef,undef,.5); + + my $entry = parseLdifEntry(\*READ); + + while() { + print STDERR; + } + + waitpid($pid, 1); + return $entry; +} + +sub parseLdifEntry { + my ($fh) = @_; + + my $ldif = Net::LDAP::LDIF->new($fh); + my $entry; + while ( not $ldif->eof() ) { + if ( $ldif->error ( ) ) { + die("Error parsing LDIF: ".$ldif->error()."\n".$ldif->error_lines()."\n"); + } else { + $entry = $ldif->read_entry(); + } + } + $ldif->done ( ); + + return $entry; +} + +sub deleteSchema { + my $schemaName = shift @ARGV; + if (!$schemaName) { + die("Schema name not provided\n"); + } + + my $schemaIndex = undef; + ($schemaName, $schemaIndex) = parseIndexedName($schemaName); + + print "schemaName=$schemaName, schemaIndex=$schemaIndex\n" if $debug; + + my $conn = ldapConnectBind(); + + my $schemaEntry = undef; + foreach my $entry (getSchemaEntries($conn)) { + my $entryCn = $entry->get_value("cn"); + my ($entryName, $entryIndex) = parseIndexedName($entryCn); + if ($entryName eq $schemaName) { + if (defined $schemaIndex && $schemaIndex != $entryIndex) { + ldapDisconnect($conn); + die("Schema $schemaName present, but it does have index $entryIndex and not $schemaIndex\n"); + } + $schemaEntry = $entry; + last; + } + } + + if (!$schemaEntry) { + die("Schema $schemaName does not exist\n"); + } + + print ("Deleting entry:\n".$schemaEntry->ldif."\n") if $debug; + + ldapDelete($conn, $schemaEntry->dn); + + ldapDisconnect($conn); +} + + +sub getSchemaEntries { + my ($conn) = @_; + + return getConfigEntriesByObjectclass($conn,"cn=schema,cn=config","one","olcSchemaConfig"); +} + + +##### DSE, EXPORT, MODULES, etc. + +sub listModules { + my $conn = ldapConnectBind(); + + my ($entry) = getConfigEntriesByObjectclass($conn,"cn=config","sub","olcModuleList"); + foreach my $module ($entry->get_value("olcModuleload")) { + print "$module\n"; + } + + ldapDisconnect($conn); +} + +sub addModule { + my $module = shift @ARGV; + if (!$module) { + die("No module name specified\n"); + } + + my $conn = ldapConnectBind(); + + my ($entry) = getConfigEntriesByObjectclass($conn,"cn=config","sub","olcModuleList"); + + if (!$entry) { + die("Cannot find module configuration entry (olcModuleList)"); + } + + if (! grep { $_ =~ /^(\{\d+\})?$module$/ } $entry->get_value("olcModuleload")) { + + ldapModify($conn,$entry->dn, + add => { 'olcModuleload' => [ $module ] }, + ); + + } else { + print "Module $module already active in the server\n"; + } + + ldapDisconnect($conn); +} + +sub deleteModule { + my $module = shift @ARGV; + if (!$module) { + die("No module name specified\n"); + } + + my $conn = ldapConnectBind(); + + my ($entry) = getConfigEntriesByObjectclass($conn,"cn=config","sub","olcModuleList"); + + my @modids = grep { $_ =~ /^(\{\d+\})?$module$/ } $entry->get_value("olcModuleload"); + if (! @modids) { + + print "Module $module not active in the server\n"; + ldapModify($conn,$entry->dn, + add => { 'olcModuleload' => [ $module ] }, + ); + + } else { + ldapModify($conn,$entry->dn, + delete => { 'olcModuleload' => \@modids }, + ); + } + + ldapDisconnect($conn); +} + +sub dumpConfiguration { + my $conn = ldapConnectBind(); + + my $resp = $conn->search( + base => "cn=config", + filter => "(objectclass=*)", + scope => "sub", + attrs => ['*','+'], + ); + if ($resp->code) { + die("Fetch configuratin (cn=config): ERROR: ".$resp->error." (".$resp->code.")\n"); + } + + my $ldif; + if ($filename) { + $ldif = Net::LDAP::LDIF->new($filename, "w"); + } else { + $ldif = Net::LDAP::LDIF->new(\*STDOUT, "w", + wrap => 1); + } + $ldif->write_entry($resp->entries); + $ldif->done; + + ldapDisconnect($conn); +} + +sub rootDse { + my $conn = ldapConnectBind(); + my $arg = shift @ARGV || ''; + + my $resp = $conn->search( + base => "", + filter => "(objectclass=*)", + scope => "base", + attrs => ['*','+'], + ); + if ($resp->code) { + die("Fetch root DSE: ERROR: ".$resp->error." (".$resp->code.")\n"); + } + my $rootDseEntry = $resp->entry(0); + if ($arg eq '--raw') { + $rootDseEntry->dump; + } else { + $rootDseEntry->dump if ($verbose); + my $version = $rootDseEntry->get_value("supportedLDAPVersion"); + print("LDAP version $version\n"); + my @suffixes = $rootDseEntry->get_value("namingContexts"); + print("Suffixes:\n"); + foreach my $suffix (@suffixes) { print (" $suffix\n") }; + } + + ldapDisconnect($conn); +} + +sub testConnection { + + my $conn = ldapConnect(); + if ($uri) { + print "Connect to $uri: OK\n"; + } else { + print "Connect to $hostname:$port: OK\n"; + } + + my ($resp,$bindDesc) = ldapBind($conn,0); + if ($resp->code) { + print "Bind $bindDesc: ERROR: ".$resp->error." (".$resp->code.")\n"; + exit(-1); + } else { + print "Bind $bindDesc: OK\n"; + } + + my $dseResp = testFetchEntry($conn,"","base","root DSE"); + my ($schemaDn) = $dseResp->entry->get_value('subschemaSubentry'); + if (!$schemaDn) { + $schemaDn = "cn=schema"; + } + testFetchEntry($conn,$schemaDn,"base","schema"); + testFetchEntry($conn,"cn=config","sub","configuration entry"); + + # todo + + $resp = $conn->unbind; + if ($resp->code) { + print "Unbind: ERROR: ".$resp->error." (".$resp->code.")\n"; + exit(-1); + } else { + print "Unbind: OK\n"; + } + + $conn->disconnect; +} + +sub testFetchEntry { + my ($conn,$dn,$scope,$entryName) = @_; + my $resp = $conn->search( + base => $dn, + filter => "(objectclass=*)", + scope => $scope, + attrs => ['*','+'], + ); + if ($resp->code) { + print "Fetch $entryName (dn: $dn): ERROR: ".$resp->error." (".$resp->code.")\n"; + } else { + print "Fetch $entryName (dn: $dn): OK"; + if ($scope ne "base") { print " (".$resp->count." entries)"; } + print "\n"; + if ($verbose) { + foreach my $entry ($resp->entries) { $entry->dump; } + } + } + return $resp; +} + +sub getLogLevel { + my $conn = ldapConnectBind(); + + my ($entry) = getConfigEntriesByDn($conn,"cn=config","base"); + my (@loglevels) = $entry->get_value('olcLogLevel'); + print "olcLogLevel : ".join(" ",@loglevels)."\n"; + + ldapDisconnect($conn); +} + +sub setLogLevel { + my (@newLevels) = @ARGV; + my $conn = ldapConnectBind(); + + my ($entry) = getConfigEntriesByDn($conn,"cn=config","base"); +# my $loglevel = $entry->get_value('olcLogLevel'); +# print "olcLogLevel : $loglevel\n"; + + ldapModify($conn,"cn=config", + replace => { 'olcLogLevel' => \@newLevels }, + ); + + ldapDisconnect($conn); +} + +sub setTls { + my ($cacert,$cert,$key,$ciphersuite); + GetOptions ( + "cacert=s" => \$cacert, + "cert=s" => \$cert, + "key=s" => \$key, + "ciphersuite=s" => \$ciphersuite, + ) or usage(); + if (!$cacert) { die("No CA certificate file (cacert) specified\n"); } + if (!$cert) { die("No certificate file (cert) specified\n"); } + if (!$key) { die("No certificate key file (key) specified\n"); } + + my $conn = ldapConnectBind(); + + my $replace = { + 'olcTLSCACertificateFile' => $cacert, + 'olcTLSCertificateFile' => $cert, + 'olcTLSCertificateKeyFile' => $key, + }; + + if ($ciphersuite) { + $replace->{olcTLSCipherSuite} = $ciphersuite; + } else { + my ($entry) = getConfigEntriesByDn($conn,"cn=config","base"); + my ($olcTLSCipherSuite) = $entry->get_value('olcTLSCipherSuite'); + if (!$olcTLSCipherSuite) { + $replace->{olcTLSCipherSuite} = $defaultTLSCipherSuite; + } + } + +# print(Dumper($replace)."\n"); + + ldapModify($conn,"cn=config", + replace => $replace, + ); + + ldapDisconnect($conn); +} + +##### REPLICATION + +sub enableReplProvider { + + my $suffix; + if ($ARGV[0] !~ /^-/) { + $suffix = shift @ARGV; + } + + my ($rpassword,$serverId); + GetOptions ( + "rpassword=s" => \$rpassword, + "server-id|sid=s" => \$serverId, + ) or usage(); + + if (!defined($suffix)) { + $suffix = shift @ARGV; + } + if (!$suffix) { + die("No suffix name specified\n"); + } + + my $conn = ldapConnectBind(); + + my ($centry) = getConfigEntriesByDn($conn,"cn=config","base"); + my $olcServerId = $centry->get_value('olcServerID'); + if (defined $serverId) { + if (!defined($olcServerId)) { + ldapModify($conn,"cn=config", + add => { + olcServerID => $serverId, + }); + } + } elsif (!defined($olcServerId)) { + print("Note: server ID is not set\n"); + } + + my $suffixEntry = getConfigObjectBySuffix($conn,$suffix,0); + if (!$suffixEntry) { + die("Suffix $suffix does not exists\n"); + } + + enableModuleLoad($conn,'syncprov'); + + my $rmDn = setupReplicationManager($conn,$suffix,$rpassword); + setupReplicationProviderACLsAndIndexes($conn,$suffix,$suffixEntry,$rmDn); + setupSyncprovOverlay($conn,$suffix,$suffixEntry); + + ldapDisconnect($conn); +} + + +sub getReplProvider { + my $suffix; + if ($ARGV[0] !~ /^-/) { + $suffix = shift @ARGV; + } + + my $conn = ldapConnectBind(); + + my ($centry) = getConfigEntriesByDn($conn,"cn=config","base"); + my $serverId = $centry->get_value('olcServerID'); + if (defined($serverId)) { + print "Server ID set: $serverId\n"; + } else { + print "Server ID NOT set\n"; + } + + my $mentry = getModuleLoadEntry($conn,'syncprov',0); + if ($mentry) { + print "Module syncProv loaded\n"; + } else { + print "Module syncProv NOT loaded\n"; + } + + if ($suffix) { + print "Replication configuration for $suffix:\n"; + my $rmDn = findReplicationManager($conn,$suffix); + if ($rmDn) { + print " Replication manager: $rmDn.\n"; + } else { + print " No replication manager entry\n"; + $rmDn = "$defaultReplicationManagerNamingAttribute=$defaultReplicationManagerName,$suffix"; + } + + my $sentry = getConfigObjectBySuffix($conn,$suffix,1); + my @acls = $sentry->get_value('olcAccess'); + my (@good,@bad); + foreach my $acl (@acls) { + if ($acl =~ / by dn="$rmDn" read/ || $acl =~ / by \* read/) { + push @good,$acl; + } else { + push @bad,$acl; + } + } + if (!@bad) { + print(" replication ACL entries present\n"); + } elsif (!@good) { + print(" replication ACL entries NOT present\n"); + } else { + print(" replication ACL entries partially present. Wrong entries:\n"); + foreach my $acl (@bad) { + print(" $acl\n"); + } + } + + my @indexes = $sentry->get_value('olcDbIndex'); + my @missingIndexes; + foreach my $rIndex (@replicationProviderIndexes) { + if (!(grep {$_ eq $rIndex} @indexes)) { + push @missingIndexes,$rIndex; + } + } + if (@missingIndexes) { + print(" some replication indexes missing:\n"); + for my $index (@missingIndexes) { + print(" $index\n"); + } + } else { + print(" replication indexes present\n"); + } + + my $oentry = getOverlayEntry($conn,'syncprov',$suffix,$sentry,0); + if ($oentry) { + print(" syncprov overlay configured\n"); + print(" checkpoint: ".$oentry->get_value('olcSpCheckpoint')."\n"); + print(" session log: ".$oentry->get_value('olcSpSessionlog')."\n"); + } else { + print(" syncprov overlay NOT configured\n"); + } + + + } + + ldapDisconnect($conn); +} + +sub findReplicationManager { + my ($conn, $suffix) = @_; + + my $resp = $conn->search( + base => $suffix, + filter => "(&(objectclass=simpleSecurityObject)($defaultReplicationManagerNamingAttribute=$defaultReplicationManagerName))", + scope => "sub", + ); + if ($resp->code) { + die("Error searching for replication manager in $suffix: ".$resp->error." (".$resp->code.")\n"); + } + if ($resp->count == 0) { + return undef; + } else { + return $resp->entry(0)->dn; + } +} + +sub setupReplicationManager { + my ($conn, $suffix, $rpassword) = @_; + + my $rmdn = findReplicationManager($conn,$suffix); + + if ($rmdn) { + return $rmdn; + } else { + # No replication manager. We need to create it. + my $replicationManagerDn = "$defaultReplicationManagerNamingAttribute=$defaultReplicationManagerName,$suffix"; + # WARNING! This is dangerous. Just for testing. ganerate the password later. + my $password = $rpassword || $defaultReplicationManagerPassword; + ldapAdd($conn,$replicationManagerDn, + 'objectClass' => [ 'simpleSecurityObject', 'organizationalRole' ], + $defaultReplicationManagerNamingAttribute => $defaultReplicationManagerName, + 'description' => 'Replication Manager', + 'userPassword' => hashPassword($password), + ); + return $replicationManagerDn; + } +} + +sub setupReplicationProviderACLsAndIndexes { + my ($conn,$suffix,$suffixEntry,$rmDn) = @_; + + my %replace = (); + + my @acls = $suffixEntry->get_value('olcAccess'); + my $changed = aclAddReadEverywhere(\@acls,$rmDn); +# print "Post-processed ACLS ($changed):\n".Dumper(\@acls)."\n"; + if ($changed) { + $replace{olcAccess} = \@acls; + } + + my (@indexes) = $suffixEntry->get_value('olcDbIndex'); + $changed = addToList(\@indexes, @replicationProviderIndexes); + if ($changed) { + $replace{olcDbIndex} = \@indexes; + } + + if (%replace) { + ldapModify($conn,$suffixEntry->dn, + replace => \%replace); + } + +} + +sub aclAddReadEverywhere { + my ($aclsref, $rmDn) = @_; + + my $changed = 0; + foreach my $acl (@$aclsref) { + if ($acl !~ / by dn="$rmDn" read/ && $acl !~ / by \* read/) { + if ($acl =~ s/ by / by dn="$rmDn" read by /) { + $changed = 1; + } + } + } + return $changed; +} + +sub setupSyncprovOverlay { + my ($conn,$suffix,$sentry) = @_; + + my $oentry = getOverlayEntry($conn,'syncprov',$suffix,$sentry,0); + if (!$oentry) { + ldapAdd($conn, "olcOverlay=syncprov,".$sentry->dn, + 'objectClass' => [ 'olcOverlayConfig', 'olcSyncProvConfig' ], + 'olcOverlay' => 'syncprov', + %defaultSyncprovOlcConfig); + } +} + +sub enableReplConsumer { + + my $suffix; + if ($ARGV[0] !~ /^-/) { + $suffix = shift @ARGV; + } + + my ($optReadOnly,$providerUri,$rid,$rmDn,$rmPassword,$replType); + GetOptions ( + "provider-uri|P=s" => \$providerUri, + "rid=s" => \$rid, + "read-only" => \$optReadOnly, + ) or usage(); + + if (!defined($suffix)) { + $suffix = shift @ARGV; + } + if (!$suffix) { + die("No suffix name specified\n"); + } + + my $conn = ldapConnectBind(); + + my $suffixEntry = getConfigObjectBySuffix($conn,$suffix,0); + if (!$suffixEntry) { + die("Suffix $suffix does not exists\n"); + } + + my $olcSyncrepl = $suffixEntry->get_value('olcSyncrepl'); + if ($olcSyncrepl) { + die("Replication consumer already enabled for suffix $suffix\n"); + } + + if (!$providerUri) { + die("Replication provider URI not specified\n"); + } + + if (!$rid) { + die("Replica ID not specified\n"); + } + + setupReplicationConsumerIndexes($conn,$suffix,$suffixEntry); + + if (!$rmDn) { + $rmDn = "$defaultReplicationManagerNamingAttribute=$defaultReplicationManagerName,$suffix"; + } + if (!$rmPassword) { + $rmPassword = $defaultReplicationManagerPassword; + } + if (!$replType) { + $replType = "refreshAndPersist"; + } + + my %syncReplConf = ( + rid => $rid, + provider => dquote($providerUri), + type => $replType, + searchbase => dquote($suffix), + bindmethod => 'simple', + binddn => dquote($rmDn), + credentials => $rmPassword, + schemachecking => "off", + retry => dquote("5 5 300 5"), + timeout => 1, + ); + + my $syncreplConfString = createSyncreplConfString(%syncReplConf); + + print "SYNCREPL: $syncreplConfString\n"; + +# ldapModify($conn,$suffixEntry->dn, +# add => { +# olcSyncrepl => $syncreplConfString, +# }); + + ldapDisconnect($conn); +} + +sub createSyncreplConfString { + my (%conf) = @_; + + my $s = ""; + foreach my $k (@syncreplConfOrder) { + if (exists $conf{$k}) { + if ($s) { $s .= " " } + $s .= $k."=".$conf{$k}; + } + } + + foreach my $k (keys %conf) { + if (!(grep{$_ eq $k} @syncreplConfOrder)) { + if ($s) { $s .= " " } + $s .= $k."=".$conf{$k}; + } + } + + return $s; +} + +sub setupReplicationConsumerIndexes { + my ($conn,$suffix,$suffixEntry,$rmDn) = @_; + + my %replace = (); + + my (@indexes) = $suffixEntry->get_value('olcDbIndex'); + my $changed = addToList(\@indexes, @replicationConsumerIndexes); + if ($changed) { + $replace{olcDbIndex} = \@indexes; + } + + if (%replace) { + ldapModify($conn,$suffixEntry->dn, + replace => \%replace); + } + +sub disableReplConsumer { + # TODO +} + +sub getReplConsumer { + # TODO +} + + +} + + +##### UTIL functions + + +sub getConfigObjectBySuffix { + my ($conn,$suffix,$die) = @_; + + my $resp = $conn->search( + base => "cn=config", + filter => "(&(objectclass=olcDatabaseConfig)(olcSuffix=$suffix))", + scope => "sub", + attrs => ['*','+'], + ); + if ($die && $resp->count == 0) { + die("Suffix $suffix not found\n"); + } + if ($resp->code) { + die("Error fetching configuration object for suffix $suffix: ".$resp->error." (".$resp->code.")\n"); + } + + return $resp->entry(0); +} + +sub getModuleLoadEntry { + my ($conn,$moduleName,$die) = @_; + + my (@entries) = getConfigEntriesByDn($conn,"cn=config","sub","(objectclass=olcModuleList)"); + + foreach my $entry (@entries) { + my (@moduleLoads) = $entry->get_value('olcModuleLoad'); + foreach my $moduleLoad (@moduleLoads) { + if ($moduleLoad =~ /^\{\d+\}$moduleName$/) { + return $entry; + } + } + } + + if ($die) { + die("Module load for module $moduleName not found\n"); + } + + return undef; +} + +sub enableModuleLoad { + my ($conn,$moduleName) = @_; + + my $mentry = getModuleLoadEntry($conn,$moduleName,0); + if (!$mentry) { + ldapModify($conn,'cn=module{0},cn=config', + add => { + olcModuleLoad => $moduleName, + }); + } +} + +sub getOverlayEntry { + my ($conn,$overlayName,$suffix,$sentry,$die) = @_; + + my (@entries) = getConfigEntriesByDn($conn,$sentry->dn,"sub","(objectclass=olcOverlayConfig)"); + + foreach my $entry (@entries) { + my $olcOverlay = $entry->get_value('olcOverlay'); + if ($olcOverlay =~ /^\{\d+\}$overlayName$/) { + return $entry; + } + } + + if ($die) { + die("Entry for overlay $overlayName in suffix $suffix not found\n"); + } + + return undef; + +} + +sub getConfigEntriesByDn { + my ($conn,$dn,$scope,$filter) = @_; + + $filter = "(objectclass=*)" unless $filter; + + my $resp = $conn->search( + base => $dn, + filter => $filter, + scope => $scope, + attrs => ['*','+'], + ); + if ($resp->code) { + die("Fetch configuration ($dn): ERROR: ".$resp->error." (".$resp->code.")\n"); + } + + return $resp->entries; +} + +sub getConfigEntriesByObjectclass { + my ($conn,$dn,$scope,$objectclass) = @_; + + my $resp = $conn->search( + base => $dn, + filter => "(objectclass=$objectclass)", + scope => $scope, + attrs => ['*','+'], + ); + if ($resp->code) { + die("Fetch configuration ($dn, objectclass $objectclass): ERROR: ".$resp->error." (".$resp->code.")\n"); + } + + return $resp->entries; +} + +sub addToList { + my ($listref, @vals) = @_; + + my $changed = 0; + foreach my $val (@vals) { + if (!(grep {$_ eq $val} @$listref)) { + push @$listref,$val; + $changed = 1; + } + } + return $changed; +} + +sub dquote { + return map {'"'.$_.'"'} @_; +} + +sub hashPassword { + my ($clearPassword) = @_; + my $salt = generateSalt(); + my $hash = "{SSHA}".encode_base64(sha1($clearPassword.$salt).$salt, ""); + return $hash; +} + +sub generateSalt { + return join('',map {$saltChars[rand(64)]} (1..4)); +} + +sub parseIndexedName { + my ($val) = @_; + if ($val =~ /^{(\d+)}/) { + return ($', $1); + } else { + return ($val, undef); + } +} + +sub editLines { + my (@lines) = @_; + + my $fh = new File::Temp(); + my $fname = $fh->filename; + print $fh join("\n", @lines); + $fh->close(); + my $editor = $ENV{EDITOR} || 'vi'; + system($editor, $fname); + open $fh, '<', $fname or die "Can't open temp file: $!"; + my @newLines; + while (<$fh>) { + chomp; + push @newLines, $_; + } + $fh->close(); + return @newLines; +} + +####### LDAP functions + +sub ldapConnect { + my $conn; + if ($uri) { + $conn = Net::LDAP->new($uri) or die("Error connecting to $uri: ".$@."\n"); + } else { + $conn = Net::LDAP->new($hostname, + port => $port, + ) or die("Error connecting to $hostname:$port: ".$@."\n"); + } + return $conn; +} + +sub ldapBind { + my ($conn,$die) = @_; + + my $resp; + my $desc; + if ($bindDn) { + $desc = "$bindDn (simple bind)"; + print "Binding to $bindDn with simple bind\n" if $verbose; + $resp = $conn->bind($bindDn, + password => $bindPassword, + ); + } elsif ($bindSaslMechanism) { + $desc = "(SASL $bindSaslMechanism)"; + my $sasl = Authen::SASL->new(mechanism => $bindSaslMechanism); + my $saslArg = $sasl; + if ($bindSaslMechanism eq "EXTERNAL") { + $saslArg = $sasl->client_new('ldap', 'localhost'); + } + print "Binding to $bindDn with SASL mechanism $bindSaslMechanism\n" if $verbose; + $resp = $conn->bind($bindDn, + sasl => $saslArg, + ); + } else { + $desc = "(anonymous bind)"; + print "Binding as anonymous\n" if $verbose; + $resp = $conn->bind(); + } + if ($die && $resp->code) { + die("Error binding as $desc: ".$resp->error." (".$resp->code.")\n"); + } + return ($resp,$desc); +} + +sub ldapConnectBind { + my $conn = ldapConnect(); + ldapBind($conn,1); + return $conn; +} + +sub ldapDisconnect { + my ($conn) = @_; + + my $resp = $conn->unbind; + if ($resp->code) { + die("Unbind: ERROR: ".$resp->error." (".$resp->code.")\n"); + } + + $conn->disconnect; +} + +sub ldapAdd { + my ($conn,$dn,%attrs) = @_; + + my $entry = Net::LDAP::Entry->new($dn, %attrs); + + if ($verbose) { + print "Adding entry:\n"; + $entry->dump; + } + + my $resp = $conn->add($entry); + if ($resp->code) { + die("Error adding $dn: ".$resp->error." (".$resp->code.")\n"); + } +} + +sub ldapModify { + my ($conn,$dn,%args) = @_; + + my $resp = $conn->modify($dn,%args); + if ($resp->code) { + die("Error modyfying $dn: ".$resp->error." (".$resp->code.")\n"); + } +} + +sub ldapDelete { + my ($conn,$dn) = @_; + + my $resp = $conn->delete($dn); + if ($resp->code) { + die("Error deleting $dn: ".$resp->error." (".$resp->code.")\n"); + } +} + +### USAGE and DOCUMENTATION + +sub usage { + pod2usage(-verbose => 2); + exit(1); +} + +sub man { + pod2usage(-verbose => 3); + exit(0); +} + +__END__ + +=head1 NAME + +slapdconf - a command-line tool to configure running OpenLDAP instance. + +=head1 SYNOPSIS + +slapdconf [global options] command [command options] + + +=head1 OPTIONS + +=head2 COMMANDS + +=over 8 + +=item B [ I<--raw> ] + +Show directory root DSE entry (entry with dn=""). + +=item B + +Tests connection to the directory server and configuration availability. + +=item B + +Display server-wide configuration properties. + +=item B [+]I:I + +Set server-wide configuration property. If plus sign is specified before +a property name then the value will be added to existing values. Otherwise +the new value overwrites existing value. + +=item B + +Display current server log level + +=item B I [ I [ I ... ] ] + +Sets new server log level(s). + +=item B + +Dumps a complete server configuration. + + +=item B + +List databases configured on the server. + +=item B + +List directory suffixes configured on the server. + +=item B I [ --dbDir | -B I ] [ --dbType I ] [ --rootDn I ] [ --rootPassword I ] + +Creates new directory suffix with an associated database. +It will create empty database without any entry - even without a root entry. This needs to be populated. +But it creates a default configuration for the suffix including root user and default ACLs. +Default root user: cn=admin,I. Default root password: secret + +=item B I + +Deletes an existing directory suffix together with an associated database and the data. +NOTE: this is currently not supported operation in running OpenLDAP instance. Use the C tool instead. + +=item B I + +Display a suffix configuration properties + +=item B I [+]I:I + +Sets suffix configuration property. +If plus sign is specified before +a property name then the value will be added to existing values. Otherwise +the new value overwrites existing value. + +=item B I + +Display ACIs configured for specified suffix + +=item B I [ I ] + +Set suffix ACIs. The ACIs are read from STDIN or from the specified file. Each ACI should be provided on its own line. +The 'olcAccess' attribute name should NOT be present. The operation replaces all ACIs previously defined for the suffix. +This is the same format as produced by get-suffix-acis operation. + +=item B I + +Opens a text editor filled with the content of suffix ACIs. Lets user edit the ACIs and then replaces them on the server. + +=item B C<-cacert> I C<-cert> I C<-key> I + +Applies configuration for TLS/SSL connection support. + +=item B + +List the LDAP schemas that are applied to the server. + +=item B [ I ] [ -f I ] + +Load specified LDAP schema to the server. Both the OpenLDAP format +(suffix *.schema) and LDIF format (suffix *.ldif) are supported. + +=item B I + +Delete specified LDAP schema from the server. + +=item B + +Lists modules that are enabled on the server. + +=item B I + +Adds specified module to server configuration + +=item B I + +Deletes specified module from server configuration. (May not be supported by the server yet) + +=item B [ I ] + +Lists overlays that are activated for the specified suffix. + +=item B I I I [ I:I ] ... + +Activates specified overlay for the specified suffix. + +=item B I I + +Show overlay configuration parameters. + +=item B I I I:I + +Set overlay configuration parameter. + +=item B I + +Sets up the server and the suffix to enable replication in a provider role. It configures required modules, +sets up replication manager user, modifies the ACLs and so on. + +=item B I + +Un-configures the support for replication provider for a specified suffix. + +=item B I + +Displays the status of a replication provider setup for the specified suffix. + +=item B I + +Sets up the specified suffix as a replication consumer. It enables the overlay and configures +replication from the provider. + +=item B I + +Un-configures the replication consumer setup for specified suffix. + +=item B I + +Displays the status of a replication consumer setup for specified suffix. + +=item B + +Displays command usage summary. + +=back + +=head2 GLOBAL OPTIONS + +=over 8 + +=item [ B<-h> | B<--hostname> ] I + +Specifies hostname of the LDAP server. + +=item [ B<-p> | B<--port> ] I + +Specifies port number of the LDAP server. Defaults to 389. + +=item [ B<-H> | B<--uri> ] I + +Specifies complete URI for LDAP server connection. ldap://, ldaps:// and ldapi:// URIs can be used. +Defaults to C + +=item [ B<-D> | B<--bindDn> ] I + +Specifies DN which will be used for LDAP Bind operation. + +=item [ B<-w> | B<--bindPassword> ] I + +Specifies password which will be used for LDAP Bind operation. + +=item [ B<-Y> | B<--saslMechanism> ] I + +Specifies a SASL mechanism to used for LDAP Bind operation. + +=item [ B<-v> | B<--verbose> ] + +Increases verbosity. + +=item B<--help> + +Displays help message. + +=back + +=head1 DESCRIPTION + +This command-line tool is used to configure a runnint OpenLDAP server instance. +It uses LDAP protocol to change the cn=config subtree of an OpenLDAP server. +The configuration changes are applied without a server restart. + +=head1 EXAMPLES + + slapdconf -h myserver.example.com -D "uid=admin,ou=people,dc=example,dc=com" -w secret get-server-prop + + slapdconf -Y EXTERNAL list-suffixes + + slapdconf -Y EXTERNAL create-suffix dc=example,dc=com --dbDir /var/lib/ldap/dc=example,dc=com --rootPassword supersecret + +=head1 NOTES + +This is still work in progress. Please feel free to contribute. + +=head1 AUTHOR + +Radovan Semancik + +=head1 SEE ALSO + +C + +=cut diff --git a/deps/mysql/Dockerfile b/deps/mysql/Dockerfile new file mode 100644 index 0000000..e197011 --- /dev/null +++ b/deps/mysql/Dockerfile @@ -0,0 +1,40 @@ +FROM ubuntu:trusty + +MAINTAINER "TIER API & EntReg Working Group " + +# Copy in the "sis" data to bootstrap mysql +COPY bootstrap /opt/bootstrap + +#MySql shamelessly stolen from https://github.com/dockerfile/mysql/blob/master/Dockerfile +RUN set -x; \ + apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.6 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && sed -i 's/^\(bind-address\s.*\)/# \1/' /etc/mysql/my.cnf \ + && sed -i 's/^\(log_error\s.*\)/# \1/' /etc/mysql/my.cnf \ + && sed -i 's/\[mysqld\]/\[mysqld\]\ncharacter_set_server = utf8/' /etc/mysql/my.cnf \ + && sed -i 's/\[mysqld\]/\[mysqld\]\ncollation_server = utf8_general_ci/' /etc/mysql/my.cnf \ + && cat /etc/mysql/my.cnf \ + && echo "mysqld_safe &" > /tmp/config \ + && echo "mysqladmin --silent --wait=30 ping || exit 1" >> /tmp/config \ + && echo "mysql -e 'GRANT ALL PRIVILEGES ON *.* TO \"root\"@\"%\" WITH GRANT OPTION;'" >> /tmp/config \ + && echo "mysql -e 'CREATE DATABASE grouper CHARACTER SET utf8 COLLATE utf8_bin;'" >> /tmp/config \ + && bash /tmp/config \ + && rm -f /tmp/config \ + && mysql grouper < /opt/bootstrap/sisData.sql + + + +# Note that Grouper will also put stuff into the container too. It will attempt to initialize the registry on every start +# You may want to do a "docker commit mysql-with-grouper" if you want this container to +# exist in a more persistent post-Grouper state. +# +# You can also volume mount in the mysql directories though you will need to re-run the seed data. + +# Define mountable directories. +VOLUME ["/etc/mysql", "/var/lib/mysql"] + +EXPOSE 3306 + +CMD ["mysqld_safe"] diff --git a/deps/mysql/bootstrap/sisData.sql b/deps/mysql/bootstrap/sisData.sql new file mode 100644 index 0000000..44452bf --- /dev/null +++ b/deps/mysql/bootstrap/sisData.sql @@ -0,0 +1,2540 @@ +CREATE TABLE SIS_COURSES ( + uid varchar(255) NOT NULL, + surname varchar(255) default NULL, + givenName varchar(255) default NULL, + courseId varchar(255) default NULL, + PRIMARY KEY (uid, courseId) +); + +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite','White','Karl','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('whenderson','Henderson','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis','Davis','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison','Morrison','Colin','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson','Anderson','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison','Morrison','Ann','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wprice','Price','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts','Roberts','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson','Johnson','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown','Brown','James','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agasper','Gasper','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott','Scott','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler','Butler','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison','Morrison','Thomas','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown14','Brown','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson','Johnson','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez','Martinez','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis','Lewis','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper','Gasper','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales','Vales','Karoline','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgrady','Grady','Thomas','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison','Morrison','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady','Grady','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson','Thompson','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper','Gasper','Bill','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlopez','Lopez','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite','White','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis27','Davis','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper28','Gasper','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson','Johnson','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('amorrison30','Morrison','Ann','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez','Martinez','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson','Henderson','Ann','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales','Vales','Ann','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles','Gonazles','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe','Doe','Blake','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg','Langenberg','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gvales','Vales','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson','Henderson','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson','Thompson','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales40','Vales','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee','Lee','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee','Lee','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark','Clark','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott','Scott','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler','Butler','Donna','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite','White','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe','Doe','Heather','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg','Langenberg','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson','Thompson','Eric','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbrown50','Brown','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles','Gonazles','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler','Butler','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales','Vales','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis','Lewis','Michael','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales','Vales','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott56','Scott','Jo','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdoe','Doe','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales','Vales','Sarah','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison','Morrison','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez','Lopez','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg61','Langenberg','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady','Grady','Betty','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison','Morrison','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wvales','Vales','William','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez','Martinez','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez','Martinez','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper67','Gasper','Mary','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson','Peterson','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice','Price','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper','Gasper','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark','Clark','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson','Peterson','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wsmith','Smith','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams','Williams','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady76','Grady','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez77','Martinez','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis','Lewis','Donna','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wscott79','Scott','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe','Doe','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gmorrison','Morrison','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson','Henderson','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson','Peterson','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice84','Price','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith','Smith','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams','Williams','Donna','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez','Lopez','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson','Johnson','William','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown','Brown','William','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown','Brown','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts','Roberts','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters','Walters','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee','Lee','Nancy','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgonazles','Gonazles','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson','Anderson','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson96','Anderson','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady97','Grady','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady','Grady','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson','Thompson','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson','Thompson','John','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson','Thompson','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson','Thompson','Kiersten','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson','Thompson','Kiersten','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson','Peterson','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson','Peterson','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmorrison','Morrison','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmorrison','Morrison','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('glee','Lee','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('glee','Lee','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson','Henderson','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson','Henderson','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson','Henderson','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson','Henderson','Lori','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott','Scott','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldavis','Davis','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldavis','Davis','Lori','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldavis','Davis','Lori','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts','Roberts','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts','Roberts','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts','Roberts','James','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts','Roberts','James','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('asmith','Smith','Ann','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown','Brown','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown','Brown','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown','Brown','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite110','White','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite110','White','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite110','White','Kim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite110','White','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts111','Roberts','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts111','Roberts','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite','White','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite','White','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite','White','Mark','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice','Price','Jim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice','Price','Jim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith','Smith','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith','Smith','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith','Smith','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sclark','Clark','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sclark','Clark','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sclark','Clark','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales','Vales','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales','Vales','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales','Vales','Donna','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson117','Johnson','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dsmith','Smith','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite','White','Blake','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite','White','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite','White','Blake','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldoe','Doe','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldoe','Doe','Lori','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg121','Langenberg','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gwilliams','Williams','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gwilliams','Williams','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark123','Clark','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark123','Clark','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark123','Clark','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams','Williams','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egonazles','Gonazles','Eric','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egonazles','Gonazles','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egonazles','Gonazles','Eric','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rprice','Price','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rprice','Price','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rprice','Price','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rprice','Price','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewalters','Walters','Erik','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('clangenberg','Langenberg','Colin','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('clangenberg','Langenberg','Colin','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison129','Morrison','Colin','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler','Butler','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler','Butler','Mary','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler','Butler','Mary','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler','Butler','Mary','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smartinez','Martinez','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smartinez','Martinez','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smartinez','Martinez','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smartinez','Martinez','Sarah','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klewis','Lewis','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klewis','Lewis','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams','Williams','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams','Williams','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dsmith134','Smith','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dsmith134','Smith','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gpeterson','Peterson','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gpeterson','Peterson','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gpeterson','Peterson','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gpeterson','Peterson','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady136','Grady','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady136','Grady','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson137','Thompson','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson137','Thompson','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson137','Thompson','Mark','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts138','Roberts','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts138','Roberts','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts138','Roberts','Mary','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts138','Roberts','Mary','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson','Anderson','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson','Anderson','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson','Anderson','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson','Anderson','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott140','Scott','Jo','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott140','Scott','Jo','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott140','Scott','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott140','Scott','Jo','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis141','Davis','Donna','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis141','Davis','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler','Butler','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler','Butler','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis143','Lewis','Jo','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson144','Anderson','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg','Langenberg','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg','Langenberg','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson146','Thompson','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson146','Thompson','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson146','Thompson','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales147','Vales','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite','White','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite','White','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite','White','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite','White','John','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper','Gasper','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper','Gasper','Thomas','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper','Gasper','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper','Gasper','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson','Johnson','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts151','Roberts','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts151','Roberts','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson152','Thompson','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson152','Thompson','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson152','Thompson','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe','Doe','Michael','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe','Doe','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe','Doe','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgonazles','Gonazles','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgonazles','Gonazles','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgonazles','Gonazles','Bill','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson155','Thompson','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson155','Thompson','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlee','Lee','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts','Roberts','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts','Roberts','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts','Roberts','Bill','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales','Vales','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales','Vales','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales','Vales','John','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams','Williams','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams','Williams','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams','Williams','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams160','Williams','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams160','Williams','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams160','Williams','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper','Gasper','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper','Gasper','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlopez','Lopez','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlopez','Lopez','Robert','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlopez','Lopez','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlopez','Lopez','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgrady','Grady','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lpeterson','Peterson','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lpeterson','Peterson','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lpeterson','Peterson','Lisa','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ljohnson','Johnson','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ljohnson','Johnson','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gscott','Scott','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice','Price','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice','Price','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice','Price','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aanderson','Anderson','Ann','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aanderson','Anderson','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aanderson','Anderson','Ann','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aanderson','Anderson','Ann','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice170','Price','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hscott','Scott','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hthompson','Thompson','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison173','Morrison','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison173','Morrison','Jo','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison173','Morrison','Jo','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice174','Price','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hprice','Price','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler','Butler','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler','Butler','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler','Butler','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler','Butler','Karoline','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson177','Johnson','Blake','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson177','Johnson','Blake','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee','Lee','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee','Lee','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee','Lee','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee','Lee','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwilliams','Williams','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwilliams','Williams','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwilliams','Williams','Robert','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice180','Price','Jo','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice180','Price','Jo','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper','Gasper','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper','Gasper','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper','Gasper','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper','Gasper','Kim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cthompson','Thompson','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cthompson','Thompson','Colin','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson183','Thompson','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson183','Thompson','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson183','Thompson','Eric','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson183','Thompson','Eric','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark','Clark','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark','Clark','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark','Clark','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee','Lee','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee','Lee','Lori','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee','Lee','Lori','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson186','Peterson','Karl','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson186','Peterson','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson186','Peterson','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wlee','Lee','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wlee','Lee','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wlee','Lee','William','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson188','Johnson','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson188','Johnson','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez','Lopez','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez','Lopez','Michael','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez','Lopez','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez','Lopez','Michael','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgrady','Grady','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sgrady','Grady','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbrown','Brown','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbrown','Brown','Paul','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbrown','Brown','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams192','Williams','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams192','Williams','Mary','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams192','Williams','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis193','Lewis','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis193','Lewis','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nbrown','Brown','Nancy','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nbrown','Brown','Nancy','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters','Walters','Jo','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters','Walters','Jo','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe196','Doe','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis197','Lewis','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis197','Lewis','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis197','Lewis','Michael','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis','Lewis','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis','Lewis','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis','Lewis','Bill','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis','Lewis','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwalters','Walters','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwalters','Walters','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwalters','Walters','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwalters','Walters','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llopez','Lopez','Lisa','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llopez','Lopez','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llopez','Lopez','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters201','Walters','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters201','Walters','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters201','Walters','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters201','Walters','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison202','Morrison','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison202','Morrison','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison202','Morrison','Karoline','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison202','Morrison','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady203','Grady','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady203','Grady','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('clewis','Lewis','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite205','White','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite205','White','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite205','White','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dprice','Price','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee207','Lee','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee207','Lee','John','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee207','Lee','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler208','Butler','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis','Davis','Betty','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis','Davis','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis','Davis','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis','Davis','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts210','Roberts','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts210','Roberts','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts210','Roberts','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson211','Johnson','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson211','Johnson','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson211','Johnson','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg','Langenberg','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg','Langenberg','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg','Langenberg','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg','Langenberg','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson','Henderson','Donna','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson','Henderson','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson','Henderson','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson','Henderson','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pmartinez','Martinez','Paul','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pmartinez','Martinez','Paul','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pmartinez','Martinez','Paul','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pmartinez','Martinez','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ganderson','Anderson','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ganderson','Anderson','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ganderson','Anderson','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ganderson','Anderson','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson','Peterson','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson','Peterson','Mary','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson','Peterson','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson','Peterson','Mary','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez217','Lopez','Karoline','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez217','Lopez','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez217','Lopez','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez217','Lopez','Karoline','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper218','Gasper','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper218','Gasper','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper218','Gasper','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper218','Gasper','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lsmith','Smith','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ebutler','Butler','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ebutler','Butler','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales221','Vales','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales221','Vales','Jim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales221','Vales','Jim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales222','Vales','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales222','Vales','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson223','Johnson','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson223','Johnson','Karoline','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kscott','Scott','Kiersten','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams225','Williams','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark226','Clark','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark226','Clark','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite227','White','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson228','Anderson','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson228','Anderson','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson228','Anderson','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady229','Grady','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady229','Grady','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady230','Grady','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady230','Grady','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady230','Grady','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe','Doe','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe','Doe','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe','Doe','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe','Doe','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dmorrison','Morrison','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark','Clark','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plopez','Lopez','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plopez','Lopez','Paul','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plopez','Lopez','Paul','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plopez','Lopez','Paul','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hlewis','Lewis','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dsmith236','Smith','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dsmith236','Smith','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dsmith236','Smith','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dsmith236','Smith','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler237','Butler','Kiersten','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler237','Butler','Kiersten','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler237','Butler','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdavis','Davis','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdavis','Davis','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe','Doe','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe','Doe','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgrady','Grady','Karl','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgrady','Grady','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice241','Price','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('shenderson','Henderson','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('shenderson','Henderson','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('shenderson','Henderson','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison243','Morrison','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmorrison243','Morrison','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles244','Gonazles','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alewis','Lewis','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alewis','Lewis','Ann','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alewis','Lewis','Ann','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alewis','Lewis','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis','Davis','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis','Davis','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('manderson','Anderson','Marie','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('manderson','Anderson','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmorrison','Morrison','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith249','Smith','Marie','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith249','Smith','Marie','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe250','Doe','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe250','Doe','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe250','Doe','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper251','Gasper','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper251','Gasper','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper251','Gasper','James','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott252','Scott','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott252','Scott','Jo','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott252','Scott','Jo','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite253','White','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite253','White','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite253','White','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite253','White','Karoline','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown254','Brown','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown254','Brown','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown254','Brown','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wbrown254','Brown','William','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson255','Peterson','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson255','Peterson','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson255','Peterson','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson255','Peterson','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson256','Thompson','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson256','Thompson','Kiersten','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson256','Thompson','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott257','Scott','Jo','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott257','Scott','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott257','Scott','Jo','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott257','Scott','Jo','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg258','Langenberg','Mary','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson259','Henderson','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson259','Henderson','Karoline','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbutler','Butler','Heather','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbutler','Butler','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler261','Butler','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler261','Butler','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler261','Butler','Marie','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison262','Morrison','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison262','Morrison','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison262','Morrison','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison262','Morrison','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis','Davis','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis','Davis','Robert','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis','Davis','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis','Davis','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler264','Butler','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler264','Butler','Kim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler264','Butler','Kim','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler264','Butler','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite265','White','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite265','White','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite265','White','James','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite265','White','James','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams','Williams','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llangenberg','Langenberg','Lisa','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llangenberg','Langenberg','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llangenberg','Langenberg','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson','Henderson','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson','Henderson','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg269','Langenberg','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg269','Langenberg','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg269','Langenberg','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe270','Doe','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe270','Doe','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown271','Brown','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown271','Brown','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown271','Brown','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown271','Brown','Mark','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales272','Vales','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdavis','Davis','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdavis','Davis','Thomas','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ejohnson','Johnson','Eric','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ejohnson','Johnson','Eric','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson275','Peterson','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson275','Peterson','John','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson275','Peterson','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson275','Peterson','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gsmith','Smith','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gsmith','Smith','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez278','Lopez','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez278','Lopez','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez278','Lopez','Kim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sclark279','Clark','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sclark279','Clark','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sclark279','Clark','Sarah','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('abrown','Brown','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('abrown','Brown','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite281','White','Jim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite281','White','Jim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite281','White','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite281','White','Jim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hgrady','Grady','Heather','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hgrady','Grady','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hgrady','Grady','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite283','White','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite283','White','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bsmith','Smith','Betty','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elopez','Lopez','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elopez','Lopez','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elopez','Lopez','Eric','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pclark','Clark','Paul','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pclark','Clark','Paul','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('glee287','Lee','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('glee287','Lee','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('glee287','Lee','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('glee287','Lee','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite288','White','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite288','White','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite288','White','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite288','White','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis289','Davis','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis289','Davis','Robert','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper290','Gasper','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwhite','White','Nancy','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwhite','White','Nancy','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwhite','White','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwhite','White','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson292','Peterson','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson292','Peterson','Kiersten','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klewis293','Lewis','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales294','Vales','John','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales294','Vales','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales294','Vales','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales294','Vales','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe','Doe','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe','Doe','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe','Doe','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbrown','Brown','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbrown','Brown','Blake','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg297','Langenberg','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg297','Langenberg','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg297','Langenberg','Mark','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg297','Langenberg','Mark','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts298','Roberts','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts298','Roberts','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts298','Roberts','Bill','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts298','Roberts','Bill','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldoe299','Doe','Lori','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper300','Gasper','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper300','Gasper','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper300','Gasper','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts','Roberts','Lori','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts','Roberts','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts','Roberts','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts','Roberts','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite302','White','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite302','White','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite302','White','Kiersten','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite302','White','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams303','Williams','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson304','Peterson','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson304','Peterson','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson304','Peterson','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson304','Peterson','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swalters','Walters','Sarah','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swalters','Walters','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swalters','Walters','Sarah','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swalters','Walters','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis','Davis','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis','Davis','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis','Davis','Eric','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bthompson','Thompson','Blake','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bthompson','Thompson','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bthompson','Thompson','Blake','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bthompson','Thompson','Blake','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slangenberg','Langenberg','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slangenberg','Langenberg','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slangenberg','Langenberg','Sarah','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams309','Williams','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams309','Williams','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cpeterson','Peterson','Colin','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee311','Lee','Mary','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elopez312','Lopez','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elopez312','Lopez','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pmartinez313','Martinez','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pmartinez313','Martinez','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pmartinez313','Martinez','Paul','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams314','Williams','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams314','Williams','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams314','Williams','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson315','Peterson','Kiersten','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson315','Peterson','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson315','Peterson','Kiersten','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson315','Peterson','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales316','Vales','Kiersten','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbutler317','Butler','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbutler317','Butler','Heather','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbutler317','Butler','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbutler317','Butler','Heather','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters318','Walters','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson319','Thompson','Kiersten','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson319','Thompson','Kiersten','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson319','Thompson','Kiersten','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson319','Thompson','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott320','Scott','Mary','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rbutler','Butler','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rbutler','Butler','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rbutler','Butler','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rbutler','Butler','Robert','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark322','Clark','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark322','Clark','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hhenderson','Henderson','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hhenderson','Henderson','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe324','Doe','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe324','Doe','Heather','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe324','Doe','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdoe324','Doe','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe325','Doe','Mark','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe325','Doe','Mark','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez326','Lopez','Kiersten','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez326','Lopez','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez326','Lopez','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis327','Lewis','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis327','Lewis','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis327','Lewis','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wlee328','Lee','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wlee328','Lee','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wlee328','Lee','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mthompson329','Thompson','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbrown','Brown','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbrown','Brown','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbrown','Brown','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbrown','Brown','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez331','Martinez','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rmartinez331','Martinez','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klee','Lee','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mjohnson','Johnson','Marie','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams334','Williams','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams334','Williams','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams334','Williams','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tbrown','Brown','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tbrown','Brown','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tbrown','Brown','Thomas','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tbrown','Brown','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters336','Walters','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters336','Walters','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters336','Walters','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler','Butler','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler','Butler','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler','Butler','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler','Butler','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown','Brown','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown','Brown','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pjohnson','Johnson','Paul','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pjohnson','Johnson','Paul','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice340','Price','John','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice341','Price','Jim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson342','Henderson','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson342','Henderson','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite343','White','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez344','Lopez','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgonazles345','Gonazles','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('apeterson','Peterson','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler347','Butler','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('speterson','Peterson','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson349','Peterson','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson349','Peterson','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson349','Peterson','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson350','Johnson','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson350','Johnson','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gjohnson350','Johnson','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lthompson','Thompson','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lthompson','Thompson','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nclark','Clark','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nclark','Clark','Nancy','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swilliams','Williams','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice354','Price','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice354','Price','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lclark','Clark','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lclark','Clark','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ghenderson','Henderson','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ghenderson','Henderson','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ghenderson','Henderson','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egonazles357','Gonazles','Eric','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egonazles357','Gonazles','Eric','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egonazles357','Gonazles','Eric','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egonazles357','Gonazles','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg358','Langenberg','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg358','Langenberg','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg358','Langenberg','Donna','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cbrown','Brown','Colin','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cbrown','Brown','Colin','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cbrown','Brown','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('twalters','Walters','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('twalters','Walters','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('twalters','Walters','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swhite','White','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swhite','White','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swhite','White','Sarah','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swhite','White','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters','Walters','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters','Walters','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters','Walters','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters','Walters','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eroberts','Roberts','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bvales','Vales','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bvales','Vales','Blake','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe365','Doe','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe365','Doe','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe365','Doe','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe365','Doe','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee366','Lee','Nancy','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee366','Lee','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlee366','Lee','Nancy','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison367','Morrison','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler368','Butler','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler368','Butler','Kiersten','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis369','Davis','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis369','Davis','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis369','Davis','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdavis370','Davis','Kiersten','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llewis','Lewis','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('djohnson','Johnson','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('djohnson','Johnson','Donna','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('djohnson','Johnson','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg373','Langenberg','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg373','Langenberg','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg373','Langenberg','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg373','Langenberg','James','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klangenberg','Langenberg','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson375','Thompson','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson375','Thompson','John','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgonazles','Gonazles','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott377','Scott','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott377','Scott','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott377','Scott','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott377','Scott','Mark','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jsmith378','Smith','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jsmith378','Smith','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts379','Roberts','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mroberts379','Roberts','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kprice','Price','Kiersten','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tclark','Clark','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egasper','Gasper','Erik','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egasper','Gasper','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egasper','Gasper','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egasper','Gasper','Erik','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson383','Johnson','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson383','Johnson','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson383','Johnson','James','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson383','Johnson','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdavis','Davis','Colin','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdavis','Davis','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdavis','Davis','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott','Scott','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott','Scott','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott','Scott','Eric','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott','Scott','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez386','Martinez','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez386','Martinez','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lgrady','Grady','Lori','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez388','Martinez','Jo','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alangenberg','Langenberg','Ann','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alangenberg','Langenberg','Ann','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis390','Lewis','Betty','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pjohnson391','Johnson','Paul','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pjohnson391','Johnson','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pjohnson391','Johnson','Paul','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee392','Lee','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee392','Lee','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee392','Lee','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slewis','Lewis','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slewis','Lewis','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwalters','Walters','Nancy','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwalters','Walters','Nancy','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hscott395','Scott','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hscott395','Scott','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hscott395','Scott','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis396','Davis','Erik','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg397','Langenberg','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg397','Langenberg','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg397','Langenberg','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg398','Langenberg','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg398','Langenberg','Paul','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plangenberg398','Langenberg','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott399','Scott','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott399','Scott','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott399','Scott','Michael','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott399','Scott','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper400','Gasper','Jo','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper400','Gasper','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez401','Martinez','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez401','Martinez','Karoline','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cwalters','Walters','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cgasper','Gasper','Colin','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cgasper','Gasper','Colin','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cgasper','Gasper','Colin','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cgasper','Gasper','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams404','Williams','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams404','Williams','James','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams404','Williams','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams404','Williams','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters405','Walters','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters405','Walters','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters405','Walters','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales406','Vales','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bscott','Scott','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bscott','Scott','Bill','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison408','Morrison','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison408','Morrison','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison408','Morrison','Heather','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison408','Morrison','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eanderson','Anderson','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg410','Langenberg','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith411','Smith','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith411','Smith','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith411','Smith','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wpeterson','Peterson','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wpeterson','Peterson','William','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wpeterson','Peterson','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wpeterson','Peterson','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper413','Gasper','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper413','Gasper','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper413','Gasper','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper413','Gasper','Marie','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bvales414','Vales','Blake','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bvales414','Vales','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bvales414','Vales','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady415','Grady','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady415','Grady','Blake','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady415','Grady','Blake','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady415','Grady','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plee','Lee','Paul','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plee','Lee','Paul','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plee','Lee','Paul','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwilliams','Williams','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwilliams','Williams','Kim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwilliams','Williams','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwilliams','Williams','Kim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams418','Williams','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams418','Williams','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams418','Williams','William','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler419','Butler','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales420','Vales','Heather','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales420','Vales','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hvales420','Vales','Heather','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts421','Roberts','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe422','Doe','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe422','Doe','Betty','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe422','Doe','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark','Clark','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark','Clark','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson','Henderson','Michael','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson','Henderson','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson','Henderson','Michael','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson425','Henderson','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson425','Henderson','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson425','Henderson','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson425','Henderson','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgonazles','Gonazles','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgonazles','Gonazles','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgrady427','Grady','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson428','Johnson','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson428','Johnson','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson428','Johnson','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson428','Johnson','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis429','Lewis','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klangenberg430','Langenberg','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klangenberg430','Langenberg','Kim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klangenberg430','Langenberg','Kim','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klangenberg430','Langenberg','Kim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe431','Doe','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe431','Doe','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott432','Scott','Eric','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott432','Scott','Eric','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott432','Scott','Eric','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters','Walters','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters','Walters','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gsmith434','Smith','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gsmith434','Smith','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gsmith434','Smith','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters','Walters','Karl','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison436','Morrison','Thomas','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison436','Morrison','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison436','Morrison','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler437','Butler','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles438','Gonazles','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters439','Walters','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters439','Walters','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark440','Clark','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nvales','Vales','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nvales','Vales','Nancy','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters442','Walters','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters442','Walters','James','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters442','Walters','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwilliams','Williams','Bill','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady444','Grady','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady444','Grady','Jim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady444','Grady','Jim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott445','Scott','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott445','Scott','Erik','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark446','Clark','Bill','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark446','Clark','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark446','Clark','Bill','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark446','Clark','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez447','Lopez','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez447','Lopez','Kiersten','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez447','Lopez','Kiersten','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez447','Lopez','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slee','Lee','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams449','Williams','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams449','Williams','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams449','Williams','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams449','Williams','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klewis450','Lewis','Kim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elangenberg','Langenberg','Eric','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elangenberg','Langenberg','Eric','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elangenberg','Langenberg','Eric','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elangenberg','Langenberg','Eric','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rvales','Vales','Robert','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rvales','Vales','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rvales','Vales','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rvales','Vales','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper453','Gasper','Jo','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper454','Gasper','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper454','Gasper','Mark','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper454','Gasper','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper454','Gasper','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark455','Clark','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper456','Gasper','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper456','Gasper','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper456','Gasper','Betty','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper456','Gasper','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwilliams457','Williams','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kprice458','Price','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kprice458','Price','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith','Smith','Kiersten','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith','Smith','Kiersten','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith','Smith','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith','Smith','Kiersten','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler460','Butler','Lori','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler460','Butler','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler460','Butler','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis461','Lewis','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis461','Lewis','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis461','Lewis','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis461','Lewis','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison462','Morrison','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison462','Morrison','Jo','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmorrison462','Morrison','Jo','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith463','Smith','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blopez','Lopez','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdavis','Davis','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwilliams466','Williams','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwilliams466','Williams','Betty','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwilliams466','Williams','Betty','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwilliams466','Williams','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis','Davis','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis','Davis','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis','Davis','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis','Davis','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles468','Gonazles','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles468','Gonazles','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles468','Gonazles','Michael','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez469','Lopez','Mary','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez469','Lopez','Mary','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez469','Lopez','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eroberts470','Roberts','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eroberts470','Roberts','Eric','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eroberts470','Roberts','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eroberts470','Roberts','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bsmith471','Smith','Blake','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bsmith471','Smith','Blake','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bsmith471','Smith','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bsmith471','Smith','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwilliams472','Williams','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwilliams472','Williams','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwilliams472','Williams','Robert','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwilliams472','Williams','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdavis','Davis','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdavis','Davis','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egrady','Grady','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson475','Peterson','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson475','Peterson','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson475','Peterson','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams476','Williams','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams476','Williams','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams476','Williams','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams476','Williams','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eroberts477','Roberts','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eroberts477','Roberts','Erik','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pvales','Vales','Paul','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pvales','Vales','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott479','Scott','Jim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis480','Davis','Betty','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady481','Grady','Jim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady481','Grady','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nbrown482','Brown','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nbrown482','Brown','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nbrown482','Brown','Nancy','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nbrown482','Brown','Nancy','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee483','Lee','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blee483','Lee','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark484','Clark','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark484','Clark','Jim','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark484','Clark','Jim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown','Brown','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown','Brown','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pgonazles','Gonazles','Paul','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pgonazles','Gonazles','Paul','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pgonazles','Gonazles','Paul','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite487','White','Mark','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite487','White','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite487','White','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite487','White','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales488','Vales','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales488','Vales','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales488','Vales','Sarah','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('svales488','Vales','Sarah','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egasper489','Gasper','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe490','Doe','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe490','Doe','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmorrison491','Morrison','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmorrison491','Morrison','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales','Vales','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales','Vales','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales','Vales','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdavis493','Davis','Heather','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson494','Thompson','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jthompson494','Thompson','James','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe495','Doe','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwilliams496','Williams','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('egasper497','Gasper','Erik','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pvales498','Vales','Paul','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sscott','Scott','Sarah','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sscott','Scott','Sarah','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez','Martinez','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales501','Vales','Marie','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales501','Vales','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales501','Vales','Marie','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales501','Vales','Marie','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson502','Henderson','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis503','Davis','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis503','Davis','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe504','Doe','Mary','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe504','Doe','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdoe504','Doe','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady505','Grady','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady505','Grady','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady505','Grady','Betty','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez506','Martinez','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez506','Martinez','Michael','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters','Walters','Betty','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters','Walters','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters','Walters','Betty','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters','Walters','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales508','Vales','Ann','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales508','Vales','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales508','Vales','Ann','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales508','Vales','Ann','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg509','Langenberg','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg509','Langenberg','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tlopez','Lopez','Thomas','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tlopez','Lopez','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tlopez','Lopez','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lclark511','Clark','Lisa','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lclark511','Clark','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('panderson','Anderson','Paul','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('panderson','Anderson','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('panderson','Anderson','Paul','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson513','Johnson','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson513','Johnson','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson513','Johnson','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson513','Johnson','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wlopez','Lopez','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez515','Martinez','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez515','Martinez','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wclark','Clark','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wclark','Clark','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wclark','Clark','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wclark','Clark','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams517','Williams','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwilliams','Williams','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwilliams','Williams','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwilliams','Williams','Heather','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llopez519','Lopez','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez520','Lopez','Karoline','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez520','Lopez','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez520','Lopez','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tlee','Lee','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tlee','Lee','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tlee','Lee','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tlee','Lee','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott522','Scott','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott522','Scott','Mary','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson523','Anderson','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson523','Anderson','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgonazles524','Gonazles','Jim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hgasper','Gasper','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hgasper','Gasper','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hgasper','Gasper','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ehenderson','Henderson','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ehenderson','Henderson','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ehenderson','Henderson','Eric','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bscott527','Scott','Bill','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bscott527','Scott','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewhite','White','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewhite','White','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sroberts','Roberts','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbutler','Butler','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis531','Davis','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wjohnson532','Johnson','William','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott533','Scott','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott533','Scott','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott533','Scott','Eric','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('escott533','Scott','Eric','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez534','Martinez','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez534','Martinez','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez534','Martinez','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez534','Martinez','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown535','Brown','Kiersten','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown535','Brown','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg536','Langenberg','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg536','Langenberg','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis537','Davis','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis537','Davis','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis537','Davis','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gdavis537','Davis','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wdoe','Doe','William','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wdoe','Doe','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wdoe','Doe','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson539','Thompson','Kiersten','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson539','Thompson','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldavis540','Davis','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldavis540','Davis','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldavis540','Davis','Lisa','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmartinez','Martinez','Blake','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmartinez','Martinez','Blake','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts542','Roberts','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts542','Roberts','Lisa','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts542','Roberts','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts542','Roberts','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith543','Smith','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith543','Smith','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith543','Smith','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith543','Smith','Karl','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark544','Clark','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark544','Clark','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler545','Butler','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler545','Butler','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler545','Butler','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady546','Grady','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgrady546','Grady','John','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee547','Lee','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee547','Lee','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee547','Lee','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee547','Lee','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('csmith','Smith','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('csmith','Smith','Colin','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('csmith','Smith','Colin','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('csmith','Smith','Colin','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tpeterson','Peterson','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles550','Gonazles','Marie','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles550','Gonazles','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles550','Gonazles','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles550','Gonazles','Marie','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite551','White','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite551','White','Bill','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson552','Henderson','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nhenderson552','Henderson','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis553','Lewis','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis553','Lewis','Bill','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis553','Lewis','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mjohnson554','Johnson','Michael','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mjohnson554','Johnson','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ganderson555','Anderson','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ganderson555','Anderson','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ganderson555','Anderson','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slewis556','Lewis','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slewis556','Lewis','Sarah','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slewis556','Lewis','Sarah','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales557','Vales','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales557','Vales','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales557','Vales','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez558','Lopez','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez558','Lopez','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez558','Lopez','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez558','Lopez','John','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez559','Martinez','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez559','Martinez','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez559','Martinez','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez559','Martinez','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kthompson560','Thompson','Karl','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts561','Roberts','Karoline','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts561','Roberts','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts561','Roberts','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts561','Roberts','Karoline','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown562','Brown','Mary','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blopez563','Lopez','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blopez563','Lopez','Betty','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blopez563','Lopez','Betty','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts564','Roberts','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts564','Roberts','Jo','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts564','Roberts','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts564','Roberts','Jo','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez565','Lopez','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez565','Lopez','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters566','Walters','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters566','Walters','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters566','Walters','Blake','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales567','Vales','Karoline','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez568','Lopez','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez568','Lopez','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez568','Lopez','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez568','Lopez','Michael','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison569','Morrison','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison569','Morrison','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison569','Morrison','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmorrison569','Morrison','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis570','Davis','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis570','Davis','Blake','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdavis570','Davis','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdavis','Davis','Sarah','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdavis','Davis','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdavis','Davis','Sarah','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('banderson572','Anderson','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('banderson572','Anderson','Blake','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('banderson572','Anderson','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wanderson','Anderson','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wanderson','Anderson','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wanderson','Anderson','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wanderson','Anderson','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice574','Price','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice574','Price','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice574','Price','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice574','Price','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler575','Butler','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler575','Butler','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler575','Butler','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler575','Butler','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott576','Scott','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott576','Scott','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott576','Scott','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe577','Doe','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe577','Doe','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdavis578','Davis','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdavis578','Davis','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdavis578','Davis','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdavis578','Davis','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slangenberg579','Langenberg','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slangenberg579','Langenberg','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bvales580','Vales','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lpeterson581','Peterson','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lpeterson581','Peterson','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lpeterson581','Peterson','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmartinez582','Martinez','Blake','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmartinez582','Martinez','Blake','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmartinez582','Martinez','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('asmith583','Smith','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('asmith583','Smith','Ann','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('asmith583','Smith','Ann','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aprice','Price','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aprice','Price','Ann','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ehenderson585','Henderson','Eric','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmorrison586','Morrison','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmorrison586','Morrison','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('chenderson','Henderson','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbrown','Brown','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbrown','Brown','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbrown','Brown','Lori','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbrown','Brown','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('psmith','Smith','Paul','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klee590','Lee','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klee590','Lee','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe591','Doe','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe591','Doe','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe591','Doe','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe591','Doe','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldoe592','Doe','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales593','Vales','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson594','Henderson','Ann','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ahenderson594','Henderson','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aroberts','Roberts','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aroberts','Roberts','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aroberts','Roberts','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dthompson','Thompson','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dthompson','Thompson','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown597','Brown','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown597','Brown','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown597','Brown','Donna','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez598','Martinez','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez598','Martinez','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown599','Brown','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown599','Brown','Karl','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pclark600','Clark','Paul','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pclark600','Clark','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pclark600','Clark','Paul','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice601','Price','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler602','Butler','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson603','Henderson','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson603','Henderson','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kscott604','Scott','Karoline','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kscott604','Scott','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kscott604','Scott','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe605','Doe','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe605','Doe','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('djohnson606','Johnson','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbutler607','Butler','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbutler607','Butler','Paul','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbutler607','Butler','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbutler607','Butler','Paul','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler608','Butler','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler608','Butler','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler608','Butler','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler608','Butler','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith609','Smith','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith609','Smith','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson610','Peterson','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler611','Butler','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler611','Butler','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler611','Butler','Karl','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwhite','White','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwhite','White','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson613','Peterson','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson613','Peterson','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson613','Peterson','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson613','Peterson','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez614','Lopez','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez614','Lopez','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez614','Lopez','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tjohnson','Johnson','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee616','Lee','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee616','Lee','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice617','Price','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice617','Price','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice617','Price','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice617','Price','Jennifer','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ghenderson618','Henderson','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters619','Walters','Robert','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rwalters619','Walters','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmorrison620','Morrison','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmorrison620','Morrison','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson','Anderson','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson','Anderson','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson','Anderson','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson','Anderson','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson622','Anderson','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson622','Anderson','Lori','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson622','Anderson','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson622','Anderson','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pprice','Price','Paul','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pprice','Price','Paul','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nsmith','Smith','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nsmith','Smith','Nancy','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nsmith','Smith','Nancy','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nsmith','Smith','Nancy','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson625','Peterson','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson625','Peterson','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson625','Peterson','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson625','Peterson','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez626','Lopez','Mary','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez626','Lopez','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez626','Lopez','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlopez626','Lopez','Mary','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales627','Vales','Donna','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales627','Vales','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales627','Vales','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales627','Vales','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ethompson628','Thompson','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe629','Doe','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe629','Doe','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe629','Doe','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe629','Doe','Robert','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cjohnson','Johnson','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cjohnson','Johnson','Colin','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cjohnson','Johnson','Colin','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cjohnson','Johnson','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams631','Williams','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams631','Williams','Michael','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams631','Williams','Michael','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams631','Williams','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson632','Peterson','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgonazles633','Gonazles','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgonazles633','Gonazles','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('danderson634','Anderson','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters635','Walters','Kim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters635','Walters','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters635','Walters','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters635','Walters','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('adoe','Doe','Ann','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('adoe','Doe','Ann','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdoe','Doe','Colin','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe638','Doe','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis639','Davis','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis639','Davis','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis639','Davis','Erik','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis639','Davis','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite640','White','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dprice641','Price','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dprice641','Price','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dprice641','Price','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dprice641','Price','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez642','Lopez','Kim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez642','Lopez','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez642','Lopez','Kim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez642','Lopez','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('abrown643','Brown','Ann','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite644','White','Mary','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwhite644','White','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite645','White','Kiersten','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite645','White','Kiersten','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite645','White','Kiersten','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite645','White','Kiersten','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edoe','Doe','Erik','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles647','Gonazles','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles647','Gonazles','Mark','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles647','Gonazles','Mark','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson648','Henderson','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson648','Henderson','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bsmith649','Smith','Bill','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bsmith649','Smith','Bill','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bsmith649','Smith','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmorrison650','Morrison','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmorrison650','Morrison','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmorrison650','Morrison','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llangenberg651','Langenberg','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llangenberg651','Langenberg','Lori','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llangenberg651','Langenberg','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llangenberg651','Langenberg','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters652','Walters','Jim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters652','Walters','Jim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tjohnson653','Johnson','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tjohnson653','Johnson','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tjohnson653','Johnson','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters654','Walters','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters654','Walters','Jo','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bmorrison655','Morrison','Betty','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark656','Clark','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark656','Clark','Michael','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark656','Clark','Michael','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark656','Clark','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams657','Williams','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams657','Williams','Erik','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams657','Williams','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis658','Lewis','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis658','Lewis','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgrady659','Grady','Kiersten','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgrady659','Grady','Kiersten','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wmartinez','Martinez','William','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wmartinez','Martinez','William','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pwilliams','Williams','Paul','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pwilliams','Williams','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson662','Johnson','Kim','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson662','Johnson','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson662','Johnson','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smartinez663','Martinez','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smartinez663','Martinez','Sarah','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smartinez663','Martinez','Sarah','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales664','Vales','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klangenberg665','Langenberg','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith666','Smith','Marie','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales667','Vales','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters668','Walters','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters668','Walters','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters668','Walters','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters668','Walters','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pgonazles669','Gonazles','Paul','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pgonazles669','Gonazles','Paul','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales670','Vales','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales670','Vales','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark671','Clark','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe672','Doe','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe672','Doe','Betty','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bdoe672','Doe','Betty','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown673','Brown','Mark','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown673','Brown','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown673','Brown','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe674','Doe','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe674','Doe','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe674','Doe','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdoe674','Doe','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson675','Thompson','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wthompson675','Thompson','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dmorrison676','Morrison','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edoe677','Doe','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edoe677','Doe','Erik','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edoe677','Doe','Erik','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlangenberg','Langenberg','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlangenberg','Langenberg','Nancy','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson679','Peterson','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hgonazles','Gonazles','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hgonazles','Gonazles','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('droberts','Roberts','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgonazles682','Gonazles','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgonazles682','Gonazles','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmorrison','Morrison','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison684','Morrison','Colin','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison684','Morrison','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cmorrison684','Morrison','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis685','Lewis','Jim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis685','Lewis','Jim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis685','Lewis','Jim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis685','Lewis','Jim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson686','Johnson','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson686','Johnson','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elee','Lee','Erik','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elee','Lee','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elee','Lee','Erik','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elee','Lee','Erik','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe688','Doe','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe688','Doe','Donna','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('droberts689','Roberts','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('droberts689','Roberts','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles690','Gonazles','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgonazles690','Gonazles','Mary','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awilliams','Williams','Ann','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gwalters','Walters','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gwalters','Walters','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gwalters','Walters','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gwalters','Walters','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wgonazles','Gonazles','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis694','Lewis','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis694','Lewis','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales695','Vales','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('avales695','Vales','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mjohnson696','Johnson','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mjohnson696','Johnson','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson','Anderson','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson','Anderson','Kim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson','Anderson','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('troberts','Roberts','Thomas','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('troberts','Roberts','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('troberts','Roberts','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis699','Lewis','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis699','Lewis','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis699','Lewis','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters700','Walters','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown701','Brown','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown701','Brown','Kim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown701','Brown','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewhite702','White','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewhite702','White','Erik','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewhite702','White','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewhite702','White','Erik','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters703','Walters','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters703','Walters','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters703','Walters','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alangenberg704','Langenberg','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbrown705','Brown','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbrown705','Brown','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blangenberg','Langenberg','Blake','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis707','Lewis','Michael','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis707','Lewis','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis707','Lewis','Michael','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith708','Smith','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith708','Smith','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith708','Smith','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith708','Smith','Karl','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('clopez','Lopez','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('clopez','Lopez','Colin','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark710','Clark','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark710','Clark','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark710','Clark','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tprice','Price','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tprice','Price','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tprice','Price','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tprice','Price','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klewis712','Lewis','Karl','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klewis712','Lewis','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler713','Butler','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler713','Butler','Marie','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler713','Butler','Marie','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbutler713','Butler','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmorrison714','Morrison','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmorrison714','Morrison','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmorrison714','Morrison','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gsmith715','Smith','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gsmith715','Smith','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gsmith715','Smith','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('randerson','Anderson','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('randerson','Anderson','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('randerson','Anderson','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klangenberg717','Langenberg','Kiersten','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klangenberg717','Langenberg','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg718','Langenberg','Mary','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plee719','Lee','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plee719','Lee','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark720','Clark','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbrown721','Brown','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbrown721','Brown','Blake','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bvales722','Vales','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('emartinez','Martinez','Erik','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('emartinez','Martinez','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles','Gonazles','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles','Gonazles','Karl','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles','Gonazles','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles','Gonazles','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales725','Vales','Lisa','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales725','Vales','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales725','Vales','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgrady726','Grady','Karl','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgrady726','Grady','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aanderson727','Anderson','Ann','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite728','White','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwilliams729','Williams','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark730','Clark','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark730','Clark','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams731','Williams','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams732','Williams','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis733','Lewis','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis733','Lewis','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ndoe','Doe','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ndoe','Doe','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ndoe','Doe','Nancy','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson735','Johnson','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson735','Johnson','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson735','Johnson','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgonazles736','Gonazles','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lprice','Price','Lisa','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lprice','Price','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lprice','Price','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lprice','Price','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe738','Doe','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe738','Doe','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdoe738','Doe','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown739','Brown','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson740','Anderson','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson740','Anderson','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez741','Martinez','Jo','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez741','Martinez','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('agonazles','Gonazles','Ann','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis743','Davis','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis743','Davis','Erik','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis743','Davis','Erik','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis743','Davis','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson744','Peterson','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson744','Peterson','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson744','Peterson','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson744','Peterson','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice745','Price','Betty','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice745','Price','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice745','Price','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice745','Price','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams746','Williams','Jim','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams746','Williams','Jim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams746','Williams','Jim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams746','Williams','Jim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rroberts','Roberts','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rroberts','Roberts','Robert','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rroberts','Roberts','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rroberts','Roberts','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts748','Roberts','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kroberts748','Roberts','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson749','Anderson','Jim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson749','Anderson','Jim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson749','Anderson','Jim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson749','Anderson','Jim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts750','Roberts','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts750','Roberts','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('broberts750','Roberts','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('elopez751','Lopez','Erik','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('manderson752','Anderson','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('manderson752','Anderson','Michael','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler753','Butler','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler753','Butler','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler753','Butler','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler753','Butler','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gclark','Clark','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gclark','Clark','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gclark','Clark','Greg','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams755','Williams','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams755','Williams','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llopez756','Lopez','Lori','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llopez756','Lopez','Lori','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llopez756','Lopez','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson757','Henderson','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson757','Henderson','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson757','Henderson','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cjohnson758','Johnson','Colin','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cjohnson758','Johnson','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cjohnson758','Johnson','Colin','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper759','Gasper','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper759','Gasper','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis760','Lewis','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis760','Lewis','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis760','Lewis','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis760','Lewis','James','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee761','Lee','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee761','Lee','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('llee761','Lee','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rvales762','Vales','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rvales762','Vales','Robert','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rvales762','Vales','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rvales762','Vales','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper763','Gasper','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper763','Gasper','John','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper763','Gasper','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper763','Gasper','John','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice764','Price','Marie','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice764','Price','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice764','Price','Marie','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('asmith765','Smith','Ann','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('asmith765','Smith','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson766','Anderson','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson766','Anderson','Kiersten','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tbrown767','Brown','Thomas','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tbrown767','Brown','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales768','Vales','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales768','Vales','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales768','Vales','Karoline','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kvales768','Vales','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson769','Henderson','Jo','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson769','Henderson','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson769','Henderson','Jo','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson769','Henderson','Jo','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jjohnson770','Johnson','James','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wroberts','Roberts','William','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wroberts','Roberts','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wroberts','Roberts','William','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wroberts','Roberts','William','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cpeterson772','Peterson','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdoe','Doe','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdoe','Doe','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdoe','Doe','Thomas','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tdoe','Doe','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hroberts','Roberts','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hroberts','Roberts','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice775','Price','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice775','Price','Michael','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice775','Price','Michael','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts776','Roberts','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts776','Roberts','Lori','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts776','Roberts','Lori','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lroberts776','Roberts','Lori','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis777','Davis','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis777','Davis','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles778','Gonazles','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles778','Gonazles','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles778','Gonazles','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles778','Gonazles','Karoline','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales779','Vales','Mary','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales779','Vales','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mvales779','Vales','Mary','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe780','Doe','Jo','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dmartinez','Martinez','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales782','Vales','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tprice783','Price','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tprice783','Price','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tprice783','Price','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tprice783','Price','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dmorrison784','Morrison','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgonazles785','Gonazles','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgonazles785','Gonazles','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgonazles785','Gonazles','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgonazles785','Gonazles','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swalters786','Walters','Sarah','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swalters786','Walters','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('swalters786','Walters','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hpeterson','Peterson','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hpeterson','Peterson','Heather','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hpeterson','Peterson','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee788','Lee','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlopez','Lopez','Nancy','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlopez','Lopez','Nancy','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlopez','Lopez','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlopez','Lopez','Nancy','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite790','White','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite790','White','Kim','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite790','White','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nbutler','Butler','Nancy','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts792','Roberts','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts792','Roberts','Jo','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts792','Roberts','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hclark','Clark','Heather','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hclark','Clark','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hclark','Clark','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nclark794','Clark','Nancy','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nclark794','Clark','Nancy','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson795','Peterson','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson795','Peterson','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson795','Peterson','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown796','Brown','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown796','Brown','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hbrown796','Brown','Heather','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hlewis797','Lewis','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hlewis797','Lewis','Heather','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hlewis797','Lewis','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis798','Lewis','Betty','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis798','Lewis','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis798','Lewis','Betty','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis798','Lewis','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sroberts799','Roberts','Sarah','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sroberts799','Roberts','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sroberts799','Roberts','Sarah','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sroberts799','Roberts','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('clewis800','Lewis','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('clewis800','Lewis','Colin','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('clewis800','Lewis','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark801','Clark','Jim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark801','Clark','Jim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales802','Vales','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales802','Vales','Jim','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis803','Lewis','John','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis803','Lewis','John','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis803','Lewis','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis803','Lewis','John','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper804','Gasper','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper804','Gasper','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis805','Davis','Robert','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis805','Davis','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis805','Davis','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis805','Davis','Robert','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams806','Williams','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams806','Williams','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams806','Williams','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott807','Scott','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott807','Scott','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott807','Scott','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wwilliams808','Williams','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis809','Davis','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis809','Davis','Eric','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('edavis809','Davis','Eric','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice810','Price','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice810','Price','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice810','Price','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bhenderson','Henderson','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bhenderson','Henderson','Betty','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bhenderson','Henderson','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hhenderson812','Henderson','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hhenderson812','Henderson','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hhenderson812','Henderson','Heather','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hhenderson812','Henderson','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kscott813','Scott','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kscott813','Scott','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kscott813','Scott','Karl','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe814','Doe','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe814','Doe','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe814','Doe','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams815','Williams','Erik','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams815','Williams','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jsmith816','Smith','Jo','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jsmith816','Smith','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jsmith816','Smith','Jo','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jsmith816','Smith','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales817','Vales','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales817','Vales','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales817','Vales','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lvales817','Vales','Lisa','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lpeterson818','Peterson','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgasper','Gasper','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dgasper','Gasper','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlangenberg820','Langenberg','Nancy','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlangenberg820','Langenberg','Nancy','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson821','Henderson','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jhenderson821','Henderson','Jo','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis822','Davis','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis822','Davis','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis822','Davis','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper823','Gasper','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper823','Gasper','Karl','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper823','Gasper','Karl','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper823','Gasper','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice824','Price','John','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice824','Price','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice824','Price','John','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jprice824','Price','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('aclark','Clark','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark826','Clark','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark826','Clark','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark826','Clark','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jclark826','Clark','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmartinez','Martinez','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmartinez','Martinez','Lori','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmartinez','Martinez','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lmartinez','Martinez','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson828','Peterson','Jim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson828','Peterson','Jim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson828','Peterson','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson828','Peterson','Jim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe829','Doe','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe829','Doe','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe829','Doe','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdoe829','Doe','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nmorrison','Morrison','Nancy','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ehenderson831','Henderson','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ehenderson831','Henderson','Eric','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ehenderson831','Henderson','Eric','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwhite832','White','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson833','Henderson','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson833','Henderson','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown834','Brown','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown834','Brown','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbrown834','Brown','Donna','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('manderson835','Anderson','Marie','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('manderson835','Anderson','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('manderson835','Anderson','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper836','Gasper','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper836','Gasper','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper836','Gasper','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggasper836','Gasper','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis837','Lewis','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlewis837','Lewis','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark838','Clark','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark838','Clark','Karl','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark838','Clark','Karl','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark838','Clark','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark839','Clark','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark839','Clark','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark839','Clark','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis840','Lewis','Blake','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis840','Lewis','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blewis840','Lewis','Blake','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wlewis','Lewis','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler842','Butler','John','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler842','Butler','John','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bbutler843','Butler','Betty','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gthompson','Thompson','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gthompson','Thompson','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gthompson','Thompson','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gthompson','Thompson','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('glangenberg','Langenberg','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('glangenberg','Langenberg','Greg','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ajohnson','Johnson','Ann','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ajohnson','Johnson','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ajohnson','Johnson','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite847','White','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite847','White','Ann','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('awhite847','White','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson848','Henderson','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson848','Henderson','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mwilliams849','Williams','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nprice','Price','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nprice','Price','Nancy','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nprice','Price','Nancy','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dthompson851','Thompson','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dthompson851','Thompson','Donna','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ebutler852','Butler','Erik','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ebutler852','Butler','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ebutler852','Butler','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ebutler852','Butler','Erik','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdavis853','Davis','Kim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdavis853','Davis','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kdavis853','Davis','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper854','Gasper','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alangenberg855','Langenberg','Ann','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark856','Clark','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kclark856','Clark','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wdavis','Davis','William','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters858','Walters','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters858','Walters','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters858','Walters','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwalters858','Walters','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice859','Price','Erik','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice859','Price','Erik','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice859','Price','Erik','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('eprice859','Price','Erik','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slee860','Lee','Sarah','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slee860','Lee','Sarah','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slee860','Lee','Sarah','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('slee860','Lee','Sarah','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters861','Walters','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rprice862','Price','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rprice862','Price','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rprice862','Price','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rprice862','Price','Robert','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez863','Martinez','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez863','Martinez','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez863','Martinez','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez863','Martinez','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark864','Clark','Mary','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark864','Clark','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters865','Walters','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters865','Walters','Lisa','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters865','Walters','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lwalters865','Walters','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('handerson866','Anderson','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dhenderson867','Henderson','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldoe868','Doe','Lisa','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldoe868','Doe','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldoe868','Doe','Lisa','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ldoe868','Doe','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles869','Gonazles','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggonazles869','Gonazles','Greg','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson870','Anderson','Karoline','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson870','Anderson','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson870','Anderson','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kanderson870','Anderson','Karoline','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ajohnson871','Johnson','Ann','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ajohnson871','Johnson','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper872','Gasper','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper872','Gasper','Betty','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper872','Gasper','Betty','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgasper872','Gasper','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee873','Lee','John','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee873','Lee','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson874','Henderson','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson874','Henderson','Karoline','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams875','Williams','John','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwilliams875','Williams','John','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwilliams','Williams','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwilliams','Williams','Nancy','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwilliams','Williams','Nancy','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nwilliams','Williams','Nancy','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbrown877','Brown','Karoline','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bthompson878','Thompson','Blake','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bthompson878','Thompson','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bthompson878','Thompson','Blake','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis879','Davis','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis879','Davis','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis879','Davis','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rdavis879','Davis','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gthompson880','Thompson','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gthompson880','Thompson','Greg','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gthompson880','Thompson','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson881','Peterson','Blake','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson881','Peterson','Blake','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson881','Peterson','Blake','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson881','Peterson','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown882','Brown','Marie','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown882','Brown','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mbrown882','Brown','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez883','Martinez','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez883','Martinez','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez883','Martinez','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hwhite884','White','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson885','Henderson','Lisa','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson885','Henderson','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson885','Henderson','Lisa','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson885','Henderson','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('thenderson','Henderson','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('thenderson','Henderson','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('thenderson','Henderson','Thomas','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('sdavis887','Davis','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark888','Clark','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark888','Clark','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark888','Clark','David','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dclark888','Clark','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson889','Peterson','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson889','Peterson','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dpeterson889','Peterson','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler890','Butler','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith891','Smith','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith891','Smith','Kiersten','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlopez892','Lopez','Robert','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlopez892','Lopez','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ksmith893','Smith','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdavis894','Davis','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdavis894','Davis','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe895','Doe','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe895','Doe','Donna','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddoe895','Doe','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith896','Smith','Michael','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('msmith896','Smith','Michael','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis897','Davis','Michael','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis897','Davis','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mdavis897','Davis','Michael','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez898','Martinez','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg899','Langenberg','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlangenberg899','Langenberg','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdavis900','Davis','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdavis900','Davis','Colin','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdavis900','Davis','Colin','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdavis900','Davis','Colin','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez901','Martinez','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez901','Martinez','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez902','Martinez','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez902','Martinez','Thomas','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez902','Martinez','Thomas','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tmartinez902','Martinez','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice903','Price','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bprice903','Price','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdavis904','Davis','Jo','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdavis904','Davis','Jo','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdavis904','Davis','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jdavis904','Davis','Jo','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez905','Martinez','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jmartinez905','Martinez','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('landerson906','Anderson','Lori','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlee','Lee','Robert','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlee','Lee','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlee','Lee','Robert','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rlee','Lee','Robert','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlewis908','Lewis','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez909','Lopez','Jo','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlopez909','Lopez','Jo','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper910','Gasper','Karoline','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper910','Gasper','Karoline','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgasper910','Gasper','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mscott911','Scott','Michael','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smorrison','Morrison','Sarah','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smorrison','Morrison','Sarah','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smorrison','Morrison','Sarah','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('smorrison','Morrison','Sarah','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson913','Johnson','Karl','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson913','Johnson','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson913','Johnson','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite914','White','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite914','White','Bill','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite914','White','Bill','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwhite914','White','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles915','Gonazles','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles915','Gonazles','Kim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles915','Gonazles','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgasper916','Gasper','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis917','Lewis','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis917','Lewis','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mjohnson918','Johnson','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis919','Davis','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis919','Davis','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis919','Davis','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ddavis919','Davis','David','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dvales920','Vales','Donna','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg921','Langenberg','Mary','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg921','Langenberg','Mary','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlangenberg921','Langenberg','Mary','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales922','Vales','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgrady923','Grady','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith924','Smith','Heather','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hsmith924','Smith','Heather','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lgrady925','Grady','Lori','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler926','Butler','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler926','Butler','Greg','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('gbutler926','Butler','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite927','White','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite927','White','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite927','White','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bpeterson928','Peterson','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlewis','Lewis','Nancy','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('nlewis','Lewis','Nancy','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts930','Roberts','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts930','Roberts','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jroberts930','Roberts','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kpeterson931','Peterson','Kiersten','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson932','Henderson','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis933','Lewis','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis933','Lewis','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis933','Lewis','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlewis933','Lewis','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg934','Langenberg','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg934','Langenberg','David','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dlangenberg934','Langenberg','David','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kbutler935','Butler','Kim','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rjohnson','Johnson','Robert','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters937','Walters','Jennifer','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters937','Walters','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwalters937','Walters','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kgonazles938','Gonazles','Kiersten','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper939','Gasper','Marie','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper939','Gasper','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper939','Gasper','Marie','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper939','Gasper','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez940','Lopez','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez940','Lopez','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez940','Lopez','Kim','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klopez940','Lopez','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite941','White','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgonazles942','Gonazles','James','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgonazles942','Gonazles','James','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgonazles942','Gonazles','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jgonazles942','Gonazles','James','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson943','Henderson','Kim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson943','Henderson','Kim','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('khenderson943','Henderson','Kim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson944','Henderson','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson944','Henderson','Mark','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson944','Henderson','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cprice','Price','Colin','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cprice','Price','Colin','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cprice','Price','Colin','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cprice','Price','Colin','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson946','Anderson','Jim','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson946','Anderson','Jim','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ejohnson947','Johnson','Erik','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ejohnson947','Johnson','Erik','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ejohnson947','Johnson','Erik','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ejohnson947','Johnson','Erik','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson948','Anderson','John','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson948','Anderson','John','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson948','Anderson','John','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('janderson948','Anderson','John','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson949','Henderson','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson949','Henderson','Lisa','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson949','Henderson','Lisa','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lhenderson949','Henderson','Lisa','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee950','Lee','Mary','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mlee950','Lee','Mary','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams951','Williams','Eric','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams951','Williams','Eric','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ewilliams951','Williams','Eric','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plewis','Lewis','Paul','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plewis','Lewis','Paul','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('plewis','Lewis','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark953','Clark','Marie','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mclark953','Clark','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwilliams954','Williams','David','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('rroberts955','Roberts','Robert','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jsmith956','Smith','Jo','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite957','White','Jennifer','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite957','White','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite957','White','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jwhite957','White','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters958','Walters','Bill','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters958','Walters','Bill','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bwalters958','Walters','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson959','Henderson','Mark','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson959','Henderson','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson959','Henderson','Mark','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mhenderson959','Henderson','Mark','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper960','Gasper','Mark','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper960','Gasper','Mark','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mgasper960','Gasper','Mark','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ppeterson','Peterson','Paul','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ppeterson','Peterson','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott962','Scott','John','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jscott962','Scott','John','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdavis963','Davis','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdavis963','Davis','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hdavis963','Davis','Heather','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pwhite','White','Paul','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters965','Walters','David','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters965','Walters','David','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dwalters965','Walters','David','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('blopez966','Lopez','Blake','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady967','Grady','Blake','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady967','Grady','Blake','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgrady967','Grady','Blake','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark968','Clark','Bill','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark968','Clark','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark968','Clark','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bclark968','Clark','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lprice969','Price','Lisa','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wpeterson970','Peterson','William','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wpeterson970','Peterson','William','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wpeterson970','Peterson','William','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wpeterson970','Peterson','William','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('banderson971','Anderson','Betty','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('banderson971','Anderson','Betty','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hprice972','Price','Heather','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hprice972','Price','Heather','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson973','Peterson','Marie','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson973','Peterson','Marie','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mpeterson973','Peterson','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ngonazles','Gonazles','Nancy','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ngonazles','Gonazles','Nancy','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales975','Vales','James','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales975','Vales','James','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales975','Vales','James','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales975','Vales','James','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson976','Peterson','Jennifer','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson976','Peterson','Jennifer','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jpeterson976','Peterson','Jennifer','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kmartinez977','Martinez','Kim','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbrown978','Brown','Paul','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('pbrown978','Brown','Paul','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler979','Butler','Donna','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler979','Butler','Donna','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('dbutler979','Butler','Donna','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison980','Morrison','Heather','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison980','Morrison','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmorrison980','Morrison','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdoe981','Doe','Colin','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdoe981','Doe','Colin','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('cdoe981','Doe','Colin','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alee','Lee','Ann','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alee','Lee','Ann','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('alee','Lee','Ann','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee983','Lee','Jo','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee983','Lee','Jo','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jlee983','Lee','Jo','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice984','Price','Marie','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice984','Price','Marie','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mprice984','Price','Marie','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler985','Butler','Jo','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler985','Butler','Jo','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jbutler985','Butler','Jo','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez986','Martinez','Mary','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez986','Martinez','Mary','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('mmartinez986','Martinez','Mary','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmartinez','Martinez','Heather','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmartinez','Martinez','Heather','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('hmartinez','Martinez','Heather','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('twalters988','Walters','Thomas','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('twalters988','Walters','Thomas','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('twalters988','Walters','Thomas','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('twalters988','Walters','Thomas','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwilliams989','Williams','Karl','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwilliams989','Williams','Karl','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kwilliams989','Williams','Karl','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('emartinez990','Martinez','Eric','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('emartinez990','Martinez','Eric','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('emartinez990','Martinez','Eric','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klee991','Lee','Karoline','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('klee991','Lee','Karoline','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson992','Johnson','Bill','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson992','Johnson','Bill','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson992','Johnson','Bill','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bjohnson992','Johnson','Bill','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wdavis993','Davis','William','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('wdavis993','Davis','William','CS252'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('bgonazles994','Gonazles','Blake','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales995','Vales','Jennifer','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('jvales995','Vales','Jennifer','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('kjohnson996','Johnson','Kiersten','CS251'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggrady','Grady','Greg','SCI123'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggrady','Grady','Greg','MATH101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('ggrady','Grady','Greg','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler998','Butler','Lori','ACCT101'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler998','Butler','Lori','MATH100'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler998','Butler','Lori','ACCT201'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('lbutler998','Butler','Lori','SCI404'); +INSERT INTO SIS_COURSES (uid, surname, givenName, courseId) VALUES ('tgasper999','Gasper','Thomas','CS252'); diff --git a/deps/mysql/build.sh b/deps/mysql/build.sh new file mode 100755 index 0000000..a2c7f8e --- /dev/null +++ b/deps/mysql/build.sh @@ -0,0 +1,2 @@ +#!/bin/bash +docker build . -t tier-demo-mysql diff --git a/deps/rabbit/Dockerfile b/deps/rabbit/Dockerfile new file mode 100644 index 0000000..3c054f0 --- /dev/null +++ b/deps/rabbit/Dockerfile @@ -0,0 +1,9 @@ +FROM rabbitmq:3-management + +MAINTAINER "TIER API & EntReg Working Group " + +#TODO: Copy local queue configuration into container +# 1. copy local json file to container +# 2. run rabbitmqadmin to import configuration + +COPY definitions.json rabbitmq.config /etc/rabbitmq/ diff --git a/deps/rabbit/definitions.json b/deps/rabbit/definitions.json new file mode 100644 index 0000000..54372e0 --- /dev/null +++ b/deps/rabbit/definitions.json @@ -0,0 +1 @@ +{"rabbit_version":"3.6.12","users":[{"name":"guest","password_hash":"4VmAkFG+K+rvBMmSMveyMOapIC1bgVHQHqT08yxmrVOalkQb","hashing_algorithm":"rabbit_password_hashing_sha256","tags":"administrator"}],"vhosts":[{"name":"/"}],"permissions":[{"user":"guest","vhost":"/","configure":".*","write":".*","read":".*"}],"parameters":[],"global_parameters":[{"name":"cluster_name","value":"rabbit@643b562f2679"}],"policies":[],"queues":[{"name":"CS102","vhost":"/","durable":true,"auto_delete":false,"arguments":{}},{"name":"CS101","vhost":"/","durable":true,"auto_delete":false,"arguments":{}},{"name":"MATH101","vhost":"/","durable":true,"auto_delete":false,"arguments":{}},{"name":"ACCT101","vhost":"/","durable":true,"auto_delete":false,"arguments":{}},{"name":"TIER101","vhost":"/","durable":true,"auto_delete":false,"arguments":{}}],"exchanges":[],"bindings":[{"source":"amq.topic","vhost":"/","destination":"ACCT101","destination_type":"queue","routing_key":"basis.courses.ACCT101","arguments":{}},{"source":"amq.topic","vhost":"/","destination":"CS101","destination_type":"queue","routing_key":"basis.courses.CS101","arguments":{}},{"source":"amq.topic","vhost":"/","destination":"CS102","destination_type":"queue","routing_key":"basis.courses.CS102","arguments":{}},{"source":"amq.topic","vhost":"/","destination":"MATH101","destination_type":"queue","routing_key":"basis.courses.MATH101","arguments":{}},{"source":"amq.topic","vhost":"/","destination":"TIER101","destination_type":"queue","routing_key":"basis.courses.TIER101","arguments":{}}]} diff --git a/deps/rabbit/rabbitmq.config b/deps/rabbit/rabbitmq.config new file mode 100644 index 0000000..436c133 --- /dev/null +++ b/deps/rabbit/rabbitmq.config @@ -0,0 +1,14 @@ +[ + { rabbit, [ + { loopback_users, [ ] }, + { tcp_listeners, [ 5672 ] }, + { ssl_listeners, [ ] }, + { hipe_compile, false } + ] }, + { rabbitmq_management, [ + { load_definitions, "/etc/rabbitmq/definitions.json"}, + { listener, [ + { port, 15672 }, + { ssl, false } + ] } ] } +]. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7e8dbdf --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,78 @@ +version: "2" +services: +# midpoint: +# image: tier-demo-midpoint +# mem_limit: 4g +# container_name: tier-demo-midpoint +# ports: +# - 8081:8080 +# + mysql: + image: tier-demo-mysql + container_name: tier-demo-mysql + ports: + - 3306:3306 + ldap: + image: tier-demo-ldap + container_name: tier-demo-ldap + ports: + - 389:389 + grouper: + image: tier-demo-grouper + mem_limit: 4g + container_name: tier-demo-grouper + ports: + - 8080:8080 + depends_on: + # Note: this only starts the other containers first. + # Still need to check to make sure they are available on container start. + - mysql + - ldap + shib: + image: tier-demo-idp + container_name: tier-demo-idp + ports: + - 443:4443 + # - 8443:8443 + depends_on: + - ldap + web-app: + image: tier-demo-web-app + container_name: tier-demo-web-app + ports: + - 9443:9443 + depends_on: + - shib + + rabbit: + image: tier-demo-rabbit + container_name: tier-demo-rabbit + ports: + - 4369:4369 + - 5671:5671 + - 5672:5672 + - 15671:15671 + - 15672:15672 + - 25672:25672 + + sis-web: + image: tier-sis-web + container_name: tier-sis-web + ports: + - "3000:3000" + depends_on: + - mysql + + canvas: + image: tier-demo-canvas + container_name: tier-demo-canvas +# volumes: +# - .:/shared_t1j + depends_on: + - rabbit + + attribute-slammer: + image: tier-attribute-slammer + container_name: tier-attribute-slammer + depends_on: + - grouper diff --git a/grouper/Dockerfile b/grouper/Dockerfile new file mode 100644 index 0000000..f4b27f2 --- /dev/null +++ b/grouper/Dockerfile @@ -0,0 +1,137 @@ +FROM ubuntu:trusty + +MAINTAINER "TIER API & EntReg Working Group " + +ENV JAVA_HOME=/opt/jdk-home \ + ANT_HOME=/opt/ant \ + PATH=$PATH:$JAVA_HOME/bin:/opt/container-scripts:$ANT_HOME/bin \ + GROUPER_VERSION=2.3.0 \ + tomcat_version=8.0.45 + +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y wget tar unzip dos2unix expect vim + +RUN set -x; \ + java_version=8.0.131; \ + zulu_version=8.21.0.1; \ + java_md5_hash=1931ed3beedee0b16fb7fd37e069b162; \ + tomcat_version=8.0.45; \ + tomcat_sha1_hash=ed27fc0564bafd5a81a6975b9aa6dd29101d8ff8; \ + ant_version=1.10.1; \ + ant_sha1_hash=fa9acb3b1987f8acf2aa7a87894d1fd9da80e871; \ + \ + echo 'Downloading the JDK...' \ + && wget -q http://cdn.azul.com/zulu/bin/zulu$zulu_version-jdk$java_version-linux_x64.tar.gz \ + && echo 'Downloading Tomcat...'\ + && wget -q https://archive.apache.org/dist/tomcat/tomcat-8/v$tomcat_version/bin/apache-tomcat-$tomcat_version.zip \ + && echo 'Downloading Ant...'\ + && wget -q https://archive.apache.org/dist/ant/binaries/apache-ant-$ant_version-bin.zip \ + && echo 'Downloading grouper installer...'\ + && wget -q http://software.internet2.edu/grouper/release/$GROUPER_VERSION/grouperInstaller.jar \ + && echo 'Downloading grouper API...'\ + && wget -q http://software.internet2.edu/grouper/release/$GROUPER_VERSION/grouper.apiBinary-$GROUPER_VERSION.tar.gz \ + && echo 'Downloading grouper UI...'\ + && wget -q http://software.internet2.edu/grouper/release/$GROUPER_VERSION/grouper.ui-$GROUPER_VERSION.tar.gz \ + && echo 'Downloading grouper Web Services...'\ + && wget -q http://software.internet2.edu/grouper/release/$GROUPER_VERSION/grouper.ws-$GROUPER_VERSION.tar.gz \ + && echo 'Downloading grouper client...'\ + && wget -q http://software.internet2.edu/grouper/release/$GROUPER_VERSION/grouper.clientBinary-$GROUPER_VERSION.tar.gz \ + && echo 'Downloading grouper PSP...'\ + && wget -q http://software.internet2.edu/grouper/release/$GROUPER_VERSION/grouper.psp-$GROUPER_VERSION.tar.gz \ + && echo 'Downloading grouper PSPNG...'\ + && wget -q http://software.internet2.edu/grouper/release/$GROUPER_VERSION/grouper.pspng-$GROUPER_VERSION.tar.gz \ + && echo 'Downloading grouper Quickstart...'\ + && wget -q http://software.internet2.edu/grouper/release/$GROUPER_VERSION/quickstart.xml \ + \ + && echo "$java_md5_hash zulu$zulu_version-jdk$java_version-linux_x64.tar.gz" | md5sum -c - \ + && tar -zxvf zulu$zulu_version-jdk$java_version-linux_x64.tar.gz -C /opt \ + && rm zulu$zulu_version-jdk$java_version-linux_x64.tar.gz \ + && ln -s /opt/zulu$zulu_version-jdk$java_version-linux_x64/ /opt/jdk-home \ + \ + && echo "$tomcat_sha1_hash apache-tomcat-$tomcat_version.zip" | sha1sum -c - \ + && unzip apache-tomcat-$tomcat_version.zip -d /opt 1>/dev/null \ + && rm -r apache-tomcat-$tomcat_version.zip /opt/apache-tomcat-$tomcat_version/webapps/* \ + && ln -s /opt/apache-tomcat-$tomcat_version /opt/tomcat \ + \ + && unzip apache-ant-$ant_version-bin.zip -d /opt 1>/dev/null \ + && echo "$ant_sha1_hash apache-ant-$ant_version-bin.zip" | sha1sum -c - \ + && rm -r apache-ant-$ant_version-bin.zip /opt/apache-ant-$ant_version/manual/ \ + && ln -s /opt/apache-ant-$ant_version /opt/ant \ + && chmod +x /opt/apache-ant-$ant_version/bin/ant \ + \ + && tar -zxf grouper.apiBinary-$GROUPER_VERSION.tar.gz -C /opt \ + && tar -zxf grouper.ui-$GROUPER_VERSION.tar.gz -C /opt \ + && tar -zxf grouper.ws-$GROUPER_VERSION.tar.gz -C /opt \ + && tar -zxf grouper.clientBinary-$GROUPER_VERSION.tar.gz -C /opt \ + && tar -zxf grouper.psp-$GROUPER_VERSION.tar.gz -C /opt \ + && tar -zxf grouper.pspng-$GROUPER_VERSION.tar.gz -C /opt \ + + && cp -R /opt/grouper.psp-$GROUPER_VERSION/lib/custom/* /opt/grouper.apiBinary-$GROUPER_VERSION/lib/custom \ + && cp -R /opt/grouper.pspng-$GROUPER_VERSION/lib/custom/* /opt/grouper.apiBinary-$GROUPER_VERSION/lib/custom \ + && cp -R /opt/grouper.pspng-$GROUPER_VERSION/dist/* /opt/grouper.apiBinary-$GROUPER_VERSION/lib/grouper \ + && rm grouper.apiBinary-$GROUPER_VERSION.tar.gz grouper.ui-$GROUPER_VERSION.tar.gz grouper.ws-$GROUPER_VERSION.tar.gz grouper.psp-$GROUPER_VERSION.tar.gz grouper.clientBinary-$GROUPER_VERSION.tar.gz + + +COPY opt/ /opt/ + +RUN set -x; \ + chmod -R +x /opt/container-scripts/; \ + chmod -R +x /opt/apache-tomcat-$tomcat_version/bin/*.sh; \ + JAVA_HOME=/opt/jdk-home; \ + echo Building the wars before patching so embedded api patching works properly \ + && mkdir /opt/webapps \ + && cd /opt/grouper.ui-$GROUPER_VERSION \ + && /opt/ant/bin/ant war \ + && cp dist/grouper.war /opt/webapps \ + && cd /opt/grouper.ws-$GROUPER_VERSION/grouper-ws/ \ + && /opt/ant/bin/ant dist \ + && cp build/dist/grouper-ws.war /opt/webapps \ + && echo Extracting Tomcats war files for patching \ + && mkdir /opt/webapps/grouper/ /opt/webapps/grouper-ws/ \ + && cd /opt/webapps/grouper \ + && $JAVA_HOME/bin/jar xvf ../grouper.war \ + && cd /opt/webapps/grouper-ws \ + && $JAVA_HOME/bin/jar xvf ../grouper-ws.war \ + && cd /opt/grouper.apiBinary-$GROUPER_VERSION \ + #&& bin/gsh -registry -check -runscript -noprompt \ + && mkdir /tmp/grp-api/ /tmp/grp-ui/ /tmp/grp-psp/ /tmp/grp-pspng/ /tmp/grp-ws/ \ + && cd / \ + # Patch everything we either just downloaded or built above. + && cp /opt/patch-scripts/grouper.installer-api.properties /grouper.installer.properties \ + && $JAVA_HOME/bin/java -cp .:/grouperInstaller.jar edu.internet2.middleware.grouperInstaller.GrouperInstaller \ + # bootstrap on container start as required. + #&& cd /opt/grouper.apiBinary-$GROUPER_VERSION \ + #&& bin/gsh -registry -check -runscript -noprompt \ + #&& bin/gsh /bootstrap.gsh \ + #&& bin/gsh /pspng.gsh \ + && cd / \ + && cp /opt/patch-scripts/grouper.installer-psp.properties /grouper.installer.properties \ + && $JAVA_HOME/bin/java -cp .:/grouperInstaller.jar edu.internet2.middleware.grouperInstaller.GrouperInstaller \ + && cp /opt/patch-scripts/grouper.installer-pspng.properties /grouper.installer.properties \ + && $JAVA_HOME/bin/java -cp .:/grouperInstaller.jar edu.internet2.middleware.grouperInstaller.GrouperInstaller \ + && cp /opt/patch-scripts/grouper.installer-ui.properties /grouper.installer.properties \ + && $JAVA_HOME/bin/java -cp .:/grouperInstaller.jar edu.internet2.middleware.grouperInstaller.GrouperInstaller \ + && cp /opt/patch-scripts/grouper.installer-ws.properties /grouper.installer.properties \ + && $JAVA_HOME/bin/java -cp .:/grouperInstaller.jar edu.internet2.middleware.grouperInstaller.GrouperInstaller \ + && rm -fr /tmp/grp-ui/ /tmp/grp-api/ /tmp/grp-psp/ /tmp/grp-pspng/ /tmp/grp-ws/ + +# Grouper SCIM Stuff +# +# not using SCIM...did not have all the necessary endpoints available yet +# +#COPY scim/grouper-ws-scim /opt/webapps/grouper-ws-scim +#RUN set -x; \ +# cp -rv /opt/grouper.apiBinary-$GROUPER_VERSION/conf/. /opt/webapps/grouper-ws-scim/WEB-INF/classes/ + + +# Indicate the container needs bootstrapping +RUN touch /FIRSTRUN + +# TODO: Apache proxy in front of tomcat. set tomcat up on AJP + +COPY run-grouper.sh /usr/local/bin/ +COPY seed-data/ /opt/bootstrap + +EXPOSE 8080 + +CMD ["/bin/bash", "/usr/local/bin/run-grouper.sh"] diff --git a/grouper/build.sh b/grouper/build.sh new file mode 100755 index 0000000..054e53e --- /dev/null +++ b/grouper/build.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# build.sh, DESCRIPTION +# +# Copyright (C) 2017 Tom Jordan +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# $Id:$ +# Tom Jordan +docker build . -t tier-demo-grouper diff --git a/grouper/data-generator.html b/grouper/data-generator.html new file mode 100644 index 0000000..871b3d4 --- /dev/null +++ b/grouper/data-generator.html @@ -0,0 +1,169 @@ + + + + + +
+ Number of Subjects:
+ Table Name:
+ People OU:
+
+
+ + Ldif:

+ Sql:

+ + \ No newline at end of file diff --git a/grouper/opt/apache-tomcat-8.0.45/bin/setenv.sh b/grouper/opt/apache-tomcat-8.0.45/bin/setenv.sh new file mode 100644 index 0000000..2035b59 --- /dev/null +++ b/grouper/opt/apache-tomcat-8.0.45/bin/setenv.sh @@ -0,0 +1 @@ +export JAVA_OPTS="-Xms64m -Xmx750m -XX:MaxPermSize=512m -Dfile.encoding=UTF-8" diff --git a/grouper/opt/apache-tomcat-8.0.45/conf/server.xml b/grouper/opt/apache-tomcat-8.0.45/conf/server.xml new file mode 100644 index 0000000..0b9cd89 --- /dev/null +++ b/grouper/opt/apache-tomcat-8.0.45/conf/server.xml @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper-loader.properties b/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper-loader.properties new file mode 100644 index 0000000..507a114 --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper-loader.properties @@ -0,0 +1,91 @@ +#specify the consumers here. specify the consumer name after the changeLog.consumer. part. This example is "psp" +#but it could be changeLog.consumer.myConsumerName.class +#the class must extend edu.internet2.middleware.grouper.changeLog.ChangeLogConsumerBase +#changeLog.consumer.psp.class = edu.internet2.middleware.psp.grouper.PspChangeLogConsumer + +#the quartz cron is a cron-like string. it defaults to every minute on the minute (since the temp to change log job runs +#at 10 seconds to each minute). it defaults to this: 0 * * * * ? +#though it will stagger each one by 2 seconds +# http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger +#changeLog.consumer.psp.quartzCron = 0 * * * * ? + +# To retry processing a change log entry if an error occurs, set retryOnError to true. Defaults to false. +#changeLog.consumer.psp.retryOnError = false + +# To run full provisioning synchronizations periodically, provide the class name which provides a 'public void fullSync()' method. +#changeLog.psp.fullSync.class = edu.internet2.middleware.psp.grouper.PspChangeLogConsumer + +# Schedule full synchronizations. Defaults to 5 am : 0 0 5 * * ?. +#changeLog.psp.fullSync.quartzCron = 0 0 5 * * ? + +# Run a full synchronization job at startup. Defaults to false. +#changeLog.psp.fullSync.runAtStartup = false + +# Omit diff responses from bulk response to conserve memory. +#changeLog.psp.fullSync.omitDiffResponses = true + +# Omit sync responses from bulk response to conserve memory. +#changeLog.psp.fullSync.omitSyncResponses = true + +################################# +## LDAP connections +################################# +# specify the ldap connection with user, pass, url +# the string after "ldap." is the ID of the connection, and it should not have +# spaces or other special chars in it. In this case is it "personLdap" + +#note the URL should start with ldap: or ldaps: if it is SSL. +#It should contain the server and port (optional if not default), and baseDn, +#e.g. ldaps://ldapserver.school.edu:636/dc=school,dc=edu +ldap.demo.url = ldap://tier-demo-ldap:389/dc=example,dc=edu + +#optional, if authenticated +#ldap.personLdap.user = uid=someapp,ou=people,dc=myschool,dc=edu + +#optional, if authenticated note the password can be stored encrypted in an external file +#ldap.personLdap.pass = secret + +#optional, if you are using tls, set this to true. Generally you will not be using an SSL URL to use TLS... +#ldap.personLdap.tls = false + +#optional, if using sasl +#ldap.personLdap.saslAuthorizationId = +#ldap.personLdap.saslRealm = + +#optional (note, time limit is for search operations, timeout is for connection timeouts), +#most of these default to vt-ldap defaults. times are in millis +#validateOnCheckout defaults to true if all other validate methods are false +#ldap.personLdap.batchSize = +#ldap.personLdap.countLimit = +#ldap.personLdap.timeLimit = +#ldap.personLdap.timeout = +#ldap.personLdap.minPoolSize = +#ldap.personLdap.maxPoolSize = +#ldap.personLdap.validateOnCheckIn = +#ldap.personLdap.validateOnCheckOut = +#ldap.personLdap.validatePeriodically = +#ldap.personLdap.validateTimerPeriod = +#ldap.personLdap.pruneTimerPeriod = +#if connections expire after a certain amount of time, this is it, in millis, defaults to 300000 (5 minutes) +#ldap.personLdap.expirationTime = + +# t1j - ESB Changelog to Rabbit + +# ESB changelog consumer +changeLog.consumer.esbAmqp.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer +#run every second +changeLog.consumer.esbAmqp.quartzCron = */10 * * * * ? +changeLog.consumer.esbAmqp.elfilter = event.eventType eq 'GROUP_DELETE' || event.eventType eq 'GROUP_ADD' || event.eventType eq 'MEMBERSHIP_DELETE' || event.eventType eq 'MEMBERSHIP_ADD' + +changeLog.consumer.esbAmqp.publisher.class = net.unicon.grouper.changelog.esb.publisher.EsbAmqpPublisher +changeLog.consumer.esbAmqp.hostName = tier-demo-rabbit +changeLog.consumer.esbAmqp.defaultExchange = amq.topic + +# SpEL-based regex replacement definition. The chain of 'replaceFirst' method calls will be applied to an extracted group name (String) at runtime +# See: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replaceFirst(java.lang.String,%20java.lang.String) +#changeLog.consumer.esbAmqp.regexReplacementDefinition = replaceFirst('^hawaii.edu:', 'group.modify.').replaceFirst('(:enrolled|:waitlisted|:withdrawn)$', '') +changeLog.consumer.esbAmqp.replaceRoutingKeyColonsWithPeriods = true + +# we need the regular changelog processor to run more often for demo purposes: +#quartz cron-like schedule for change log temp to change log daemon, the default is 50 seconds after every minute: 50 * * * * ? +changeLog.changeLogTempToChangeLog.quartz.cron = */10 * * * * ? diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper.hibernate.properties b/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper.hibernate.properties new file mode 100644 index 0000000..9d00b22 --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper.hibernate.properties @@ -0,0 +1,30 @@ +# +# Grouper Hibernate Configuration +# $Id: grouper.hibernate.example.properties,v 1.9 2009-08-11 20:18:09 mchyzer Exp $ +# + +# The grouper hibernate config uses Grouper Configuration Overlays (documented on wiki) +# By default the configuration is read from grouper.hibernate.base.properties +# (which should not be edited), and the grouper.hibernate.properties overlays +# the base settings. See the grouper.hibernate.base.properties for the possible +# settings that can be applied to the grouper.hibernate.properties + +######################################## +## DB settings +######################################## + +# e.g. mysql: jdbc:mysql://localhost:3306/grouper +# e.g. p6spy (log sql): [use the URL that your DB requires] +# e.g. oracle: jdbc:oracle:thin:@server.school.edu:1521:sid +# e.g. hsqldb (a): jdbc:hsqldb:dist/run/grouper;create=true +# e.g. hsqldb (b): jdbc:hsqldb:hsql://localhost:9001/grouper +# e.g. postgres: jdbc:postgresql://localhost:5432/database +# e.g. mssql: jdbc:sqlserver://localhost:3280;databaseName=grouper +hibernate.connection.url = jdbc:mysql://tier-demo-mysql:3306/grouper?CharSet=utf8&useUnicode=true&characterEncoding=utf8 + +hibernate.connection.username = root +# If you are using an empty password, depending upon your version of +# Java and Ant you may need to specify a password of "". +# Note: you can keep passwords external and encrypted: https://bugs.internet2.edu/jira/browse/GRP-122 +hibernate.connection.password = + diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper.properties b/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper.properties new file mode 100644 index 0000000..c931287 --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/grouper.properties @@ -0,0 +1,25 @@ +# +# Grouper Configuration +# $Id: grouper.example.properties,v 1.48 2009-12-16 06:02:30 mchyzer Exp $ +# + +# Grouper uses Grouper Configuration Overlays (documented on wiki) +# By default the configuration is read from grouper.base.properties +# (which should not be edited), and the grouper.properties overlays +# the base settings. See the grouper.base.properties for the possible +# settings that can be applied to the grouper.properties + +#if groups like the wheel group should be auto-created for convenience (note: check config needs to be on) +configuration.autocreate.system.groups = true + +# A wheel group allows you to enable non-GrouperSystem subjects to act +# like a root user when interacting with the registry. +groups.wheel.use = true + +# Set to the name of the group you want to treat as the wheel group. +# The members of this group will be treated as root-like users. +groups.wheel.group = etc:sysadmingroup + +# Used to allow Include Exclude groups +grouperIncludeExclude.use = true +grouperIncludeExclude.requireGroups.use = true diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/ldap.properties b/grouper/opt/grouper.apiBinary-2.3.0/conf/ldap.properties new file mode 100644 index 0000000..2008b53 --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/ldap.properties @@ -0,0 +1,73 @@ +# This is the configuration file for vt-ldap. +# See http://code.google.com/p/vt-middleware/wiki/vtldapProperties + +edu.vt.middleware.ldap.ldapUrl=ldap://127.0.0.1:389 +edu.vt.middleware.ldap.searchScope=SUBTREE + +# authn if simple +edu.vt.middleware.ldap.bindDn=cn=admin,dc=example,dc=edu +edu.vt.middleware.ldap.bindCredential=secret +# The bind credential may be external and encrypted: https://bugs.internet2.edu/jira/browse/GRP-122 +# edu.vt.middleware.ldap.bindCredential=/path/to/ldap.pwd +edu.vt.middleware.ldap.authtype=simple + +# encryption +edu.vt.middleware.ldap.ssl=false +edu.vt.middleware.ldap.tls=false + +# pooling options +edu.vt.middleware.ldap.pool.minPoolSize = 2 +edu.vt.middleware.ldap.pool.maxPoolSize = 5 + +# paged results +edu.vt.middleware.ldap.pagedResultsSize=0 + +# authn for sasl external (certificates) +# edu.vt.middleware.ldap.authtype=EXTERNAL +# edu.vt.middleware.ldap.tls=true +# edu.vt.middleware.ldap.serviceUser=cn=admin.example.edu +# these to use PEM format cert and key +# pemCaFile=/path/to/ca.pem +# pemCertFile=/path/to/cert.pem +# pemKeyFile=/path/to/key.pem + + +# The default base DN for searches. +# All subordinate objects will be deleted during tests ! +edu.vt.middleware.ldap.baseDn=dc=example,dc=edu + +# The base DN for groups. +edu.internet2.middleware.psp.groupsBaseDn=ou=groups,dc=example,dc=edu + +# The base DN for people. +edu.internet2.middleware.psp.peopleBaseDn=ou=people,dc=example,dc=edu + +# The group object class. +# OpenLDAP, RedHat, 389, ApacheDS, etc. +edu.internet2.middleware.psp.groupObjectClass=groupOfNames +# Active Directory +# edu.internet2.middleware.psp.groupObjectClass=group + +# The base Grouper stem to be provisioned. +edu.internet2.middleware.psp.baseStem=psp + +# The ldap DN structure may be either flat or bushy. +# In a flat structure all groups are provisioned under a single base DN (container ID). +# A flat group's ldap RDN is its Grouper name or displayName. +# edu.internet2.middleware.psp.structure=flat +# edu.internet2.middleware.psp.cnSourceAttributeID=name + +# In a bushy structure groups are provisioned hierarchically, with stems as branches in the tree. +# A bushy group's RDN is its Grouper extension or displayExtension. +edu.internet2.middleware.psp.structure=flat +edu.internet2.middleware.psp.cnSourceAttributeID=name + +# The QuotedDnResultHandler removes quotes from DNs of the form "CN=quoted/name",DC=edu. +# The FqdnSearchResultHandler makes sure that all ldap dns are fully qualified. +# You may wish to comment out the following property for the Grouper UI or WS. +edu.vt.middleware.ldap.searchResultHandlers=edu.internet2.middleware.psp.ldap.QuotedDnResultHandler,edu.vt.middleware.ldap.handler.FqdnSearchResultHandler + +# handle Active Directory groups with a large (>1500) number of members +# see https://bugs.internet2.edu/jira/browse/GRP-335 +# see http://code.google.com/p/vt-middleware/wiki/vtldapAD#Range_Attributes +# edu.vt.middleware.ldap.searchResultHandlers=edu.internet2.middleware.ldappc.util.QuotedDnResultHandler,edu.vt.middleware.ldap.handler.FqdnSearchResultHandler,edu.internet2.middleware.ldappc.util.RangeSearchResultHandler diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/log4j.properties b/grouper/opt/grouper.apiBinary-2.3.0/conf/log4j.properties new file mode 100644 index 0000000..26803a0 --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/log4j.properties @@ -0,0 +1,157 @@ +# +# Copyright 2014 Internet2 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#${grouper.home} will be substituted with the System property "grouper.home", which must have a trailing \ or / +# depending on your OS. Of course you can use absolute paths if you prefer + + +# +# log4j Configuration +# $Id: log4j.example.properties,v 1.13 2009-12-18 13:56:51 tzeller Exp $ +# + +# Appenders + +## Log messages to stderr +log4j.appender.grouper_stderr = org.apache.log4j.ConsoleAppender +log4j.appender.grouper_stderr.Target = System.err +log4j.appender.grouper_stderr.layout = org.apache.log4j.PatternLayout +log4j.appender.grouper_stderr.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n + +## Log messages to stdout +log4j.appender.grouper_stdout = org.apache.log4j.ConsoleAppender +log4j.appender.grouper_stdout.Target = System.out +log4j.appender.grouper_stdout.layout = org.apache.log4j.PatternLayout +log4j.appender.grouper_stdout.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n + +## Grouper API event logging +log4j.appender.grouper_event = org.apache.log4j.DailyRollingFileAppender +log4j.appender.grouper_event.File = ${grouper.home}logs/grouper_event.log +log4j.appender.grouper_event.DatePattern = '.'yyyy-MM-dd +log4j.appender.grouper_event.layout = org.apache.log4j.PatternLayout +log4j.appender.grouper_event.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n + +## Grouper API error logging +log4j.appender.grouper_error = org.apache.log4j.DailyRollingFileAppender +log4j.appender.grouper_error.File = ${grouper.home}logs/grouper_error.log +log4j.appender.grouper_error.DatePattern = '.'yyyy-MM-dd +log4j.appender.grouper_error.layout = org.apache.log4j.PatternLayout +log4j.appender.grouper_error.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n +#log4j.appender.grouper_error.layout.ConversionPattern = %d{ISO8601}: %m%n + +# Debug logging (Or: logging that I haven't cleaned up yet to send elsewhere) +log4j.appender.grouper_debug = org.apache.log4j.RollingFileAppender +log4j.appender.grouper_debug.File = ${grouper.home}logs/grouper_debug.log +log4j.appender.grouper_debug.MaxFileSize = 100KB +log4j.appender.grouper_debug.MaxBackupIndex = 1 +log4j.appender.grouper_debug.layout = org.apache.log4j.PatternLayout +#log4j.appender.grouper_debug.layout.ConversionPattern = %d{ISO8601} %5p %c{2}: %m%n +log4j.appender.grouper_debug.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n + +## Benchmark logging +log4j.appender.grouper_gb = org.apache.log4j.RollingFileAppender +log4j.appender.grouper_gb.File = ${grouper.home}logs/grouper_bench.log +log4j.appender.grouper_gb.MaxFileSize = 100KB +log4j.appender.grouper_gb.MaxBackupIndex = 1 +log4j.appender.grouper_gb.layout = org.apache.log4j.PatternLayout +#log4j.appender.grouper_gb.layout.ConversionPattern = %d{ISO8601} %5p %c{2}: %m%n +log4j.appender.grouper_gb.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n + +# Loggers + +## Default logger; will log *everything* +log4j.rootLogger = ERROR, grouper_error + +## All Internet2 (warn to grouper_error per default logger) +log4j.logger.edu.internet2.middleware = WARN + + +# Provisioning : PSP (version 2.1+) +log4j.logger.edu.internet2.middleware.psp = INFO + +# Provisioning : vt-ldap +# log4j.logger.edu.vt.middleware.ldap = INFO + +# Provisioning : Grouper plugin to Shibboleth attribute resolver +# log4j.logger.edu.internet2.middleware.grouper.shibboleth = INFO + + +# For more precise (or verbose) logging, enable one or more of the +# following logging directives. To remove duplicate entries, just change the +# level, and not where to send the logs +# http://robertmarkbramprogrammer.blogspot.com/2007/06/log4j-duplicate-lines-in-output.html + +## Grouper Event Logging +## * Logs at _info_ only +log4j.logger.edu.internet2.middleware.grouper.log.EventLog = INFO, grouper_event +log4j.logger.edu.internet2.middleware.grouper.RegistryInstall = INFO, grouper_event, grouper_stderr + +## Grouper Error Logging +## * Logs at _warn_, _fatal_ and _error_ only (by default this is WARN due to internet2 below) +#log4j.logger.edu.internet2.middleware.grouper = WARN, grouper_error + +## Grouper XML Export + Import Logging +## TODO Integrate with normal logging +log4j.logger.edu.internet2.middleware.grouper.xml.XmlExporter = INFO, grouper_event +log4j.logger.edu.internet2.middleware.grouper.xml.XmlImporter = INFO, grouper_event + +## Grouper Benchmark Logging +log4j.logger.edu.internet2.middleware.grouper.bench = INFO, grouper_gb, grouper_stderr + +## Grouper script to add missing group sets +log4j.logger.edu.internet2.middleware.grouper.misc.AddMissingGroupSets = INFO, grouper_event + +## Grouper Sync Point in Time Tables +log4j.logger.edu.internet2.middleware.grouper.misc.SyncPITTables = INFO, grouper_event + +## Grouper Sync Stem Set Table +log4j.logger.edu.internet2.middleware.grouper.misc.SyncStemSets = INFO, grouper_event + +## Grouper Migrate Legacy Attributes +log4j.logger.edu.internet2.middleware.grouper.misc.MigrateLegacyAttributes = INFO, grouper_event + +### Subject API +#log4j.logger.edu.internet2.middleware.subject = ERROR, grouper_error +#log4j.logger.edu.internet2.middleware.subject.provider = ERROR, grouper_error +### Hibernate +#log4j.logger.org.hibernate = ERROR, grouper_error +### ehcache +#log4j.logger.net.sf.ehcache = ERROR, grouper_error +### Spring +#log4j.logger.org.springframework = ERROR, grouper_error + +## Grouper Stress Testing +log4j.logger.edu.internet2.middleware.grouper.stress = INFO, grouper_debug, grouper_stderr + + +####################################################### +##Optional settings for debug logs +####################################################### + +## Hooks debug info +#log4j.logger.edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook = DEBUG +#log4j.logger.edu.internet2.middleware.grouper.Group = DEBUG + +#log4j.logger.edu.internet2.middleware.grouper.hooks.examples.GroupTypeSecurityHook = DEBUG + +## t1j - Dedicated Grouper ESB logging +log4j.appender.grouper_esb = org.apache.log4j.DailyRollingFileAppender +log4j.appender.grouper_esb.File = ${grouper.home}logs/grouper_esb.log +log4j.appender.grouper_esb.DatePattern = '.'yyyy-MM-dd +log4j.appender.grouper_esb.layout = org.apache.log4j.PatternLayout +log4j.appender.grouper_esb.layout.ConversionPattern = %d{ISO8601}: [%t] %-5p %C{1}.%M(%L) - %x - %m%n + +log4j.logger.net.unicon.grouper.changelog.esb.publisher = DEBUG, grouper_esb diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-internal.xml b/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-internal.xml new file mode 100644 index 0000000..9a71728 --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-internal.xml @@ -0,0 +1,37 @@ + + + + + + + + classpath, string + + org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader + + + edu.internet2.middleware.shibboleth.common.util.StringResourceLoader + + + + + + + + + + + + + \ No newline at end of file diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-resolver.xml b/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-resolver.xml new file mode 100644 index 0000000..0d4dfeb --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-resolver.xml @@ -0,0 +1,680 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + top + ${edu.internet2.middleware.psp.groupObjectClass} + + + + + top + organizationalUnit + + + + eduMember + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-services.xml b/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-services.xml new file mode 100644 index 0000000..a8daf9c --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/psp-services.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/psp.xml b/grouper/opt/grouper.apiBinary-2.3.0/conf/psp.xml new file mode 100644 index 0000000..db8d29c --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/psp.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/grouper/opt/grouper.apiBinary-2.3.0/conf/sources.xml b/grouper/opt/grouper.apiBinary-2.3.0/conf/sources.xml new file mode 100644 index 0000000..cb651f4 --- /dev/null +++ b/grouper/opt/grouper.apiBinary-2.3.0/conf/sources.xml @@ -0,0 +1,636 @@ + + + + + + + + + + + + + + + g:gsa + Grouper: Group Source Adapter + group + + + subjectVirtualAttribute_0_searchAttribute0 + ${subject.getAttributeValue('name')},${subject.getAttributeValue('displayName')},${subject.getAttributeValue('alternateName')} + + + sortAttribute0 + displayExtension + + + searchAttribute0 + searchAttribute0 + + + + maxPageSize + 100 + + searchAttribute0 + + + + + + grouperEntities + Grouper: Entity Source Adapter + application + + + subjectVirtualAttribute_0_searchAttribute0 + + ${subject.getAttributeValue('name')},${subject.getAttributeValue('displayName')},${subject.getAttributeValue('alternateName')} + + + sortAttribute0 + name + + + searchAttribute0 + searchAttribute0 + + searchAttribute0 + + + + + jdbc + TIER SIS JDBC Subject Source + person + + + + jdbcConnectionProvider + edu.internet2.middleware.subject.provider.C3p0JdbcConnectionProvider + + + + + + emailAttributeName + email + + + + + maxResults + 1000 + + + + + maxPageSize + 100 + + + + + + maxActive + 16 + + + maxIdle + 16 + + + maxWait + -1 + + + + + + dbDriver + com.mysql.jdbc.Driver + + + + + + dbUrl + jdbc:mysql://tier-demo-mysql:3306/myapp_development + + + dbUser + root + + + dbPwd + + + + + SubjectID_AttributeType + id + + + Name_AttributeType + name + + + Description_AttributeType + description + + + subjectVirtualAttribute_0_searchAttribute0 + ${subject.name},${subjectUtils.defaultIfBlank(subject.getAttributeValue('LFNAME'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValue('LOGINID'), "")},${subjectUtils.defaultIfBlank(subject.description, "")},${subjectUtils.defaultIfBlank(subject.getAttributeValue('EMAIL'), "")} + + + sortAttribute0 + LFNAME + + + sortAttribute1 + LOGINID + + + searchAttribute0 + searchAttribute0 + + searchAttribute0 + + + + useInClauseForIdAndIdentifier + true + + + + + identifierAttributes + LOGINID + + + + searchSubject + + sql + +select + s.uid as id, concat(s.givenname,' ',s.surname) as name, + concat(s.surname,', ',s.givenname) as lfname, + s.uid as loginid, + s.description as description, + s.email as email +from + users s +where + {inclause} + + + + inclause + +s.uid = ? + + + + + searchSubjectByIdentifier + + sql + +select + s.uid as id, concat(s.givenname,' ',s.surname) as name, + concat(s.surname,', ',s.givenname) as lfname, + s.uid as loginid, + s.description as description, + s.email as email +from + users s +where + {inclause} + + + + inclause + + s.uid = ? + + + + + search + + sql + + + + +select + s.uid as id, concat(s.givenname,' ',s.surname) as name, + concat(s.surname,', ',s.givenname) as lfname, + s.uid as loginid, + s.description as description, + s.email as email +from + users s +where + s.uid=? or s.email=? + + + + + + + + + + + + diff --git a/grouper/opt/grouper.apiBinary-2.3.0/lib/grouper/grouper-amqp-esb-publisher-all.jar b/grouper/opt/grouper.apiBinary-2.3.0/lib/grouper/grouper-amqp-esb-publisher-all.jar new file mode 100644 index 0000000..582c271 Binary files /dev/null and b/grouper/opt/grouper.apiBinary-2.3.0/lib/grouper/grouper-amqp-esb-publisher-all.jar differ diff --git a/grouper/opt/grouper.clientBinary-2.3.0/grouper.client.properties b/grouper/opt/grouper.clientBinary-2.3.0/grouper.client.properties new file mode 100644 index 0000000..996f6f7 --- /dev/null +++ b/grouper/opt/grouper.clientBinary-2.3.0/grouper.client.properties @@ -0,0 +1,43 @@ +# +# Grouper client configuration +# $Id: grouper.client.example.properties,v 1.24 2009-12-30 04:23:02 mchyzer Exp $ +# + +# The grouper client uses Grouper Configuration Overlays (documented on wiki) +# By default the configuration is read from grouper.client.base.properties +# (which should not be edited), and the grouper.client.properties overlays +# the base settings. See the grouper.client.base.properties for the possible +# settings that can be applied to the grouper.client.properties + +######################################## +## LDAP connection settings +######################################## + +# url of directory, including the base DN (distinguished name) +# e.g. ldap://server.school.edu/dc=school,dc=edu +# e.g. ldaps://server.school.edu/dc=school,dc=edu +grouperClient.ldap.url = + +# kerberos principal used to connect to ldap +grouperClient.ldap.login = + +# password for shared secret authentication to ldap +# or you can put a filename with an encrypted password +grouperClient.ldap.password = + +######################################## +## Web service Connection settings +######################################## + +# url of web service, should include everything up to the first resource to access +# e.g. http://groups.school.edu:8090/grouper-ws/servicesRest +# e.g. https://groups.school.edu/grouper-ws/servicesRest +grouperClient.webService.url = http://localhost:8080/grouper-ws/servicesRest + +# kerberos principal used to connect to web service +grouperClient.webService.login = banderson + +# password for shared secret authentication to web service +# or you can put a filename with an encrypted password +grouperClient.webService.password = password + diff --git a/grouper/opt/grouper.ui-2.3.0/build.properties b/grouper/opt/grouper.ui-2.3.0/build.properties new file mode 100644 index 0000000..2b6fbfa --- /dev/null +++ b/grouper/opt/grouper.ui-2.3.0/build.properties @@ -0,0 +1,131 @@ +#The Grouper UI requires an instance of the Grouper API. This can be a binary distribution +#or a source distribution which has had the 'dist' ant target run. +#If a java/src directory is present the Grouper UI ant html task will create combined +#Javadoc for the UI and the API +grouper.folder=../grouper.apiBinary-2.3.0 + +#if this is not a grouper source dir, might need to reset some of these +#put the grouper lib dir here +#note, any grouper*.jars here will be ignored. +#e.g. from external: C:/mchyzer/isc/dev/grouper-qs-1.2.0/grouper/lib/grouper +grouper.lib.dir=${grouper.folder}/lib/grouper + +#put the grouper jar dir here +#e.g. from external: C:/mchyzer/isc/dev/grouper-qs-1.2.0/grouper/dist/lib/grouper.jar +grouper.jar.name=${grouper.folder}/dist/lib/grouper.jar + +#By default the Grouper API log4j.properties file references a System property +#grouper.home. Before building / deploying the UI you should ensure that your +#application server e.g. Tomcat has a System property called grouper.home set* +#or you should replace ${grouper.home} with a valid path. The property below +#will cause ${grouper.home} in log4j.properties to be replaced with the grouper folder +#defined below. This is OK when building and deploying on the same system, however, +#if you are making a WAR file to deploy else where you should not rely on this mechanism. +#* Start your application server with a -Dgrouper.home= +replace.grouper.home=true + +#Must be set to * (any role - including none) or an actual role name (e.g. grouper_user) such that +#HttpServletRequest.isUserInRole() is true for a user to be able to +#log into the UI +grouper.role=* + +# Set to false if you want to make manual changes to web.xml or to speed up build +# If you set to false you will need to delete the web.xml to force it to be +# re-built +web.xml.overwrite=true + +#Switches to UI specific log4j.properties +#use.local.log4j=true + +#Make sure directory exists! +#local.log4j.output-dir=c:/tomcat_5-5/logs/ + +#If you want to email errors append to grouper_mail - only works with use.local.log4j=true +error.append=grouper_log +#error.append=grouper_log,grouper_mail +#Change to valid email addresses +error.mail.to=to@yourhost.edu +error.mail.from=from@yourhost.edu +#Change to a valid smtp server +error.mail.host=smtp.yourhost.edu +error.mail.threshold=ERROR +error.mail.buffer-size=100 +error.mail.subject=Grouper UI Error + +#uncomment and correct path for subject.folder if you want to generate Subject API +#Javadoc in with Grouper Javadoc +#subject.folder=C:/delete/subject-2005-07-11/subject + +#If you are making changes to the API, make sure to uncomment grouper.compile.api=true +#grouper.folder must be set to a source distribution +#grouper.compile.api=true +ui.folder=${basedir} + +#Compile UI Java files into temporary folder, JAR and copy to WEB-INF/lib +#Comment out to compile UI Java files direct to WEB-INF/classes +ui.make.jar=true + +#Determines the name of the web application +webapp.name=grouper + +#Where to build +dist.home=${basedir}/dist +default.webapp.folder=${basedir}/build/${webapp.name} +default.webapp.folder.cleanable=true + +#You could insr=tead build in situ - see comments in build.xml +#default.webapp.folder=${basedir}/webapp +#default.webapp.folder.cleanable=false + + +#add an additonal build file to incorporate site specific changes +#additional.build=${basedir}/../custom-grouper-ui/additional-build.xml + +#For development keep these if you want to be able to debug the UI Java source +debug.level=lines,vars,source + +######################################################## +#You can provide an additional build file which sets 'webapp.folder' so you can build +#to an appropriate location. This provides a way of overriding the 'default.webapp.folder' +#specified above. The build file could present a choice of locations. You must output a file +#called choice.properties and set the property webapp.folder +######################################################## +#webapp.choose.build= + +################################################################## +#The grouper UI has only been tested with tomcat 4.1x and 5.5. The following properties allow stopping and starting +#of the grouper webapp and determine if and where a grouper.xml (context.xml format) is copied +################################################################## + +####Url for Tomcat manager +#deploy.manager.url=http://localhost:8080/manager + +####Who to authenticate as +#deploy.manager.username= +#deploy.manager.password= + +####Web application context - as seen by end user +deploy.context.path=/${webapp.name} + +####Root of Tomcat installation +#deploy.home=c:/tomcat_4-1-18 + +####If you are deploying by war to the webapps dir, then you might consider not having a +####context.xml, it will explode the war with each restart, preventing patching +should.copy.context.xml.to.metainf=false + + +####Name of context xml file - this will be copied to META-INF and possibly to tomcat webapps directory +####Look at template-tomcat-context.xml for example - you can copy this and adjust +deploy.context.xml=tomcat-context.xml + + + +####Where to copy the context xml - note that the location for Tomcat 5-5 depends on server.xml settings +####Setting this value lets the build script automatically install your webapp on a local Tomcat instance +#deploy.context.dir=c:/tomcat_4-1-18/webapps +#deploy.context.dir=c:/Tomcat_5-5/conf/Catalina/localhost + +###If the jdbc drivers should be copied from grouper +copy.grouper.jdbc.sample.drivers=true + diff --git a/grouper/opt/grouper.ui-2.3.0/conf/grouper-ui.properties b/grouper/opt/grouper.ui-2.3.0/conf/grouper-ui.properties new file mode 100644 index 0000000..6a6a6eb --- /dev/null +++ b/grouper/opt/grouper.ui-2.3.0/conf/grouper-ui.properties @@ -0,0 +1,838 @@ +# +# Grouper UI configuration +# $Id: grouper.client.example.properties,v 1.24 2009-12-30 04:23:02 mchyzer Exp $ +# + +# The grouper UI proprties uses Grouper Configuration Overlays (documented on wiki) +# By default the configuration is read from grouper-ui.base.properties +# (which should not be edited), and the grouper-ui.properties overlays +# the base settings. See the grouper-ui.base.properties for the possible +# settings that can be applied to the grouper-ui.properties + + +######################################## +## Config chaining hierarchy +######################################## + +# comma separated config files that override each other (files on the right override the left) +# each should start with file: or classpath: +# e.g. classpath:grouper-ui.example.properties, file:c:/something/myconfig.properties +grouperUi.config.hierarchy = classpath:grouper-ui.base.properties, classpath:grouper-ui.properties + +# seconds between checking to see if the config files are updated +grouperUi.config.secondsBetweenUpdateChecks = 60 + + +########################################### +## Text bundles for UI +########################################### + +# the default index +grouper.text.defaultBundleIndex = 0 + +# language for this bundle +grouper.text.bundle.0.language = en + +# country for this bundle +grouper.text.bundle.0.country = us + +# filename in the package grouperText that is before the .base.properties, and .properties +grouper.text.bundle.0.fileNamePrefix = grouperText/grouper.text.en.us + + +######################################## + +#### Simple Look and feel. Note, the grouper-ui.properties will be checked first, then the media.properties. +#### Generally you will use the media.properties for things which need resource bundles for internationalization or +#### localization. See the grouper-ui.properties for more options + +## How to change logos and CSS + +# You may specify a logo for your organisation and for Grouper. Off-the-shelf +# your organisation logo appears on the left of the header and the Grouper logo +# appears on the right. Typically you would make the logos the same height. +image.organisation-logo=grouperExternal/public/assets/images/organisation-logo.gif +image.grouper-logo=grouperExternal/public/assets/images/grouper.gif + +# A space separated list of one or more .css files which are inserted into the +# HEAD of all Grouper pages. The .css files are referenced in order and after +# any Grouper CSS files. This means that your CSS files can override any +# Grouper style definition +css.additional= + +# You can omit the Grouper CSS files completely by setting grouper-css.hide=true +grouper-css.hide=false + +# Include link to new prototype of a Lite ui on login page +# Set to true if you want to give users access to lite ui +login.ui-lite.show-link=true +login.ui-lite.link=/grouperUi/appHtml/grouper.html?operation=SimpleMembershipUpdate.index + +# Enable links (new window) to lite UI i.e. from GroupSummary page +# Set to true if you want the admin-ui to link to the lite ui (membership management only) +ui-lite.link-from-admin-ui=true +ui.lite.group-link=/grouperUi/appHtml/grouper.html?operation=SimpleMembershipUpdate.init&groupId= + +ui-new.link-from-admin-ui=true +ui.new.group-link=/grouperUi/app/UiV2Main.index?operation=UiV2Group.viewGroup&groupId= + +# if the root ui should be the new ui +ui-root-is-new-ui = true + +#### Miscellaneous UI configuration + +# Specifies whether the error page should include a ticket. The ticket appears +# in the errror log and can be used to filter relevant messages + +#If you want a unique ticket to be displayed on the error page,set error.ticket=true +error.ticket=false + +# Specifies whether Grouper should display a logout link. Not all authentication +# schemes allow logout, including Basic authentication. +# This value can be set in the Grouper UI build.properties file +# Note that Grouper cannot guarantee that +#ending the session will log the user out of your authentication system!!! +#Only set to true if you can genuinely logout. +logout.link.show=true + +# Specifies the maximum length for the subject String that appears in the subheader +# welcome message +welcome.subject.max-length=80 + +#Set this to 'all' to remove all cookies, or set to a comma or space separated list of +#cookie names to delete. Java code will do a Cookie.getName().equals or .matches +#so valid regular expressions may be used +logout.cookies-to-delete=none + +# When creating a group, which access privs will be granted to GrouperAll? +# groups.create.grant.all allows the UI to override the defaults in grouper.properties +# =none if none should be checked in the UI +# If not set, the defaults from the grouper.properties file will be used +# NB in the QuickStart, no privs are automatically assigned - grouper.properties was +# modified so that all 'groups.create.grant.all.' are false, +groups.create.grant.all= + +# If true, on the 'Subject Search' page there will be a link to your 'Subject Summary' +allow.self-subject-summary=true + +# Unless otherwise configured, the UI starts browsing at the ROOTstem. set default.browse.stem +# to start browsing from a different stem. You can override the default browse stem, +# however, you must ensure that the stem exists by creating it using the Grouper API +default.browse.stem= + + +# Grouper has no formal notion of 'personal' stems vs 'institutional' stems, however, setting +# personal.browse.stem, will trim this portio of the hierarchy when a user is browsing in 'All' mode +# TODO members of Wheel group / GrouperSystem should be able to browse regardless. +###personal.browse.stem=uob:personal + +# The UI has a 'Saved Groups' feature intended to make it easier to find groups of interest +# and used when ceating comosite groups. This property, if true, causes any new or updated group +# to be automatically added to your list of saved groups +put.in.session.updated.groups=true + +# The UI has a 'Saved Stems' feature intended to make it easier to find stems of interest +# This property, if true, causes any new or updated stem +# to be automatically added to your list of saved stems +put.in.session.updated.stems=true + +# Turn off the debug functionality (true/false) +# For production turn off (false) or restrict to a group +browser.debug.enable=false + +# If debug is on then restrict to named group. Disable if group does not exist +browser.debug.group= + +# Enables user to specify arbitrary exsecutable as HTML editor on the server +# Do not enable unless you absolutely trust users +browser.debug.group.enable-html-editor=false + +#If you want to save your debug preferences, set debug.prefs.dir to an existing directory +#on you system, where the user Tomcat runs as, has write privilege +debug.prefs.dir=someDir/someWhereMustExist + +#### Membership Import and export +## As of V1.2 the UI provides a framework for allowing users to export membership lists +## to flat files i.e. comma separated files, including in Excel compatible format. It is also +## possible to import simple delimited files. +## Both import and export require configuration and appropriate configuration will vary from +## site to site. For this reason, the UI does not come pre-configued for import/export, however, +## sample files are provided (see [Enabling import / export of group memberships|Customising the Grouper UI#import-export]) + +#membership-export.config=resources/grouper/membership-export.xml +#membership-import.config=resources/grouper/membership-import.xml + +## If the user does not select a file to import allow text to be typed / pasted into textarea +## Since version 1.2.1 +membership-import.allow-textarea=true + +#for large files, give a temp dir so they arent stored in memory or the system temp dir +file.upload.temp.dir= +file.upload.max.bytes= + +#note: if they are in the this group, then they can use the lite ui too +require.group.for.logins= + +#users must be in this group to be able to login to the lite membership update UI (if not in require.group.for.logins) +require.group.for.membershipUpdateLite.logins= + +#users must be in this group to be able to login to the subjectPicker UI (if not in require.group.for.logins or require.group.for.membershipUpdateLite.logins) +require.group.for.subjectPicker.logins= + +#users must be in this group to invite external users to grouper +require.group.for.inviteExternalSubjects.logins= + +#users must be in this group to assign/create/etc attributes in the UI (new attribute framework) (if not in require.group.for.logins) +require.group.for.attributeUpdateLite.logins= + +#### Displaying lists + +# When browsing or searching the UI will present lists of various objects. The following settings +# allow sites to control default page sizes and a list of user-selectable page sizes +pager.pagesize.default=50 +pager.pagesize.selection=10 25 50 100 + +# If we should remove paging from subject search since we cant *really* page through all subjects, +# you would just be paging through the first part of the first page. IF you set this to true +# then you might want to bump up the default pagesize... +pager.removeFromSubjectSearch=false + +# Typically, when browsing it is sufficient to show the extension/displayExtension for a group/stem +# as the parent stems are aleady shown and are common. When searching, however, this context is lost +# so sites can configure which field to display in the context of a search where results may come from +# different locations +search.group.result-field=displayName +search.stem.result-field=displayName + +# By setting the 'result-field-choice' properties, sites can alow users to select which +# field to use for displaying serach resuts +search.group.result-field-choice=displayName displayExtension name +search.stem.result-field-choice=displayName displayExtension name + +# Prior to V1.2 sites could do little to control how subjects, groups or stems were displayed +# in the UI, beyond the display of stem/group search results, unless they created dynamic tiles +# It is now possible to control the display of stems, groups and subjects in different contexts +# In the case of subjects, an attribute can be configured based on the subject's SourceAdapter + +# Provides backwards compatability - it was assumed that all Subjects woud have a 'description' attribute +subject.display.default=description + +# Used for groups when displayed as a subject i.e. when displayed as member of another group +subject.display.g\:gsa=displayExtension + +# Used for groups when displayed as a subject i.e. when displayed as member of another group +subject.display.grouperEntities=displayExtension + +# Used for internal Grouper subjects i.e. GrouperAll and GrouperSystem +subject.display.g\:isa=name + +# Default attribute to display for groups +group.display=displayExtension + +# Attribute to use when browsing and the user has selected to hide the hierarchy - +# thus losing context +group.display.flat=displayName + +# Default attribute for stems +stem.display=displayExtension + +#### Searching + +# Configuration affecting how simple default group/stem searches are carried out + +# Determines if the name or extension field (or neither) are searched +search.default.search-in-name-or-extension= + +# Determines if the display name or display extension (or neither) is searched +search.default.search-in-display-name-or-extension=name + +# On the advanced groups search screen determines how many search fields are displayed +search.max-fields=5 + +# On the advanced groups search screen determines how many group type select lists are displayed +search.max-group-types=3 + +# On the advanced stems search screen determines how many search fields are displayed +search.stems.max-fields=4 + +# Control whether default search can search any attribute. Valid values=only or true or false +search.default.any=false + +# Control default search option +search.default=name + +# Allow filtering of membership lists by subject source +members.filter.by-source=true +members.filter.limit=500 + +# Displays source specific form elements using keys: +# subject.search.form-fragment. +subject.search.form-fragment.g\:gsa=subjectSearchGroupFragmentDef + +#### Sorting +## As of V1.2 the Grouper UI allows sorting of various lists of objects +## See [Sort order of lists|Customising the Grouper UI#sort] for explanation +comparator.impl=edu.internet2.middleware.grouper.ui.DefaultComparatorImpl +comparator.helper.edu.internet2.middleware.grouper.Group=edu.internet2.middleware.grouper.ui.GroupComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.ui.util.GroupAsMap=edu.internet2.middleware.grouper.ui.GroupComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.Stem=edu.internet2.middleware.grouper.ui.StemComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.ui.util.StemAsMap=edu.internet2.middleware.grouper.ui.StemComparatorHelper +comparator.helper.edu.internet2.middleware.subject.Subject=edu.internet2.middleware.grouper.ui.SubjectComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.ui.util.SubjectAsMap=edu.internet2.middleware.grouper.ui.SubjectComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.Member=edu.internet2.middleware.grouper.ui.SubjectComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.Membership=edu.internet2.middleware.grouper.ui.SubjectComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.ui.util.MembershipAsMap=edu.internet2.middleware.grouper.ui.SubjectComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.ui.util.SubjectPrivilegeAsMap=edu.internet2.middleware.grouper.ui.GroupOrStemComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.Composite=edu.internet2.middleware.grouper.ui.ComositeComparatorHelper +comparator.helper.edu.internet2.middleware.grouper.ui.util.CompositeAsMap=edu.internet2.middleware.grouper.ui.CompositeComparatorHelper + + +# Sorting large lists can be computationally expensive - and slow. Use this property to turn off sorting for +# large lists +comparator.sort.limit=200 + +# SubjectSummary page lists full names - so sort on those by default +group.sort.subjectSummary=displayName +stem.sort.subjectSumamry=displayName + +## To control the order in which subject attributes are listed on the Subject Summary page: +# subject.attributes.order.=comma separated list of case sensitive attribute names +subject.attributes.order.g\:gsa=displayExtension,displayName,name,alternateName,extension,createTime,createSubjectId,createSubjectType,modifySubjectId,modifySubjectType,modifyTime,subjectType,id +subject.attributes.order.qsuob=LFNAME,LOGINID,subjectType,id + + +#### Member sorting and searching +# Whether to enable member sorting using sort attributes stored in Grouper. +member.sort.enabled=true + +# Whether to use default sorting only and not allow users to specify which sort attribute to use. +member.sort.defaultOnly=false + +# Whether to enable member searching using search attributes stored in Grouper. +member.search.enabled=true + + +#### Audit query +## Date format likely to be locale dependent + may need to turn on/off +audit.query.enabled=true + +#SimpleDateFormat format strings +audit.query.date-format=MM/dd/yyyy +audit.query.display-date-format=dd MMM yyyy HH:mm:ss + +#If no date specified show results for audit.query.default-since days +audit.query.default-since=7 + + +#### Plugin browse / search +## The UI has a pluggable interface for browsing and searching. See [Customising Browsing and Searching|Customising the Grouper UI#browsing] for explanation + +repository.browser.my.class=edu.internet2.middleware.grouper.ui.MyMembershipsRepositoryBrowser +repository.browser.my.flat-capable=true +repository.browser.my.root-node= +repository.browser.my.hide-pre-root-node=true +repository.browser.my.flat-privs=member +repository.browser.my.flat-type=group +repository.browser.my.search=groups + +repository.browser.create.class=edu.internet2.middleware.grouper.ui.CreateRepositoryBrowser +repository.browser.create.flat-capable=true +repository.browser.create.root-node= +repository.browser.create.hide-pre-root-node=true +repository.browser.create.flat-privs=create stem +repository.browser.create.flat-type=stem +repository.browser.create.search=stems + +repository.browser.manage.class=edu.internet2.middleware.grouper.ui.ManageRepositoryBrowser +repository.browser.manage.flat-capable=true +repository.browser.manage.root-node= +repository.browser.manage.hide-pre-root-node=true +repository.browser.manage.flat-privs=admin update create stem +repository.browser.manage.flat-type=group +repository.browser.manage.search=groups + +repository.browser.join.class=edu.internet2.middleware.grouper.ui.JoinRepositoryBrowser +repository.browser.join.flat-capable=true +repository.browser.join.root-node= +repository.browser.join.hide-pre-root-node=true +repository.browser.join.flat-privs=optin +repository.browser.join.flat-type=group +repository.browser.join.search=groups + +repository.browser.all.class=edu.internet2.middleware.grouper.ui.AllRepositoryBrowser +repository.browser.all.flat-capable=false +repository.browser.all.root-node= +repository.browser.all.hide-pre-root-node=true +repository.browser.all.flat-privs= +repository.browser.all.search=groups + +repository.browser.subjectsearch.class=edu.internet2.middleware.grouper.ui.AllRepositoryBrowser +repository.browser.subjectsearch.flat-capable=true +repository.browser.subjectsearch.root-node= +repository.browser.subjectsearch.hide-pre-root-node=true +repository.browser.subjectsearch.flat-privs= +repository.browser.subjectsearch.search=groups + +repository.browser.savedgroups.class=edu.internet2.middleware.grouper.ui.AllRepositoryBrowser +repository.browser.savedgroups.flat-capable=true +repository.browser.savedgroups.root-node= +repository.browser.savedgroups.hide-pre-root-node=true +repository.browser.savedgroups.flat-privs= +repository.browser.savedgroups.search=groups + +repository.browser.savedsubjects.class=edu.internet2.middleware.grouper.ui.AllRepositoryBrowser +repository.browser.savedsubjects.flat-capable=true +repository.browser.savedsubjects.root-node= +repository.browser.savedsubjects.hide-pre-root-node=true +repository.browser.savedsubjects.flat-privs= +repository.browser.savedsubjects.search=groups + +### Misc + +# give more info about what is not serializable in the session +debugSessionSerialization = false + +#### Infodots +#if the little yellow "i" images that show help should be enabled +infodot.enable=true + +############################# +## Subject settings +############################# + +subject.maxChars = 100 + +# v2 max chars on subject before abbreviated +subject2.maxChars = 40 + +############################# +## Security settings +############################# + +# if you want to have the username in http header, put the head name here, e.g. REMOTE_USER +grouper.ui.authentication.http.header = REMOTE_USER + +############################# +## Membership settings +############################# + +#### Lite UI settings +#can be subjectId, sourceId, name, description, screenLabel, memberId, or attribute name which is single valued +#comma separated. will be sorted by sourceId, then the sort field (recommended to be screenName) +simpleMembershipUpdate.exportAllSubjectFields=sourceId, screenLabel, entityId, name, description +simpleMembershipUpdate.exportAllSortField=screenLabel +simpleMembershipUpdate.groupComboboxResultSize=200 +simpleMembershipUpdate.filterComboMinChars=3 +simpleMembershipUpdate.filterMaxSearchSubjects=1000 +#max subjects in drop down +simpleMembershipUpdate.subjectComboboxResultSize=250 + +#add an extra css to the simple membership update. use relative or absolute urls, comma separated +simpleMembershipUpdate.extraCss = + +#properties file via url to look for text first (before nav.properties) +simpleMembershipUpdate.textFromUrl = + +#directory for skin files, if putting config files on file system and not classpath, then put the files here +simpleMembershipUpdate.confDir = + +#if by default the screen will delete multiple +#(screen is easier to use but takes longer potentially and defaults to false) +simpleMembershipUpdate.defaultDeleteMultiple=false + +#if by default the screen will show the import by file instead of direct textarea input +#this defaults to true which helps with large imports, there might be memory problem with textarea import +simpleMembershipUpdate.defaultImportFile=true + +#if we should allow external URL properties in group attribute: grouperGroupMshipSettingsUrl +simpleMembershipUpdate.allowExternalUrlProperties=true + +#if allowing external text by url, this is the filter to strip invalid html tags. blank for none +simpleMembershipUpdate.externalUrlTextProperties.grouperHtmlFilter = edu.internet2.middleware.grouper.util.GrouperHtmlFilter + +#if the breadcrumb row should show on the screen by default +simpleMembershipUpdate.showBreadcrumbRowByDefault=true + +#if the name row should show on the screen by default +simpleMembershipUpdate.showNameRowByDefault=true + +#if the path row should show on the screen by default +simpleMembershipUpdate.showPathRowByDefault=true + +#if the description row should show on the screen by default +simpleMembershipUpdate.showDescriptionRowByDefault=true + +#if the id row should show on the screen by default +simpleMembershipUpdate.showIdRowByDefault=false + +#if the id path row should show on the screen by default +simpleMembershipUpdate.showIdPathRowByDefault=false + +#if the alternate id path row should show on the screen by default +simpleMembershipUpdate.showAlternateIdPathRowByDefault=false + +#if the uuid row should show on the screen by default +simpleMembershipUpdate.showUuidRowByDefault=false + +#if results must be in a certain group, or blank for no check. e.g. must be in employee group +simpleMembershipUpdate.subjectSearchRequireGroup = + +#if results must be in certain sources, or blank for no check. e.g. must be in the person sources, comma separated +simpleMembershipUpdate.subjectSearchRequireSources = + +# customizer class to customize common things (extend GrouperUiCustomizer) +grouperUiCustomizerClassname = + +# kill all cookies with these prefixes on logout (comma separated) +grouperUi.logout.cookie.prefix = + +# this configures how subjects look in the UI v2.2. This is the short version of the subject +grouperUi.screenLabel2.sourceId.0 = jdbc +grouperUi.screenLabel2.screenEl.0 = ${subject.name} + +grouperUi.screenLabel2.sourceId.1 = g:gsa +grouperUi.screenLabel2.screenEl.1 = ${subject.getAttributeValue('displayExtension')} + +grouperUi.screenLabel2.sourceId.2 = g:rsa +grouperUi.screenLabel2.screenEl.2 = ${subject.getAttributeValue('displayExtension')} + +grouperUi.screenLabel2.sourceId.3 = grouperEntities +grouperUi.screenLabel2.screenEl.3 = ${subject.getAttributeValue('displayExtension')} + + +# this configures how subjects look in the lite UI. This is the short version of the display +# images (must be in assets/images dir) for subject source id +grouperUi.subjectImg.sourceId.0 = pennperson +grouperUi.subjectImg.image.0 = user.png +# screen EL has "subject" as an object +grouperUi.subjectImg.screenEl.0 = ${subject.description} + +grouperUi.subjectImg.sourceId.1 = jdbc +grouperUi.subjectImg.image.1 = user.png +grouperUi.subjectImg.screenEl.1 = ${subject.description} + +grouperUi.subjectImg.sourceId.2 = g:gsa +grouperUi.subjectImg.image.2 = group.png +grouperUi.subjectImg.screenEl.2 = ${subject.getAttributeValue('displayExtension')} +grouperUi.subjectImg.textId.2 = gsa + +grouperUi.subjectImg.sourceId.3 = g:isa +grouperUi.subjectImg.image.3 = application.png +grouperUi.subjectImg.screenEl.3 = +grouperUi.subjectImg.textId.3 = isa + +grouperUi.subjectImg.sourceId.4 = grouperExternal +grouperUi.subjectImg.image.4 = user_red.png +grouperUi.subjectImg.screenEl.4 = ${subject.description} + +#this source doesnt really exist, but it is the image for roles as opposed to groups +grouperUi.subjectImg.sourceId.5 = g:rsa +grouperUi.subjectImg.image.5 = group_key.png +grouperUi.subjectImg.screenEl.5 = ${subject.getAttributeValue('displayExtension')} +grouperUi.subjectImg.textId.5 = rsa + + +#this source doesnt really exist, but it is the image for roles as opposed to groups +grouperUi.subjectImg.sourceId.6 = grouperEntities +grouperUi.subjectImg.image.6 = application.png +grouperUi.subjectImg.screenEl.6 = ${subject.getAttributeValue('displayExtension')} + +# in parts of the UI where there is a long display, this is the long display +grouperUi.subjectImgLong.sourceId.0 = g:gsa +grouperUi.subjectImgLong.image.0 = group.png +grouperUi.subjectImgLong.screenEl.0 = ${subject.getAttributeValue('displayName')} + +grouperUi.subjectImgLong.sourceId.1 = g:rsa +grouperUi.subjectImgLong.image.1 = group_key.png +grouperUi.subjectImgLong.screenEl.1 = ${subject.getAttributeValue('displayName')} + +grouperUi.subjectImgLong.sourceId.2 = grouperEntities +grouperUi.subjectImgLong.image.2 = application.png +grouperUi.subjectImgLong.screenEl.2 = ${subject.getAttributeValue('displayName')} + + + +grouperUi.logHtmlDir = +grouperUi.logHtml = false + +#if comma separated email addresses are here, then errors will trigger emails (ui-lite) +errorMailAddresses = + +################################## +## Subject picker +################################## + +# if putting config files on file system and not classpath, then put the files here +subjectPicker.confDir = c:/temp/subjectPicker + + +## subject picker config defaults + +# if the subject should be sent back to the calling page in javascript object +subjectPicker.defaultSettings.sendSubjectJsonToCallback = true + +#comma separated css urls (relative or absolute) for skinning this subject picker +subjectPicker.defaultSettings.extraCss = + +# when the subject object is sent in Javascript to the caller, which fields or attributes should be sent +subjectPicker.defaultSettings.subjectObject.include.subjectId = true +subjectPicker.defaultSettings.subjectObject.include.sourceId = true +subjectPicker.defaultSettings.subjectObject.include.name = true +subjectPicker.defaultSettings.subjectObject.include.typeName = true +subjectPicker.defaultSettings.subjectObject.include.description = true +#comma separated list of subject attirbutes or INCLUDE_ALL_ATTRIBUTES for all +#subjectObject.include.attributes = loginid,lfname +#subjectObject.include.attributes = INCLUDE_ALL_ATTRIBUTES +subjectPicker.defaultSettings.subjectObject.include.attributes = + +# put sourceIds to search in, or leave blank for all +subjectPicker.defaultSettings.searchInSourceIds = + +## You can configure per source how the subjects appear on screen, and customize per subject picker instance as well +# Increment the index (0, 1, 2, etc) to configure multiple sources +#source id we are configuring +subjectPicker.defaultSettings.sourceProperties.sourceId.0 = +#this is the expression language of how the subject result should appear on screen +subjectPicker.defaultSettings.sourceProperties.subjectElForSource.0 = + +# max results that can be retrieved before the group filter resultsMustBeInGroup is applied +subjectPicker.defaultSettings.maxSubjectsResultsBeforeGroupSearch = 800 + +# max results that can be retrieved +subjectPicker.defaultSettings.maxSubjectsResults = 200 + +#if results must be in group, or blank for no check. e.g. put your active employee group here +subjectPicker.defaultSettings.resultsMustBeInGroup = + +#if the resource is far down the folder structure, you can remove part of it +subjectPicker.defaultSettings.removePrefixOnUi = + +# is an actas should be applied for group operations. Generally this is GrouperSystem, though could be anyone, or blank +# to act as the logged in user +subjectPicker.defaultSettings.actAsSourceId = g:isa +subjectPicker.defaultSettings.actAsSubjectId = GrouperSystem + +# put a URL here where the result (subjectId, sourceId, name, description) will be submitted back +# blank if same domain and just call opener directly +subjectPicker.defaultSettings.submitResultToUrl = + +################################## +## Attribute def name picker +################################## + +# if putting config files on file system and not classpath, then put the files here +attributeDefNamePicker.confDir = + + +## attributeDefName picker config defaults + +#comma separated css urls (relative or absolute) for skinning this attributeDefName picker +attributeDefNamePicker.defaultSettings.extraCss = + +# names of attribute defs where the attribute def names should be searched from +attributeDefNamePicker.defaultSettings.searchInAttributeDefNames = + +## You can configure per source how the attributeDefNames appear on screen, and customize per attributeDefName picker instance as well +#this is the expression language of how the attributeDefName result should appear on screen +attributeDefNamePicker.defaultSettings.attributeDefNameNameEl = + +# max results that can be retrieved +attributeDefNamePicker.defaultSettings.maxAttributeDefNamesResults = 200 + +# is an actas should be applied for group operations. Generally this is GrouperSystem, though could be anyone, or blank +# to act as the logged in user +attributeDefNamePicker.defaultSettings.actAsSourceId = g:isa +attributeDefNamePicker.defaultSettings.actAsSubjectId = GrouperSystem + +# put a URL here where the result (attributeDefNameId, displayName, name, description) will be submitted back +# blank if same domain and just call opener directly +attributeDefNamePicker.defaultSettings.submitResultToUrl = + +################################## +## v2.2 UI index +################################## + +# generally the number of objects in each section +uiV2.index.numberOfObjectsInSectionDefault = 10 + +# number of groups, stems, etc on index page to show for favorites. Note, e.g. if this is 5, show 5 max of each +uiV2.index.maxFavoritesEachType = 5 + +# number of groups, stems, etc on index page to show for recently used. Note, e.g. if this is 5, show 5 max of each +uiV2.index.maxRecentlyUsedEachType = 5 + +# number of millis that widget queries must complete in before they are abandoned and the user must click a link to display it +# -1 means dont run in threads, and just draw the screen no matter how long it takes. 0 means, dont even try to load the widgets, +# let the user do it themselves +uiV2.index.widgetMaxQueryMillis = 5000 + +# if you are testing the widgets, put a sleep there +# max widget millis must elapse before the JSP displays +uiV2.index.test.sleepIn.recentlyUsed.widgetMillis = 0 +uiV2.index.test.sleepIn.myFavorites.widgetMillis = 0 +uiV2.index.test.sleepIn.groupsImanage.widgetMillis = 0 +uiV2.index.test.sleepIn.stemsImanage.widgetMillis = 0 +uiV2.index.test.sleepIn.myMemberships.widgetMillis = 0 +uiV2.index.test.sleepIn.myServices.widgetMillis = 0 + +################################## +## External subjects invitation +################################## + +# if the registration screen is enabled +externalMembers.enabledRegistration = false + +#if admins should be emailed after each action, put comma separated addresses here +externalMembers.emailAdminsAddressesAfterActions = + +#if you want to allow users to delete their record +externalMembers.allowSelfDelete = false + +################################## +## Invite external members +################################## + +inviteExternalMembers.groupComboboxResultSize = 200 + +# if the wheel group is allowed to be invited +inviteExternalMembers.allowWheelInInvite = false + +# if the invitation screen is enabled +inviteExternalMembers.enableInvitation = false + +#if link from admin UI +inviteExternalPeople.link-from-admin-ui = false + +#if link from lite UI +inviteExternalPeople.link-from-lite-ui = false + +#if admins should be emailed after each action, put comma separated addresses here +inviteExternalMembers.emailAdminsAddressesAfterActions = + +#if we should allow invite by identifier +inviteExternalMembers.allowInviteByIdentifier = false + +################################### +## Simple permission update +################################### + +#max size for combobox when filtering attribute defs for permissions +simplePermissionUpdate.attributeDefComboboxResultSize = 200 + +#max size for combobox when filtering permission resources +simplePermissionUpdate.permissionResourceComboboxResultSize = 200 + +#max users in combobox when filtering +simplePermissionUpdate.subjectComboboxResultSize = 50 + +#number of rows to repeat headers on permissions screen +simplePermissionUpdate.repeatPermissionHeaderAfterRows = 20 + +#max chars in subject listing in permissions screen +simplePermissionUpdate.maxOwnerSubjectChars = 50 + +#if we shouldnt have groups in the subject results +simplePermissionUpdate.allowGroupsInSubjectResults = false + +################################### +## Simple attribute update +################################### + +#max size for combobox when filtering attribute defs to edit +simpleAttributeUpdate.attributeDefComboboxResultSize = 200 + +#repeat the header of which privilege is which every X rows +simpleAttributeUpdate.repeatPrivilegeHeaderAfterRows = 20 + +#max size for combobox when filtering privilege users to add +simpleAttributeUpdate.attributeDefPrivilegeUserComboboxResultSize = 200 + +#max size for combobox for search for members in assignment +simpleAttributeUpdate.memberComboboxResultSize = 200 + +#when showing assignments, this is the max number of chars before ellipses, -1 for no ellipses +simpleAttributeUpdate.maxOwnerSubjectChars = 50 + +################################### +## Simple attribute name +################################### + +#max size for combobox when filtering attribute def names to edit +simpleAttributeNameUpdate.attributeDefNameComboboxResultSize = 200 + +################################### +## Groups +################################### + +#max size for combobox when filtering groups to edit +simpleGroupUpdate.groupComboboxResultSize = 200 + +#max size for entity drop down in group privilege screen +simpleGroupUpdate.groupPrivilegeUserComboboxResultSize = 200 + +################################### +## Directed graphs +################################### + +directedGraph.width = 1000 +directedGraph.height = 600 + +################################### +## Internationalization +################################### + +# this should be false, and make sure URIEncoding is set to UTF-8 in the tomcat connector +# + + + + + + + + Grouper service filter + edu.internet2.middleware.grouper.ws.GrouperServiceJ2ee + + + + + Grouper logging filter + edu.internet2.middleware.grouper.ws.j2ee.ServletFilterLogger + + + + + + Grouper service filter + /services/* + + + Grouper service filter + /servicesRest/* + + + AxisServlet + Apache-Axis Servlet + edu.internet2.middleware.grouper.ws.GrouperServiceAxisServlet + 1 + + + + + RestServlet + WS REST Servlet + edu.internet2.middleware.grouper.ws.rest.GrouperRestServlet + 1 + + + StatusServlet + Status Servlet + edu.internet2.middleware.grouper.j2ee.status.GrouperStatusServlet + 1 + + + StatusServlet + /status + + + AxisServlet + /services/* + + + RestServlet + /servicesRest/* + + + + + Web services + /services/* + + + * + + + + + + Web services + /servicesRest/* + + + + * + + + + + + BASIC + Grouper Application + + + + + + The role that is required to log in to web service + + * + + + + 1 + + + diff --git a/grouper/opt/patch-scripts/grouper.installer-api.properties b/grouper/opt/patch-scripts/grouper.installer-api.properties new file mode 100644 index 0000000..442fc7f --- /dev/null +++ b/grouper/opt/patch-scripts/grouper.installer-api.properties @@ -0,0 +1,9 @@ +grouperInstaller.autorun.useDefaultsAsMuchAsAvailable = true +grouperInstaller.autorun.actionEgInstallUpgradePatch = patch +grouperInstaller.autorun.tarballDirectory = /tmp/grp-api +grouperInstaller.autorun.appToUpgrade = api +grouperInstaller.autorun.grouperWhereInstalled = /opt/grouper.apiBinary-2.3.0 +grouperInstaller.autorun.patchAction = install +grouperInstaller.autorun.installPspng = t +grouper.version = 2.3.0 +download.server.url = http://software.internet2.edu/grouper diff --git a/grouper/opt/patch-scripts/grouper.installer-psp.properties b/grouper/opt/patch-scripts/grouper.installer-psp.properties new file mode 100644 index 0000000..17dc90e --- /dev/null +++ b/grouper/opt/patch-scripts/grouper.installer-psp.properties @@ -0,0 +1,8 @@ +grouperInstaller.autorun.useDefaultsAsMuchAsAvailable = true +grouperInstaller.autorun.actionEgInstallUpgradePatch = patch +grouperInstaller.autorun.tarballDirectory = /tmp/grp-psp +grouperInstaller.autorun.appToUpgrade = psp +grouperInstaller.autorun.grouperWhereInstalled = /opt/grouper.apiBinary-2.3.0/ +grouperInstaller.autorun.patchAction = install +grouper.version = 2.3.0 +download.server.url = http://software.internet2.edu/grouper diff --git a/grouper/opt/patch-scripts/grouper.installer-pspng.properties b/grouper/opt/patch-scripts/grouper.installer-pspng.properties new file mode 100644 index 0000000..af83fa8 --- /dev/null +++ b/grouper/opt/patch-scripts/grouper.installer-pspng.properties @@ -0,0 +1,8 @@ +grouperInstaller.autorun.useDefaultsAsMuchAsAvailable = true +grouperInstaller.autorun.actionEgInstallUpgradePatch = patch +grouperInstaller.autorun.tarballDirectory = /tmp/grp-pspng +grouperInstaller.autorun.appToUpgrade = pspng +grouperInstaller.autorun.grouperWhereInstalled = /opt/grouper.apiBinary-2.3.0/ +grouperInstaller.autorun.patchAction = install +grouper.version = 2.3.0 +download.server.url = http://software.internet2.edu/grouper diff --git a/grouper/opt/patch-scripts/grouper.installer-ui.properties b/grouper/opt/patch-scripts/grouper.installer-ui.properties new file mode 100644 index 0000000..00d6131 --- /dev/null +++ b/grouper/opt/patch-scripts/grouper.installer-ui.properties @@ -0,0 +1,8 @@ +grouperInstaller.autorun.useDefaultsAsMuchAsAvailable = true +grouperInstaller.autorun.actionEgInstallUpgradePatch = patch +grouperInstaller.autorun.tarballDirectory = /tmp/grp-ui +grouperInstaller.autorun.appToUpgrade = ui +grouperInstaller.autorun.grouperWhereInstalled = /opt/webapps/grouper/ +grouperInstaller.autorun.patchAction = install +grouper.version = 2.3.0 +download.server.url = http://software.internet2.edu/grouper diff --git a/grouper/opt/patch-scripts/grouper.installer-ws.properties b/grouper/opt/patch-scripts/grouper.installer-ws.properties new file mode 100644 index 0000000..ce1060c --- /dev/null +++ b/grouper/opt/patch-scripts/grouper.installer-ws.properties @@ -0,0 +1,8 @@ +grouperInstaller.autorun.useDefaultsAsMuchAsAvailable = true +grouperInstaller.autorun.actionEgInstallUpgradePatch = patch +grouperInstaller.autorun.tarballDirectory = /tmp/grp-ws +grouperInstaller.autorun.appToUpgrade = ws +grouperInstaller.autorun.grouperWhereInstalled = /opt/webapps/grouper-ws/ +grouperInstaller.autorun.patchAction = install +grouper.version = 2.3.0 +download.server.url = http://software.internet2.edu/grouper diff --git a/grouper/run-grouper.sh b/grouper/run-grouper.sh new file mode 100755 index 0000000..c6cb157 --- /dev/null +++ b/grouper/run-grouper.sh @@ -0,0 +1,48 @@ +#!/bin/sh +set -x + +# Is LDAP available? +until nc -vz tier-demo-ldap 389 +do + echo "LDAP is unavailable - sleeping" + sleep 1 +done +echo "LDAP is up!" + +# Is MySQL available? +until nc -vz tier-demo-mysql 3306 +do + echo "MySQL is unavailable - sleeping" + sleep 1 +done +echo "MySQL is up!" + +# probably should test functionality instead of just whether the port is accepting connections... + +# Is this the containers first run? +# if so...bootstrap it. +# TODO: determine what happens if mysql container is not on its first run. +if [ -e /FIRSTRUN ] +then + cd /opt/grouper.apiBinary-$GROUPER_VERSION \ + && bin/gsh -registry -check -runscript -noprompt \ + && bin/gsh /opt/bootstrap/bootstrap.gsh \ + && rm -fv /FIRSTRUN +fi + +# Do not start if we did not bootstrap +if [ ! -f /FIRSTRUN ] +then + + # TODO: start these with supervisord? + rm -rf /opt/apache-tomcat-$tomcat_version/work/* + + /opt/apache-tomcat-$tomcat_version/bin/startup.sh + + cd /opt/grouper.apiBinary-2.3.0/ + bin/gsh -loader & + + tail -f /opt/grouper.apiBinary-2.3.0/logs/grouper_error.log +else + echo "Bootstrap was not completed. Not starting..." +fi diff --git a/grouper/seed-data/bootstrap.gsh b/grouper/seed-data/bootstrap.gsh new file mode 100644 index 0000000..0208576 --- /dev/null +++ b/grouper/seed-data/bootstrap.gsh @@ -0,0 +1,195 @@ +gs = GrouperSession.startRootSession() + +addMember("etc:sysadmingroup","tjordan"); + +# t1j - add GDG root stems +addRootStem("basis","basis"); +addRootStem("ref","ref"); +addRootStem("bundle","bundle"); +addRootStem("app","app"); +addRootStem("org","org"); +addRootStem("test","test") + +# t1j - move these to etc +#addRootStem("psp","psp"); +#addRootStem("loader","loader"); +addStem("etc","psp","psp"); +addStem("etc","loader","loader"); + + +# Create attributes for restricting isMemberOf by entityID +addStem("etc:attribute","ShibEntityId","ShibEntityId"); +attrStem = StemFinder.findByName(gs, "etc:attribute:ShibEntityId"); +shibAttrDef = attrStem.addChildAttributeDef("ShibEntityIdDefn", AttributeDefType.attr); +shibAttrDef.setValueType(AttributeDefValueType.string); +shibAttrDef.setAssignToGroup(true); +shibAttrDef.setMultiValued(true); +shibAttrDef.store(); +shibAttr = attrStem.addChildAttributeDefName(shibAttrDef, "ShibEntityId", "ShibEntityId"); + + +addGroup("etc:loader","allUsers", "All Users"); + +groupAddType("etc:loader:allUsers", "grouperLoader"); +setGroupAttr("etc:loader:allUsers", "grouperLoaderDbName", "grouper"); +setGroupAttr("etc:loader:allUsers", "grouperLoaderType", "SQL_SIMPLE"); +setGroupAttr("etc:loader:allUsers", "grouperLoaderScheduleType", "CRON"); +setGroupAttr("etc:loader:allUsers", "grouperLoaderQuartzCron", "*/10 * * * * ?"); +setGroupAttr("etc:loader:allUsers", "grouperLoaderQuery", "select distinct uid as SUBJECT_ID from myapp_development.users"); + +addStem("basis","courses","courses"); + +addGroup("etc:loader","coursesLoader", "Course Loader"); +groupAddType("etc:loader:coursesLoader", "grouperLoader"); +setGroupAttr("etc:loader:coursesLoader", "grouperLoaderDbName", "grouper"); +setGroupAttr("etc:loader:coursesLoader", "grouperLoaderType", "SQL_GROUP_LIST"); +setGroupAttr("etc:loader:coursesLoader", "grouperLoaderScheduleType", "CRON"); +setGroupAttr("etc:loader:coursesLoader", "grouperLoaderQuartzCron", "*/10 * * * * ?"); +# t1j - try adding courses under ref +setGroupAttr("etc:loader:coursesLoader", "grouperLoaderQuery", "select distinct uid as SUBJECT_ID, CONCAT('basis:courses:', course_number) as GROUP_NAME from myapp_development.courses_users, myapp_development.courses, myapp_development.users where courses_users.course_id = courses.id and courses_users.user_id = users.id"); +# this handles removing members from groups that fall out of population from query above. +setGroupAttr("etc:loader:coursesLoader", "grouperLoaderGroupsLike", "basis:courses:%"); +# t1j - move affiliations under ref +#addRootStem("affiliations","affiliations"); +addStem("ref","affiliations","affiliations"); + +folder = StemFinder.findByName(gs, "ref:affiliations"); +AttributeAssign attributeAssign = folder.getAttributeDelegate().addAttribute(RuleUtils.ruleAttributeDefName()).getAttributeAssign(); +AttributeValueDelegate attributeValueDelegate = attributeAssign.getAttributeValueDelegate(); +attributeValueDelegate.assignValue(RuleUtils.ruleActAsSubjectSourceIdName(), "g:isa"); +attributeValueDelegate.assignValue(RuleUtils.ruleActAsSubjectIdName(), "GrouperSystem"); +attributeValueDelegate.assignValue(RuleUtils.ruleCheckTypeName(), RuleCheckType.groupCreate.name()); +attributeValueDelegate.assignValue(RuleUtils.ruleCheckStemScopeName(), Stem.Scope.SUB.name()); +attributeValueDelegate.assignValue(RuleUtils.ruleThenElName(),"${ruleElUtils.assignGroupPrivilege(groupId, 'g:gsa', groupId, null, 'read')}"); + +###LDAP###group = new GroupSave(gs).assignName("etc:loader:affiliationLoader").assignCreateParentStemsIfNotExist(true).save(); +###LDAP###group.getAttributeDelegate().assignAttribute(LoaderLdapUtils.grouperLoaderLdapAttributeDefName()).getAttributeAssign(); +###LDAP###attributeAssign = group.getAttributeDelegate().retrieveAssignment(null, LoaderLdapUtils.grouperLoaderLdapAttributeDefName(), false, true); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapQuartzCronName(), "*/15 * * * * ?"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapTypeName(), "LDAP_GROUPS_FROM_ATTRIBUTES"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapServerIdName(), "demo"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapFilterName(), "(eduPersonAffiliation=*)"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSearchDnName(), "ou=People"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectAttributeName(), "uid"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapGroupAttributeName(), "eduPersonAffiliation"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectIdTypeName(), "subjectId"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapSubjectExpressionName(), "${subjectAttributes['subjectId']}"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapGroupNameExpressionName(), "ref:affiliations:${groupAttribute}_systemOfRecord"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapGroupDisplayNameExpressionName(), "${groupAttribute} system of record"); +###LDAP###attributeAssign.getAttributeValueDelegate().assignValue(LoaderLdapUtils.grouperLoaderLdapGroupTypesName(), "addIncludeExclude"); + +# Roll Up Groups +addGroup("ref","cs_students","CS Students"); +groupAddType("ref:cs_students", "grouperLoader"); +setGroupAttr("ref:cs_students", "grouperLoaderDbName", "grouper"); +setGroupAttr("ref:cs_students", "grouperLoaderType", "SQL_SIMPLE"); +setGroupAttr("ref:cs_students", "grouperLoaderScheduleType", "CRON"); +setGroupAttr("ref:cs_students", "grouperLoaderQuartzCron", "*/10 * * * * ?"); +setGroupAttr("ref:cs_students", "grouperLoaderQuery", "SELECT DISTINCT GROUP_ID AS SUBJECT_ID FROM grouper_groups_v WHERE NAME LIKE 'basis:courses:CS%'"); + +addGroup("ref","acct_students","Accounting Students"); +groupAddType("ref:acct_students", "grouperLoader"); +setGroupAttr("ref:acct_students", "grouperLoaderDbName", "grouper"); +setGroupAttr("ref:acct_students", "grouperLoaderType", "SQL_SIMPLE"); +setGroupAttr("ref:acct_students", "grouperLoaderScheduleType", "CRON"); +setGroupAttr("ref:acct_students", "grouperLoaderQuartzCron", "*/10 * * * * ?"); +setGroupAttr("ref:acct_students", "grouperLoaderQuery", "SELECT DISTINCT GROUP_ID AS SUBJECT_ID FROM grouper_groups_v WHERE NAME LIKE 'basis:courses:ACCT%'"); + +addGroup("ref","math_students","Math Students"); +groupAddType("ref:math_students", "grouperLoader"); +setGroupAttr("ref:math_students", "grouperLoaderDbName", "grouper"); +setGroupAttr("ref:math_students", "grouperLoaderType", "SQL_SIMPLE"); +setGroupAttr("ref:math_students", "grouperLoaderScheduleType", "CRON"); +setGroupAttr("ref:math_students", "grouperLoaderQuartzCron", "*/10 * * * * ?"); +setGroupAttr("ref:math_students", "grouperLoaderQuery", "SELECT DISTINCT GROUP_ID AS SUBJECT_ID FROM grouper_groups_v WHERE NAME LIKE 'basis:courses:MATH%'"); + +addGroup("ref","tier_students","TIER Department Students"); +groupAddType("ref:tier_students", "grouperLoader"); +setGroupAttr("ref:tier_students", "grouperLoaderDbName", "grouper"); +setGroupAttr("ref:tier_students", "grouperLoaderType", "SQL_SIMPLE"); +setGroupAttr("ref:tier_students", "grouperLoaderScheduleType", "CRON"); +setGroupAttr("ref:tier_students", "grouperLoaderQuartzCron", "*/10 * * * * ?"); +setGroupAttr("ref:tier_students", "grouperLoaderQuery", "SELECT DISTINCT GROUP_ID AS SUBJECT_ID FROM grouper_groups_v WHERE NAME LIKE 'basis:courses:TIER%'"); + +# Course References Groups +# The mapping of basis to reference groups is 1 to 1 for courses...e.g. basis:TIER101 is a member of ref:courses:TIER101 +# We could scale this to be something more sophisticated such as if your basis groups contained additional information like +# TIER101|STUDENT, TIER101|TA +addStem("ref","courses","courses"); +addGroup("etc:loader","referenceCoursesLoader", "Reference Group Course Loader"); +groupAddType("etc:loader:referenceCoursesLoader", "grouperLoader"); +setGroupAttr("etc:loader:referenceCoursesLoader", "grouperLoaderDbName", "grouper"); +setGroupAttr("etc:loader:referenceCoursesLoader", "grouperLoaderType", "SQL_GROUP_LIST"); +setGroupAttr("etc:loader:referenceCoursesLoader", "grouperLoaderScheduleType", "CRON"); +setGroupAttr("etc:loader:referenceCoursesLoader", "grouperLoaderQuartzCron", "*/10 * * * * ?"); +setGroupAttr("etc:loader:referenceCoursesLoader", "grouperLoaderQuery", "select distinct group_id as SUBJECT_ID, CONCAT('ref:courses:', extension) as GROUP_NAME from grouper_groups_v where name like 'basis:courses:%'"); +# this handles removing members from groups that fall out of population from query above. +setGroupAttr("etc:loader:referenceCoursesLoader", "grouperLoaderGroupsLike", "ref:courses:%"); + + +# The "All Students" bundle +addGroup("bundle","all_students","All Students"); +addMember("bundle:all_students","ref:cs_students"); +addMember("bundle:all_students","ref:acct_students"); +addMember("bundle:all_students","ref:math_students"); +addMember("bundle:all_students","ref:tier_students"); + +# Canvas Users +# Canvas is only open to CS students +addStem("app","canvas","canvas"); +# We are building app:canvas:users -> ((app:canvas:adhoc + ref:CS Students) -> app:canvas:users_allow) - app:canvas:users_deny +addGroup("app:canvas", "users", "Users"); +addGroup("app:canvas", "users_allow", "Allowed Users"); +addGroup("app:canvas", "adhoc", "AdHoc Users"); +addGroup("app:canvas", "users_deny", "Denied Users"); +# tjordan (the IT admin) has himself in the ad-hoc group so he can test canvas +addMember("app:canvas:adhoc","tjordan"); +# users_allow is made up of all CS students +addMember("app:canvas:users_allow", "ref:cs_students"); +addMember("app:canvas:users_allow", "app:canvas:adhoc"); +# users_deny is a hand tailored list right now of naughty users. No one banned in the demo +# addMember("app:canvas:users_deny", "naughty user here"); +# Build the composite out: +addComposite("app:canvas:users", CompositeType.COMPLEMENT, "app:canvas:users_allow", "app:canvas:users_deny"); +# Couple classes that will be provisioned to canvas. Driven by basis groups +# They will also use the users_deny group. +addGroup("app:canvas","class_cs101", "CS101 Class"); +addComposite("app:canvas:class_cs101", CompositeType.COMPLEMENT, "basis:courses:CS101", "app:canvas:users_deny"); +addGroup("app:canvas","class_cs102", "CS102 Class"); +addComposite("app:canvas:class_cs102", CompositeType.COMPLEMENT, "basis:courses:CS102", "app:canvas:users_deny"); + +# "Portal" users +addStem("app","portal","portal"); +# Canvas is open to all students BUT Math students. The Portal team thinks Math students should not use the portal +# We are building: app:portal:users -> ((app:portal:adhoc + bundle:All Students) -> app:portal:users_allow - app:portal:users_deny +addGroup("app:portal", "users", "Users"); +addGroup("app:portal", "users_allow", "Allowed Users"); +addGroup("app:portal", "adhoc", "AdHoc Users"); +addGroup("app:portal", "users_deny", "Denied Users"); +# tjordan (the IT admin) has himself in the ad-hoc group so he can test the portal +addMember("app:portal:adhoc","tjordan"); +# users_allow is made up of all CS students +addMember("app:portal:users_allow", "bundle:all_students"); +addMember("app:portal:users_allow", "app:portal:adhoc"); +# users_deny is all the math students +addMember("app:portal:users_deny", "ref:math_students"); +# Build the composite out: +addComposite("app:portal:users", CompositeType.COMPLEMENT, "app:portal:users_allow", "app:portal:users_deny"); + +# "SIS" users +# nothing data driven about this. Only Tom Jordan can do anything +addStem("app","sis","sis"); +addGroup("app:sis","users","Users"); +addMember("app:sis:users","tjordan"); + + +# Grouper users +# Grouper users is a hand maintained list. Nothing data driven about it. +# An IT Admin, a random student, and the grouper wheel group +addStem("app","grouper","grouper"); +addGroup("app:grouper", "users", "users"); +addMember("app:grouper:users","tjordan"); +addMember("app:grouper:users","jbabb"); +addMember("app:grouper:users","etc:sysadmingroup"); + + diff --git a/grouper/seed-data/pspng.gsh b/grouper/seed-data/pspng.gsh new file mode 100644 index 0000000..d213738 --- /dev/null +++ b/grouper/seed-data/pspng.gsh @@ -0,0 +1,78 @@ +exit; + +GrouperSession grouperSession = GrouperSession.startRootSession(); +long gshTotalObjectCount = 0L; +long gshTotalChangeCount = 0L; +long gshTotalErrorCount = 0L; +#StemSave stemSave = new StemSave(grouperSession).assignName("etc:pspng").assignCreateParentStemsIfNotExist(true).assignDescription("Location for pspng-management objects.").assignDisplayName("etc:pspng"); +#stem = stemSave.save(); +#gshTotalObjectCount++; +#if (stemSave.getSaveResultType() != SaveResultType.NO_CHANGE) { System.out.println("Made change for stem: " + stem.getName()); gshTotalChangeCount++;} +System.out.println(new Date() + " Done with folders, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +System.out.println(new Date() + " Done with groups, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +System.out.println(new Date() + " Done with composites, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +AttributeDefSave attributeDefSave = new AttributeDefSave(grouperSession).assignName("etc:pspng:do_not_provision_to_def").assignCreateParentStemsIfNotExist(true).assignToGroup(true).assignToStem(true).assignAttributeDefType(AttributeDefType.type).assignMultiAssignable(true).assignMultiValued(true).assignValueType(AttributeDefValueType.string); +AttributeDef attributeDef = attributeDefSave.save(); +gshTotalObjectCount++; +if (attributeDefSave.getSaveResultType() != SaveResultType.NO_CHANGE) {System.out.println("Made change for attributeDef: " + attributeDef.getName()); gshTotalChangeCount++;} +AttributeDefSave attributeDefSave = new AttributeDefSave(grouperSession).assignName("etc:pspng:provision_to_def").assignCreateParentStemsIfNotExist(true).assignToGroup(true).assignToStem(true).assignAttributeDefType(AttributeDefType.type).assignMultiAssignable(true).assignMultiValued(true).assignValueType(AttributeDefValueType.string); +AttributeDef attributeDef = attributeDefSave.save(); +gshTotalObjectCount++; +if (attributeDefSave.getSaveResultType() != SaveResultType.NO_CHANGE) {System.out.println("Made change for attributeDef: " + attributeDef.getName()); gshTotalChangeCount++;} +System.out.println(new Date() + " Done with attribute definitions, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +System.out.println(new Date() + " Done with role hierarchies, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +attributeDef = AttributeDefFinder.findByName("etc:pspng:do_not_provision_to_def", false); +if (attributeDef != null) { int changeCount = attributeDef.getAttributeDefActionDelegate().configureActionList("assign"); gshTotalObjectCount+=1; if (changeCount > 0) { gshTotalChangeCount+=changeCount; System.out.println("Made " + changeCount + " changes for actionList of attributeDef: etc:pspng:do_not_provision_to_def"); } } else { gshTotalErrorCount++; System.out.println("ERROR: cant find attributeDef: 'etc:pspng:do_not_provision_to_def'"); } +attributeDef = AttributeDefFinder.findByName("etc:pspng:provision_to_def", false); +if (attributeDef != null) { int changeCount = attributeDef.getAttributeDefActionDelegate().configureActionList("assign"); gshTotalObjectCount+=1; if (changeCount > 0) { gshTotalChangeCount+=changeCount; System.out.println("Made " + changeCount + " changes for actionList of attributeDef: etc:pspng:provision_to_def"); } } else { gshTotalErrorCount++; System.out.println("ERROR: cant find attributeDef: 'etc:pspng:provision_to_def'"); } +System.out.println(new Date() + " Done with attribute actions, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +System.out.println(new Date() + " Done with attribute action hierarchies, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +Subject subject = SubjectFinder.findByIdAndSource("GrouperSystem", "g:isa", false); +if (subject == null) { gshTotalErrorCount++; System.out.println("Error: cant find subject: g:isa: GrouperSystem"); } +Privilege privilege = Privilege.listToPriv("stemAdmins", false); +Stem stem = StemFinder.findByName(grouperSession, "etc:pspng", false); +if (privilege != null) { if (subject != null) { if (stem != null) { boolean changed = stem.grantPriv(subject, privilege, false); gshTotalObjectCount++; if (changed) { gshTotalChangeCount++; System.out.println("Made change for stem privilege: " + stem.getName() + ", privilege: " + privilege + ", subject: " + GrouperUtil.subjectToString(subject)); } } else { gshTotalErrorCount++; System.out.println("ERROR: cant find stem: 'etc:pspng'"); } } } +System.out.println(new Date() + " Done with memberships and privileges, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +AttributeDef attributeDef = AttributeDefFinder.findByName("etc:pspng:do_not_provision_to_def", false); +if (attributeDef != null) { AttributeDefNameSave attributeDefNameSave = new AttributeDefNameSave(grouperSession, attributeDef).assignName("etc:pspng:do_not_provision_to").assignCreateParentStemsIfNotExist(true).assignDescription("Defines what provisioners should not process a group or groups within a folder. Since the default is already for provisioners to not provision any groups, this attribute is to override a provision_to attribute set on an ancestor folder. ").assignDisplayName("etc:pspng:do_not_provision_to"); AttributeDefName attributeDefName = attributeDefNameSave.save(); gshTotalObjectCount++; if (attributeDefNameSave.getSaveResultType() != SaveResultType.NO_CHANGE) {gshTotalChangeCount++; System.out.println("Made change for attributeDefName: " + attributeDefName.getName()); } } else { gshTotalErrorCount++; System.out.println("ERROR: cant find attributeDef: 'etc:pspng:do_not_provision_to_def'"); } +AttributeDef attributeDef = AttributeDefFinder.findByName("etc:pspng:provision_to_def", false); +if (attributeDef != null) { AttributeDefNameSave attributeDefNameSave = new AttributeDefNameSave(grouperSession, attributeDef).assignName("etc:pspng:provision_to").assignCreateParentStemsIfNotExist(true).assignDescription("Defines what provisioners should process a group or groups within a folder").assignDisplayName("etc:pspng:provision_to"); AttributeDefName attributeDefName = attributeDefNameSave.save(); gshTotalObjectCount++; if (attributeDefNameSave.getSaveResultType() != SaveResultType.NO_CHANGE) {gshTotalChangeCount++; System.out.println("Made change for attributeDefName: " + attributeDefName.getName()); } } else { gshTotalErrorCount++; System.out.println("ERROR: cant find attributeDef: 'etc:pspng:provision_to_def'"); } +System.out.println(new Date() + " Done with attribute names, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +System.out.println(new Date() + " Done with attribute name hierarchies, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +System.out.println(new Date() + " Done with attribute definition scopes, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +Set attributeAssignIdsAlreadyUsed = new HashSet(); +System.out.println(new Date() + " Script complete: total objects, objects: " + gshTotalObjectCount + ", expected approx total: 8, changes: " + gshTotalChangeCount + ", known errors (view output for full list): " + gshTotalErrorCount); +# t1j - now assign those attributes to the basis:courses and ref:affiliations +# group in order to have them provisioned by the groupOfUniqueNames provisioner +affilStem = StemFinder.findByName(grouperSession, "ref:affiliations", true); +affilProvisionTo = AttributeDefNameFinder.findByName("etc:pspng:provision_to", true); +affilStem.getAttributeDelegate().addAttribute(affilProvisionTo); +affilStem.getAttributeValueDelegate().addValue("etc:pspng:provision_to", "pspng_groupOfUniqueNames"); +affilStem.getAttributeValueDelegate().addValue("etc:pspng:provision_to", "pspng_attributes"); +affilStem.getAttributeValueDelegate().addValue("etc:pspng:provision_to", "pspng_memberof"); +# basis:courses folder? +affilStem = StemFinder.findByName(grouperSession, "basis:courses", true); +affilProvisionTo = AttributeDefNameFinder.findByName("etc:pspng:provision_to", true); +affilStem.getAttributeDelegate().addAttribute(affilProvisionTo); +affilStem.getAttributeValueDelegate().addValue("etc:pspng:provision_to", "pspng_memberof"); + +# app tree. Each app folder needs to it set. +# You could also do this just on app:canvas:users group for example. +# but this opens the opportunity to demostrate some filtering stuff in shibboleth +# Canvas: +affilStem = StemFinder.findByName(grouperSession, "app:canvas", true); +affilProvisionTo = AttributeDefNameFinder.findByName("etc:pspng:provision_to", true); +affilStem.getAttributeDelegate().addAttribute(affilProvisionTo); +affilStem.getAttributeValueDelegate().addValue("etc:pspng:provision_to", "pspng_memberof"); +# TomJordanPoint Provisioning Engine uses LDAP groups (not memberof) to drive provisioning out to canvas +affilStem.getAttributeValueDelegate().addValue("etc:pspng:provision_to", "pspng_groupOfUniqueNames"); +# Portal: +affilStem = StemFinder.findByName(grouperSession, "app:portal", true); +affilProvisionTo = AttributeDefNameFinder.findByName("etc:pspng:provision_to", true); +affilStem.getAttributeDelegate().addAttribute(affilProvisionTo); +affilStem.getAttributeValueDelegate().addValue("etc:pspng:provision_to", "pspng_memberof"); +# Grouper: +affilStem = StemFinder.findByName(grouperSession, "app:grouper", true); +affilProvisionTo = AttributeDefNameFinder.findByName("etc:pspng:provision_to", true); +affilStem.getAttributeDelegate().addAttribute(affilProvisionTo); +affilStem.getAttributeValueDelegate().addValue("etc:pspng:provision_to", "pspng_memberof"); diff --git a/midpoint/Dockerfile b/midpoint/Dockerfile new file mode 100644 index 0000000..25a5ff8 --- /dev/null +++ b/midpoint/Dockerfile @@ -0,0 +1,30 @@ +FROM centos:7 + +RUN yum -y update; yum clean all; +RUN yum -y install epel-release; yum clean all + +RUN yum -y install \ + java-1.8.0-openjdk-headless \ + tomcat \ + unzip + +RUN curl -k https://evolveum.com/downloads/midpoint/3.6/midpoint-3.6-dist.tar.gz -o midpoint-3.6-dist.tar.gz + +RUN tar -xvf midpoint-3.6-dist.tar.gz -C /opt/ + +RUN cp /opt/midpoint-3.6/war/midpoint.war /var/lib/tomcat/webapps/ + +ENV MIDPOINT_HOME=/var/lib/midpoint +RUN mkdir /var/lib/midpoint + +COPY keystore.jceks /var/lib/midpoint/keystore.jceks +COPY config.xml /var/lib/midpoint/config.xml +COPY server.xml /etc/tomcat/server.xml +COPY keystore /root/.keystore + +ENV JAVA_OPTS="-Dmidpoint.home=$MIDPOINT_HOME -Djavax.net.ssl.trustStore=$MIDPOINT_HOME/keystore.jceks -Djavax.net.ssl.trustStoreType=jceks -server -Xms512m -Xmx2048m" + +EXPOSE 8080 +EXPOSE 8443 + +CMD ["usr/libexec/tomcat/server", "start"] diff --git a/midpoint/config.xml b/midpoint/config.xml new file mode 100644 index 0000000..eee7414 --- /dev/null +++ b/midpoint/config.xml @@ -0,0 +1,62 @@ + + + + + + ${midpoint.home}/import + + + com.evolveum.midpoint.repo.sql.SqlRepositoryFactory + ${midpoint.home} + true + + + + com.evolveum.midpoint.audit.impl.LoggerAuditServiceFactory + + + com.evolveum.midpoint.repo.sql.SqlAuditServiceFactory + + + + true + ${midpoint.home}/icf-connectors + + + ${midpoint.home}/keystore.jceks + changeit + strong + http://www.w3.org/2001/04/xmlenc#aes256-cbc + + + + + diff --git a/midpoint/configs/tier-demo-groups-grouperMemberOf.xml b/midpoint/configs/tier-demo-groups-grouperMemberOf.xml new file mode 100644 index 0000000..7ebbe28 --- /dev/null +++ b/midpoint/configs/tier-demo-groups-grouperMemberOf.xml @@ -0,0 +1,333 @@ + + + + tier-demo-grouperMemberOf + + + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + 389 + tier-demo-ldap + dc=example,dc=edu + cn=admin,dc=example,dc=edu + password + never + auto + SSHA + uid + 2.5.13.3 + memberOf + + createTimestamp + + + false + false + false + + + + + + + ri:inetOrgPerson + ri:groupOfUniqueNames + ri:groupOfNames + ri:organizationalUnit + ri:eduPerson + + + + + + account + default + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + mr:distinguishedName + + + $user/name + + + + + + + + ri:entryUUID + Entry UUID + mr:stringIgnoreCase + + + ri:cn + Common Name + + 1 + + + + fullName + + + + + fullName + + + + + ri:sn + Surname + + + familyName + + + + + familyName + + + + + ri:givenName + Given Name + + + givenName + + + + + givenName + + + + + ri:uid + Login Name + mr:stringIgnoreCase + + weak + + name + + + + + + + + name + + + + + ri:memberOf + + mr:stringIgnoreCase + explicit + + + + + ri:group + entitlement + group + objectToSubject + ri:member + ri:dn + ri:memberOf + ri:dn + + + + 5 + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + cn=admin,dc=example,dc=edu + + + + + + + + + weak + + + + + + + + + + + + + weak + + + + + + + + + + entitlement + group + true + ri:groupOfNames + + + + + + + Account sync + ri:inetOrgPerson + account + default + UserType + true + + + + name + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000003"; + $account/attributes/ri:employeeNumber + + + + + name + + + + + + + + linked + true + + + deleted + true + + + + unlinked + true + + + + unmatched + true + + + + + + ldapGroup sync + ri:groupOfNames + entitlement + group + c:RoleType + true + + + + cn + + $shadow/attributes/cn + + + + + + linked + true + + + deleted + + + + unlinked + true + + + + unmatched + true + + + + + diff --git a/midpoint/configs/tier-demo-groups.xml b/midpoint/configs/tier-demo-groups.xml new file mode 100644 index 0000000..6a8b8db --- /dev/null +++ b/midpoint/configs/tier-demo-groups.xml @@ -0,0 +1,338 @@ + + + + tier-demo-groups + + + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + 389 + tier-demo-ldap + dc=example,dc=edu + cn=admin,dc=example,dc=edu + password + never + auto + SSHA + uid + 2.5.13.3 + memberOf + + createTimestamp + + + false + false + false + + + + + + + ri:inetOrgPerson + ri:groupOfUniqueNames + ri:groupOfNames + ri:organizationalUnit + ri:eduPerson + + + + + + account + default + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + mr:distinguishedName + + + $user/name + + + + + + + + ri:entryUUID + Entry UUID + mr:stringIgnoreCase + + + ri:cn + Common Name + + 1 + + + + fullName + + + + + fullName + + + + + ri:sn + Surname + + + familyName + + + + + familyName + + + + + ri:givenName + Given Name + + + givenName + + + + + givenName + + + + + ri:uid + Login Name + mr:stringIgnoreCase + + weak + + name + + + + + + + + name + + + + + ri:memberOf + + mr:stringIgnoreCase + explicit + + + ri:grouperMemberOf + mr:stringIgnoreCase + explicit + + + + + ri:group + entitlement + group + objectToSubject + ri:member + ri:dn + ri:grouperMemberOf + ri:dn + + + + 5 + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + cn=admin,dc=example,dc=edu + + + + + + + + + weak + + + + + + + + + + + + + weak + + + + + + + + + + entitlement + group + true + ri:groupOfNames + + + + + + + Account sync + ri:inetOrgPerson + account + default + UserType + true + + + + name + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000003"; + $account/attributes/ri:employeeNumber + + + + + name + + + + + + + + linked + true + + + deleted + true + + + + unlinked + true + + + + unmatched + true + + + + + + ldapGroup sync + ri:groupOfNames + entitlement + group + c:RoleType + true + + + + cn + + $shadow/attributes/cn + + + + + + linked + true + + + deleted + + + + unlinked + true + + + + unmatched + true + + + + + diff --git a/midpoint/configs/tier-demo-groups.xml.broken b/midpoint/configs/tier-demo-groups.xml.broken new file mode 100644 index 0000000..4843087 --- /dev/null +++ b/midpoint/configs/tier-demo-groups.xml.broken @@ -0,0 +1,372 @@ + + + + tier-demo-midpoint + + + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + 389 + tier-demo-ldap + dc=example,dc=edu + cn=admin,dc=example,dc=edu + password + never + auto + SSHA + uid + 2.5.13.3 + + uniqueMember + createTimestamp + + + false + false + false + + + + + + + ri:inetOrgPerson + ri:groupOfUniqueNames + ri:groupOfNames + ri:organizationalUnit + ri:eduPerson + + + + + + account + default + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + mr:distinguishedName + + + $user/name + + + + + + + + ri:entryUUID + Entry UUID + mr:stringIgnoreCase + + + ri:cn + Common Name + + 1 + + + + fullName + + + + + fullName + + + + + ri:sn + Surname + + + familyName + + + + + familyName + + + + + ri:givenName + Given Name + + + givenName + + + + + givenName + + + + + ri:uid + Login Name + mr:stringIgnoreCase + + weak + + name + + + + + + + + name + + + + + + ri:uniqueMember + mr:stringIgnoreCase + explicit + + + + ri:ldapGroup + LDAP Group Membership + mr:stringIgnoreCase + entitlement + ldapGroup + objectToSubject + ri:member + ri:dn + false + + + + 5 + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + cn=admin,dc=example,dc=edu + + + + + + + + + weak + + + + + + + + + + + + + weak + + + + + + + + + + entitlement + ldapGroup + LDAP Group + ri:groupOfNames + + identifier + mr:stringIgnoreCase + + + + $focus/identifier + + + + + + + + ri:member + mr:distinguishedName + minimal + + strong + + cn=dummy,o=whatever + + + + + ri:cn + mr:stringIgnoreCase + + weak + + $focus/identifier + + + + + ri:description + + + description + + + + + + + + + Account sync + ri:inetOrgPerson + account + default + UserType + true + + + + ri:dn + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000003"; + $account/attributes/ri:employeeNumber + + + + + name + + + + + + + + linked + true + + + deleted + true + + + + unlinked + true + + + + unmatched + true + + + + + + ldapGroup sync + ri:groupOfNames + entitlement + ldapGroup + c:RoleType + true + + + identifier + + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"; + $account/attributes/ri:dn + + + + + + + linked + true + + + deleted + + + + unlinked + + + + unmatched + + + + + diff --git a/midpoint/configs/tier-demo-midpoint.xml b/midpoint/configs/tier-demo-midpoint.xml new file mode 100644 index 0000000..d5d0b67 --- /dev/null +++ b/midpoint/configs/tier-demo-midpoint.xml @@ -0,0 +1,271 @@ + + + + tier-demo-midpoint + + + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + 389 + tier-demo-ldap + dc=example,dc=edu + cn=admin,dc=example,dc=edu + password + never + auto + SSHA + uid + 2.5.13.3 + + uniqueMember + createTimestamp + + + false + false + false + + + + + + + ri:inetOrgPerson + ri:groupOfUniqueNames + ri:groupOfNames + ri:organizationalUnit + ri:eduPerson + + + + + + account + default + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + mr:distinguishedName + + + $user/name + + + + + + + + ri:entryUUID + Entry UUID + mr:stringIgnoreCase + + + ri:cn + Common Name + + 1 + + + + fullName + + + + + fullName + + + + + ri:sn + Surname + + + familyName + + + + + familyName + + + + + ri:givenName + Given Name + + + givenName + + + + + givenName + + + + + ri:uid + Login Name + mr:stringIgnoreCase + + weak + + name + + + + + + + + name + + + + + + ri:uniqueMember + mr:stringIgnoreCase + explicit + + + + 5 + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + cn=admin,dc=example,dc=edu + + + + + + + + + weak + + + + + + + + + + + + + weak + + + + + + + + + + + + + Account sync + ri:inetOrgPerson + account + default + UserType + true + + + + name + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000003"; + $account/attributes/ri:employeeNumber + + + + + name + + + + + + + + linked + true + + + deleted + true + + + + unlinked + true + + + + unmatched + true + + + + + diff --git a/midpoint/configs/tier-demo-users.xml b/midpoint/configs/tier-demo-users.xml new file mode 100644 index 0000000..d5d0b67 --- /dev/null +++ b/midpoint/configs/tier-demo-users.xml @@ -0,0 +1,271 @@ + + + + tier-demo-midpoint + + + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + 389 + tier-demo-ldap + dc=example,dc=edu + cn=admin,dc=example,dc=edu + password + never + auto + SSHA + uid + 2.5.13.3 + + uniqueMember + createTimestamp + + + false + false + false + + + + + + + ri:inetOrgPerson + ri:groupOfUniqueNames + ri:groupOfNames + ri:organizationalUnit + ri:eduPerson + + + + + + account + default + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + mr:distinguishedName + + + $user/name + + + + + + + + ri:entryUUID + Entry UUID + mr:stringIgnoreCase + + + ri:cn + Common Name + + 1 + + + + fullName + + + + + fullName + + + + + ri:sn + Surname + + + familyName + + + + + familyName + + + + + ri:givenName + Given Name + + + givenName + + + + + givenName + + + + + ri:uid + Login Name + mr:stringIgnoreCase + + weak + + name + + + + + + + + name + + + + + + ri:uniqueMember + mr:stringIgnoreCase + explicit + + + + 5 + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + cn=admin,dc=example,dc=edu + + + + + + + + + weak + + + + + + + + + + + + + weak + + + + + + + + + + + + + Account sync + ri:inetOrgPerson + account + default + UserType + true + + + + name + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000003"; + $account/attributes/ri:employeeNumber + + + + + name + + + + + + + + linked + true + + + deleted + true + + + + unlinked + true + + + + unmatched + true + + + + + diff --git a/midpoint/configs/working-userimport.xml b/midpoint/configs/working-userimport.xml new file mode 100644 index 0000000..10da420 --- /dev/null +++ b/midpoint/configs/working-userimport.xml @@ -0,0 +1,380 @@ + + + + tier-demo-midpoint + + + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + 389 + tier-demo-ldap + dc=example,dc=edu + cn=admin,dc=example,dc=edu + password + never + auto + SSHA + uid + 2.5.13.3 + + uniqueMember + createTimestamp + + + false + false + false + + + + + + + ri:inetOrgPerson + ri:groupOfUniqueNames + ri:groupOfNames + ri:organizationalUnit + ri:eduPerson + + + + + + account + default + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + mr:distinguishedName + + + $user/name + + + + + + + + ri:entryUUID + Entry UUID + mr:stringIgnoreCase + + + ri:cn + Common Name + + 1 + + + + fullName + + + + + fullName + + + + + ri:sn + Surname + + + familyName + + + + + familyName + + + + + ri:givenName + Given Name + + + givenName + + + + + givenName + + + + + ri:uid + Login Name + mr:stringIgnoreCase + + weak + + name + + + + + + + + name + + + + + + ri:uniqueMember + mr:stringIgnoreCase + explicit + + + + 5 + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + cn=admin,dc=example,dc=edu + + + + + + + + + weak + + + + + + + + + + + + + weak + + + + + + + + + + + + + + + + + Account sync + ri:inetOrgPerson + account + default + UserType + true + + + + name + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000003"; + $account/attributes/ri:employeeNumber + + + + + name + + + + + + + + linked + true + + + deleted + true + + + + unlinked + true + + + + unmatched + true + + + + + + + + diff --git a/midpoint/keystore b/midpoint/keystore new file mode 100644 index 0000000..d62d16a Binary files /dev/null and b/midpoint/keystore differ diff --git a/midpoint/keystore.jceks b/midpoint/keystore.jceks new file mode 100644 index 0000000..8f5348e Binary files /dev/null and b/midpoint/keystore.jceks differ diff --git a/midpoint/ldap-resource-sync-advanced.xml b/midpoint/ldap-resource-sync-advanced.xml new file mode 100644 index 0000000..95c64e9 --- /dev/null +++ b/midpoint/ldap-resource-sync-advanced.xml @@ -0,0 +1,522 @@ + + + + + + + + + + + + + Localhost LDAP - Origin + + + LDAP resource using an Identity Connector Framework LDAP connector. It contains configuration + for use with stock OpenDJ and OpenDS servers. + + This resource definition contains also definition to enable synchronization and + especially an expression that is using a lookup of value from an configuration + object. + + + + + Reference to the ICF LDAP connector. This is dynamic reference, it will be translated to + OID during import. + + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + + 389 + tier-demo-ldap + dc=example,dc=edu + cn=admin,dc=example,dc=edu + + password + + auto + entryUUID + + ds-pwp-account-disabled + isMemberOf + + + 120000 + 1 + 10 + 10 + 150000 + + 100 + + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + -1 + + + false + false + false + + + + + + + + ri:inetOrgPerson + ri:groupOfUniqueNames + ri:groupOfNames + ri:organizationalUnit + + + + + + + + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + + 0 + + true + true + false + + + mr:stringIgnoreCase + + weak + + $user/name + + + + + + + + ri:entryUUID + Entry UUID + + + true + + + + + ri:cn + Common Name + + 0 + + true + true + true + + + + + $user/fullName + + + + + $user/fullName + + + + + ri:sn + Surname + + 0 + + + + + familyName + + + + + + familyName + + + + + ri:givenName + Given Name + + + + $c:user/c:givenName + + + + + $c:user/c:givenName + + + + + ri:uid + Login Name + + + true + true + + + mr:stringIgnoreCase + + + Source may have description + $user/name + + + + + + + + + Targets may have description + $c:user/c:name + + + + + ri:description + + weak + + Expression that assigns a fixed value + Created by IDM + + + + + + + declare namespace my="http://whatever.com/my"; + $c:user/c:extension/my:description + + + + + + ri:l + + + + my:defaultLocation + middle of nowhere + + + + + + + + 5 + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#distinguishedName + attributes/ri:dn + uid=idm,ou=Administrators,dc=example,dc=com + + + + + + + + + weak + + + + + + + + + + + + + + + + weak + + + + + + + + + + + + + + + + ri:ds-pwp-account-disabled + + true + + + + + + + + + + true + + + + Correlation expression is a search query. + Following search query will look for users that have "name" + equal to the "uid" attribute of the account. Simply speaking, + it will look for match in usernames in the IDM and the resource. + The correlation rule always looks for users, so it will not match + any other object type. + + + c:name + + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"; + $account/attributes/ri:uid + + + + + + + + + + + linked + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#modifyUser + + + + deleted + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlinkAccount + + + + + unlinked + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#linkAccount + + + + unmatched + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addUser + + + + + + + + + + Default User Template 1 + + + User Template Object. + This object is used when creating a new account, to set it up as needed. + + + + + Property mapping. + Defines how properties of user object are set up. + This specific definition sets a full name as a concatenation + of givenName and familyName. + + weak + + $user/givenName + + + $user/familyName + + + + + + fullName + + + + + + + + My Sample Config Object + + Sample custom configuration object. Object of the genericObject type are + in fact free-form objects. They can contain almost any XML data in the + extension part. They are supposed to hold data structures that parametrize + the IDM custom business logic or IDM expressions. + + + + + + + + + + + http://myself.me/schemas/objects#SampleConfigType + + + + Synchronization: Grouper LDAP + + Definition of a live synchronization task. It will poll changelog and pull in changes + + 91919191-76e0-59e2-86d6-3d4f02d3ffff + + runnable + + http://midpoint.evolveum.com/xml/ns/public/model/synchronization/task/live-sync/handler-3 + + recurring + tight + + 5 + + + + + diff --git a/midpoint/openldap-tier.xml b/midpoint/openldap-tier.xml new file mode 100644 index 0000000..4da7124 --- /dev/null +++ b/midpoint/openldap-tier.xml @@ -0,0 +1,391 @@ + + + + OpenLDAP + + + + + c:connectorType + com.evolveum.polygon.connector.ldap.LdapConnector + + + + + + + 389 + tier-demo-ldap + dc=example,dc=edu + cn=admin,dc=example,dc=edu + password + never + auto + SSHA + uid + 2.5.13.3 + memberOf + createTimestamp + + + false + false + false + + + + + + + ri:inetOrgPerson + ri:groupOfUniqueNames + ri:groupOfNames + ri:organizationalUnit + ri:eduPerson + + + + + + account + default + Default Account + true + ri:inetOrgPerson + + ri:dn + Distinguished Name + mr:distinguishedName + + + $user/name + + + + + + + + ri:entryUUID + Entry UUID + mr:stringIgnoreCase + + + ri:cn + Common Name + + 1 + + + + fullName + + + + + fullName + + + + + ri:sn + Surname + + + familyName + + + + + familyName + + + + + ri:givenName + Given Name + + + givenName + + + + + givenName + + + + + ri:uid + Login Name + mr:stringIgnoreCase + + weak + + name + + + + + + + + name + + + + + ri:memberOf + + mr:stringIgnoreCase + explicit + + + + ri:group + LDAP Group Membership + entitlement + + group + objectToSubject + ri:members + + ri:dn + ri:memberOf + ri:dn + true + + + + 5 + + + + + + http://prism.evolveum.com/xml/ns/public/matching-rule-3#stringIgnoreCase + attributes/ri:dn + cn=admin,dc=example,dc=com + + + + + + + + + weak + + + + + + + + + + + + + + + + + + + + + + + entitlement + + group + true + LDAP Group + ri:groupOfNames + + + ri:dn + mr:distinguishedName + + + + $focus/name + + + + + + + + ri:member + + mr:distinguishedName + + + ri:cn + mr:stringIgnoreCase + + weak + + $focus/name + + + + + name + + + + + ri:description + + + description + + + + + description + + + + + + + + + + Account sync + ri:inetOrgPerson + account + default + UserType + true + + + + name + + declare namespace ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000003"; + $account/attributes/ri:employeeNumber + + + + + name + + + + + + + + linked + true + + + deleted + true + + + + unlinked + true + + + + unmatched + true + + + + + + Group sync + ri:groupOfNames + + entitlement + + group + RoleType + true + + + + name + + $shadow/attributes/cn + + + + + + linked + true + + + deleted + true + + + + unlinked + true + + + + unmatched + true + + + + + + diff --git a/midpoint/server.xml b/midpoint/server.xml new file mode 100644 index 0000000..daf3742 --- /dev/null +++ b/midpoint/server.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shib-idp/Dockerfile b/shib-idp/Dockerfile new file mode 100644 index 0000000..0729ed0 --- /dev/null +++ b/shib-idp/Dockerfile @@ -0,0 +1,99 @@ +FROM centos:centos7 + +MAINTAINER Unicon, Inc. + +LABEL idp.java.version="8.0.121" \ + idp.jetty.version="9.3.16.v20170120" \ + idp.version="3.3.2" + +ENV JETTY_HOME=/opt/jetty-home \ + JETTY_BASE=/opt/shib-jetty-base \ + JETTY_MAX_HEAP=2048m \ + JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=changeme \ + JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=changeme \ + PATH=$PATH:$JRE_HOME/bin + +RUN yum -y update \ + && yum -y install wget tar which apache-commons-dbcp apache-commons-pool mysql-connector-java \ + && yum -y clean all + +RUN set -x; \ + java_version=8.0.121; \ + zulu_version=8.20.0.5; \ + java_hash=e5f4b1d997e50ffe4998c68c8ec45403; \ + jetty_version=9.3.16.v20170120; \ + jetty_hash=f007648daa13799554a95c5ec31d44deac7e56b8; \ + idp_version=3.3.2; \ + idp_hash=ed9fbefd273199d2841d4045b2661671c53825ed3c7d52d38bfe516b39d5fc64; \ + dta_hash=2f547074b06952b94c35631398f36746820a7697; \ + + useradd jetty -U -s /bin/false \ + +# Download Java, verify the hash, and install \ + && cd / \ + && wget http://cdn.azul.com/zulu/bin/zulu$zulu_version-jdk$java_version-linux_x64.tar.gz \ + && echo "$java_hash zulu$zulu_version-jdk$java_version-linux_x64.tar.gz" | md5sum -c - \ + && tar -zxvf zulu$zulu_version-jdk$java_version-linux_x64.tar.gz -C /opt \ + && rm zulu$zulu_version-jdk$java_version-linux_x64.tar.gz \ + && ln -s /opt/zulu$zulu_version-jdk$java_version-linux_x64/jre/ /opt/jre-home \ + +# Download Jetty, verify the hash, and install, initialize a new base \ + && cd / \ + && wget http://central.maven.org/maven2/org/eclipse/jetty/jetty-distribution/$jetty_version/jetty-distribution-$jetty_version.tar.gz \ + && echo "$jetty_hash jetty-distribution-$jetty_version.tar.gz" | sha1sum -c - \ + && tar -zxvf jetty-distribution-$jetty_version.tar.gz -C /opt \ + && rm jetty-distribution-$jetty_version.tar.gz \ + && ln -s /opt/jetty-distribution-$jetty_version/ /opt/jetty-home \ + +# Config Jetty \ + && cd / \ + && cp /opt/jetty-home/bin/jetty.sh /etc/init.d/jetty \ + && mkdir -p /opt/shib-jetty-base/modules /opt/shib-jetty-base/lib/ext /opt/shib-jetty-base/resources \ + && cd /opt/shib-jetty-base \ + && touch start.ini \ + && /opt/jre-home/bin/java -jar ../jetty-home/start.jar --add-to-startd=http,https,deploy,ext,annotations,jstl \ + +# Download Shibboleth IdP, verify the hash, and install \ + && cd / \ + && wget https://shibboleth.net/downloads/identity-provider/$idp_version/shibboleth-identity-provider-$idp_version.tar.gz \ + && echo "$idp_hash shibboleth-identity-provider-$idp_version.tar.gz" | sha256sum -c - \ + && tar -zxvf shibboleth-identity-provider-$idp_version.tar.gz -C /opt \ + && rm /shibboleth-identity-provider-$idp_version.tar.gz \ + && ln -s /opt/shibboleth-identity-provider-$idp_version/ /opt/shibboleth-idp \ + +# Download the library to allow SOAP Endpoints, verify the hash, and place \ + && cd / \ + && wget https://build.shibboleth.net/nexus/content/repositories/releases/net/shibboleth/utilities/jetty9/jetty9-dta-ssl/1.0.0/jetty9-dta-ssl-1.0.0.jar \ + && echo "$dta_hash jetty9-dta-ssl-1.0.0.jar" | sha1sum -c - \ + && mv jetty9-dta-ssl-1.0.0.jar /opt/shib-jetty-base/lib/ext/ \ + +# Copy in the MySQL jdbc library and the other stuff Shib needs for datasources + && cd /opt/shib-jetty-base/lib/ext/ \ + && ln -s /usr/share/java/mysql-connector-java.jar mysql-connector-java.jar \ + && ln -s /usr/share/java/commons-pool.jar commons-pool.jar \ + && ln -s /usr/share/java/commons-dbcp.jar commons-dbcp.jar \ + +# Setting owner ownership and permissions on new items in this command + && chown -R root:jetty /opt \ + && chmod -R 640 /opt \ + && chmod 750 /opt/jre-home/bin/java + +COPY bin/ /usr/local/bin/ +COPY opt/shib-jetty-base/ /opt/shib-jetty-base/ +COPY opt/shibboleth-idp/ /opt/shibboleth-idp/ + +# Setting owner ownership and permissions on new items from the COPY command +RUN mkdir /opt/shib-jetty-base/logs \ + && chown -R root:jetty /opt/shib-jetty-base \ + && chmod -R 640 /opt/shib-jetty-base \ + && chmod -R 750 /opt/shibboleth-idp/bin \ + && chmod 750 /usr/local/bin/run-jetty.sh /usr/local/bin/init-idp.sh + +# copy in the custom configs +COPY customized-shibboleth-idp/ /opt/shibboleth-idp/ + + +# Opening 4443 (browser TLS), 8443 (mutual auth TLS) +EXPOSE 4443 8443 + +CMD ["run-jetty.sh"] diff --git a/shib-idp/LICENSE b/shib-idp/LICENSE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/shib-idp/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/shib-idp/README.md b/shib-idp/README.md new file mode 100644 index 0000000..ab4d57f --- /dev/null +++ b/shib-idp/README.md @@ -0,0 +1,4 @@ +This is Unicon's Dockerized Shib IDP. You can get it here: https://github.com/Unicon/shibboleth-idp-dockerized + +The base configs were generated from the above project and then customized to interact with the tier-demo-ldap container. + diff --git a/shib-idp/bin/init-idp.sh b/shib-idp/bin/init-idp.sh new file mode 100644 index 0000000..aa6305e --- /dev/null +++ b/shib-idp/bin/init-idp.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +export JAVA_HOME=/opt/jre-home +export PATH=$PATH:$JAVA_HOME/bin + +cd /opt/shibboleth-idp/bin + +# Remove existing config to build starts with an empty config +rm -r ../conf/ + +echo "Please complete the following for your IdP environment:" +./build.sh -Didp.target.dir=/opt/shibboleth-idp init gethostname askscope metadata-gen + +mkdir -p /ext-mount/customized-shibboleth-idp/conf/ + +# Copy the essential and routinely customized config to out Docker mount. +cd .. +cp -r credentials/ /ext-mount/customized-shibboleth-idp/ +cp -r metadata/ /ext-mount/customized-shibboleth-idp/ +cp conf/{attribute-resolver.xml,attribute-filter.xml,cas-protocol.xml,idp.properties,ldap.properties,metadata-providers.xml,relying-party.xml,saml-nameid.xml} /ext-mount/customized-shibboleth-idp/conf/ + +# Copy the basic UI components, which are routinely customized +cp -r views/ /ext-mount/customized-shibboleth-idp/ +mkdir /ext-mount/customized-shibboleth-idp/webapp/ +cp -r webapp/css/ /ext-mount/customized-shibboleth-idp/webapp/ +cp -r webapp/images/ /ext-mount/customized-shibboleth-idp/webapp/ +cp -r webapp/js/ /ext-mount/customized-shibboleth-idp/webapp/ +rm -r /ext-mount/customized-shibboleth-idp/views/user-prefs.js + +echo "A basic Shibboleth IdP config and UI has been copied to ./customized-shibboleth-idp/ (assuming the default volume mapping was used)." +echo "Most files, if not being customized can be removed from what was exported/the local Docker image and baseline files will be used." diff --git a/shib-idp/bin/run-jetty.sh b/shib-idp/bin/run-jetty.sh new file mode 100644 index 0000000..05a9174 --- /dev/null +++ b/shib-idp/bin/run-jetty.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +#set -x + +export JAVA_HOME=/opt/jre-home +export PATH=$PATH:$JAVA_HOME/bin + +if [ -e "/opt/shibboleth-idp/ext-conf/idp-secrets.properties" ]; then + export JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD=`gawk 'match($0,/^jetty.backchannel.sslContext.keyStorePassword=\s?(.*)\s?$/, a) {print a[1]}' /opt/shibboleth-idp/ext-conf/idp-secrets.properties` + export JETTY_BROWSER_SSL_KEYSTORE_PASSWORD=`gawk 'match($0,/^jetty\.sslContext\.keyStorePassword=\s?(.*)\s?$/, a) {print a[1]}' /opt/shibboleth-idp/ext-conf/idp-secrets.properties` +fi + +export JETTY_ARGS="jetty.sslContext.keyStorePassword=$JETTY_BROWSER_SSL_KEYSTORE_PASSWORD jetty.backchannel.sslContext.keyStorePassword=$JETTY_BACKCHANNEL_SSL_KEYSTORE_PASSWORD" +sed -i "s/^-Xmx.*$/-Xmx$JETTY_MAX_HEAP/g" /opt/shib-jetty-base/start.ini + +exec /etc/init.d/jetty run diff --git a/shib-idp/build.sh b/shib-idp/build.sh new file mode 100755 index 0000000..1e02202 --- /dev/null +++ b/shib-idp/build.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# +# build.sh, DESCRIPTION +# +docker build . -t tier-demo-idp diff --git a/shib-idp/customized-shibboleth-idp/conf/attribute-filter.xml b/shib-idp/customized-shibboleth-idp/conf/attribute-filter.xml new file mode 100644 index 0000000..0df6a7b --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/attribute-filter.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shib-idp/customized-shibboleth-idp/conf/attribute-resolver.xml b/shib-idp/customized-shibboleth-idp/conf/attribute-resolver.xml new file mode 100644 index 0000000..14cf67d --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/attribute-resolver.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + member + + + urn:mace:example.edu:demoservice:demo-user + + + + + + + + + + + MyDataSource + 0) + SELECT DISTINCT grouper_memberships_lw_v.group_name + FROM grouper.grouper_aval_asn_group_v + JOIN grouper.grouper_memberships_lw_v + USING (group_id) + WHERE subject_id='$uid.get(0)' + AND grouper_aval_asn_group_v.attribute_def_name_name='etc:attribute:ShibEntityId:ShibEntityId' + AND (value_string = '$requestContext.getPeerEntityId()' OR value_string='DEFAULT') + AND grouper_aval_asn_group_v.enabled='T' + ORDER BY group_name ASC; + #else + SELECT 1 + #end + ]]> + + + + + + + + MyDataSource + 0) + select givenname, surname, fullName, email from myapp_development.users where uid='$uid.get(0)' + #else + SELECT 1 + #end + ]]> + + + + + + diff --git a/shib-idp/customized-shibboleth-idp/conf/cas-protocol.xml b/shib-idp/customized-shibboleth-idp/conf/cas-protocol.xml new file mode 100644 index 0000000..d0b3d55 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/cas-protocol.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/conf/global.xml b/shib-idp/customized-shibboleth-idp/conf/global.xml new file mode 100644 index 0000000..3f709bd --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/global.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/shib-idp/customized-shibboleth-idp/conf/idp.properties b/shib-idp/customized-shibboleth-idp/conf/idp.properties new file mode 100644 index 0000000..7bfd1c5 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/idp.properties @@ -0,0 +1,195 @@ +# Load any additional property resources from a comma-delimited list +idp.additionalProperties= /conf/ldap.properties, /conf/saml-nameid.properties, /conf/services.properties, /conf/authn/duo.properties + +# Set the entityID of the IdP +idp.entityID= https://localhost/idp/shibboleth + +# Set the scope used in the attribute resolver for scoped attributes +idp.scope= example.edu + +# General cookie properties (maxAge only applies to persistent cookies) +#idp.cookie.secure = false +#idp.cookie.httpOnly = true +#idp.cookie.domain = +#idp.cookie.path = +#idp.cookie.maxAge = 31536000 + +# Set the location of user-supplied web flow definitions +#idp.webflows = %{idp.home}/flows + +# Set the location of Velocity view templates +#idp.views = %{idp.home}/views + +# Settings for internal AES encryption key +#idp.sealer.storeType = JCEKS +#idp.sealer.updateInterval = PT15M +#idp.sealer.aliasBase = secret +idp.sealer.storeResource= %{idp.home}/credentials/sealer.jks +idp.sealer.versionResource= %{idp.home}/credentials/sealer.kver +idp.sealer.storePassword= changeme +idp.sealer.keyPassword= changeme + +# Settings for public/private signing and encryption key(s) +# During decryption key rollover, point the ".2" properties at a second +# keypair, uncomment in credentials.xml, then publish it in your metadata. +idp.signing.key= %{idp.home}/credentials/idp-signing.key +idp.signing.cert= %{idp.home}/credentials/idp-signing.crt +idp.encryption.key= %{idp.home}/credentials/idp-encryption.key +idp.encryption.cert= %{idp.home}/credentials/idp-encryption.crt +#idp.encryption.key.2 = %{idp.home}/credentials/idp-encryption-old.key +#idp.encryption.cert.2 = %{idp.home}/credentials/idp-encryption-old.crt + +# Sets the bean ID to use as a default security configuration set +#idp.security.config = shibboleth.DefaultSecurityConfiguration + +# To default to SHA-1, set to shibboleth.SigningConfiguration.SHA1 +#idp.signing.config = shibboleth.SigningConfiguration.SHA256 + +# Configures trust evaluation of keys used by services at runtime +# Defaults to supporting both explicit key and PKIX using SAML metadata. +#idp.trust.signatures = shibboleth.ChainingSignatureTrustEngine +# To pick only one set to one of: +# shibboleth.ExplicitKeySignatureTrustEngine, shibboleth.PKIXSignatureTrustEngine +#idp.trust.certificates = shibboleth.ChainingX509TrustEngine +# To pick only one set to one of: +# shibboleth.ExplicitKeyX509TrustEngine, shibboleth.PKIXX509TrustEngine + +# If true, encryption will happen whenever a key to use can be located, but +# failure to encrypt won't result in request failure. +#idp.encryption.optional = false + +# Configuration of client- and server-side storage plugins +#idp.storage.cleanupInterval = PT10M +#idp.storage.htmlLocalStorage = false + +# Set to true to expose more detailed errors in responses to SPs +#idp.errors.detailed = false +# Set to false to skip signing of SAML response messages that signal errors +#idp.errors.signed = true +# Name of bean containing a list of Java exception classes to ignore +#idp.errors.excludedExceptions = ExceptionClassListBean +# Name of bean containing a property set mapping exception names to views +#idp.errors.exceptionMappings = ExceptionToViewPropertyBean +# Set if a different default view name for events and exceptions is needed +#idp.errors.defaultView = error + +# Set to false to disable the IdP session layer +#idp.session.enabled = true + +# Set to "shibboleth.StorageService" for server-side storage of user sessions +#idp.session.StorageService = shibboleth.ClientSessionStorageService + +# Size of session IDs +#idp.session.idSize = 32 +# Bind sessions to IP addresses +#idp.session.consistentAddress = true +# Inactivity timeout +#idp.session.timeout = PT60M +# Extra time to store sessions for logout +#idp.session.slop = PT0S +# Tolerate storage-related errors +#idp.session.maskStorageFailure = false +# Track information about SPs logged into +#idp.session.trackSPSessions = false +# Support lookup by SP for SAML logout +#idp.session.secondaryServiceIndex = false +# Length of time to track SP sessions +#idp.session.defaultSPlifetime = PT2H + +# Regular expression matching login flows to enable, e.g. IPAddress|Password +idp.authn.flows= Password + +# Regular expression of forced "initial" methods when no session exists, +# usually in conjunction with the idp.authn.resolveAttribute property below. +#idp.authn.flows.initial = Password + +# Set to an attribute ID to resolve prior to selecting authentication flows; +# its values are used to filter the flows to allow. +#idp.authn.resolveAttribute = eduPersonAssurance + +# Default lifetime and timeout of various authentication methods +#idp.authn.defaultLifetime = PT60M +#idp.authn.defaultTimeout = PT30M + +# Whether to populate relying party user interface information for display +# during authentication, consent, terms-of-use. +#idp.authn.rpui = true + +# Whether to prioritize "active" results when an SP requests more than +# one possible matching login method (V2 behavior was to favor them) +#idp.authn.favorSSO = false + +# Whether to fail requests when a user identity after authentication +# doesn't match the identity in a pre-existing session. +#idp.authn.identitySwitchIsError = false + +# Set to "shibboleth.StorageService" or custom bean for alternate storage of consent +#idp.consent.StorageService = shibboleth.ClientPersistentStorageService + +# Set to "shibboleth.consent.AttributeConsentStorageKey" to use an attribute +# to key user consent storage records (and set the attribute name) +#idp.consent.userStorageKey = shibboleth.consent.PrincipalConsentStorageKey +#idp.consent.userStorageKeyAttribute = uid + +# Flags controlling how built-in attribute consent feature operates +#idp.consent.allowDoNotRemember = true +#idp.consent.allowGlobal = true +#idp.consent.allowPerAttribute = false + +# Whether attribute values and terms of use text are compared +#idp.consent.compareValues = false +# Maximum number of consent records for space-limited storage (e.g. cookies) +#idp.consent.maxStoredRecords = 10 +# Maximum number of consent records for larger/server-side storage (0 = no limit) +#idp.consent.expandedMaxStoredRecords = 0 + +# Time in milliseconds to expire consent storage records. +#idp.consent.storageRecordLifetime = P1Y + +# Whether to lookup metadata, etc. for every SP involved in a logout +# for use by user interface logic; adds overhead so off by default. +#idp.logout.elaboration = false + +# Whether to require logout requests/responses be signed/authenticated. +#idp.logout.authenticated = true + +# Message freshness and replay cache tuning +#idp.policy.messageLifetime = PT3M +#idp.policy.clockSkew = PT3M + +# Set to custom bean for alternate storage of replay cache +#idp.replayCache.StorageService = shibboleth.StorageService + +# Toggles whether to allow outbound messages via SAML artifact +#idp.artifact.enabled = true +# Suppresses typical signing/encryption when artifact binding used +#idp.artifact.secureChannel = true +# May differ to direct SAML 2 artifact lookups to specific server nodes +#idp.artifact.endpointIndex = 2 +# Set to custom bean for alternate storage of artifact map state +#idp.artifact.StorageService = shibboleth.StorageService + +# Comma-delimited languages to use if not match can be found with the +# browser-supported languages, defaults to an empty list. +idp.ui.fallbackLanguages= en,fr,de + +# Storage service used by CAS protocol +# Defaults to shibboleth.StorageService (in-memory) +# MUST be server-side storage (e.g. in-memory, memcached, database) +# NOTE that idp.session.StorageService requires server-side storage +# when CAS protocol is enabled +#idp.cas.StorageService=shibboleth.StorageService + +# CAS service registry implementation class +#idp.cas.serviceRegistryClass=net.shibboleth.idp.cas.service.PatternServiceRegistry + +# Profile flows in which the ProfileRequestContext should be exposed +# in servlet request under the key "opensamlProfileRequestContext" +#idp.profile.exposeProfileRequestContextInServletRequest = SAML2/POST/SSO,SAML2/Redirect/SSO + +# F-TICKS auditing - set a salt to include hashed username +#idp.fticks.federation=MyFederation +#idp.fticks.algorithm=SHA-256 +#idp.fticks.salt=somethingsecret +#idp.fticks.loghost=localhost +#idp.fticks.logport=514 diff --git a/shib-idp/customized-shibboleth-idp/conf/ldap.properties b/shib-idp/customized-shibboleth-idp/conf/ldap.properties new file mode 100644 index 0000000..2f4d905 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/ldap.properties @@ -0,0 +1,63 @@ +# LDAP authentication configuration, see authn/ldap-authn-config.xml +# Note, this doesn't apply to the use of JAAS + +## Authenticator strategy, either anonSearchAuthenticator, bindSearchAuthenticator, directAuthenticator, adAuthenticator +idp.authn.LDAP.authenticator = bindSearchAuthenticator + +## Connection properties ## +idp.authn.LDAP.ldapURL = ldap://tier-demo-ldap:389 +idp.authn.LDAP.useStartTLS = false +idp.authn.LDAP.useSSL = false +# Time in milliseconds that connects will block +#idp.authn.LDAP.connectTimeout = PT3S +# Time in milliseconds to wait for responses +#idp.authn.LDAP.responseTimeout = PT3S + +## SSL configuration, either jvmTrust, certificateTrust, or keyStoreTrust +#idp.authn.LDAP.sslConfig = certificateTrust +## If using certificateTrust above, set to the trusted certificate's path +idp.authn.LDAP.trustCertificates = %{idp.home}/credentials/ldap-server.crt +## If using keyStoreTrust above, set to the truststore path +idp.authn.LDAP.trustStore = %{idp.home}/credentials/ldap-server.truststore + +## Return attributes during authentication +idp.authn.LDAP.returnAttributes = passwordExpirationTime,loginGraceRemaining + +## DN resolution properties ## + +# Search DN resolution, used by anonSearchAuthenticator, bindSearchAuthenticator +# for AD: CN=Users,DC=example,DC=org +idp.authn.LDAP.baseDN = ou=people,dc=example,dc=edu +#idp.authn.LDAP.subtreeSearch = false +idp.authn.LDAP.userFilter = (uid={user}) +# bind search configuration +# for AD: idp.authn.LDAP.bindDN=adminuser@domain.com +idp.authn.LDAP.bindDN = cn=admin,dc=example,dc=edu +idp.authn.LDAP.bindDNCredential = password + +# Format DN resolution, used by directAuthenticator, adAuthenticator +# for AD use idp.authn.LDAP.dnFormat=%s@domain.com +idp.authn.LDAP.dnFormat = uid=%s,ou=people,dc=example,dc=edu + +# LDAP attribute configuration, see attribute-resolver.xml +# Note, this likely won't apply to the use of legacy V2 resolver configurations +idp.attribute.resolver.LDAP.ldapURL = %{idp.authn.LDAP.ldapURL} +idp.attribute.resolver.LDAP.connectTimeout = %{idp.authn.LDAP.connectTimeout:PT3S} +idp.attribute.resolver.LDAP.responseTimeout = %{idp.authn.LDAP.responseTimeout:PT3S} +idp.attribute.resolver.LDAP.baseDN = %{idp.authn.LDAP.baseDN:undefined} +idp.attribute.resolver.LDAP.bindDN = %{idp.authn.LDAP.bindDN:undefined} +idp.attribute.resolver.LDAP.bindDNCredential = %{idp.authn.LDAP.bindDNCredential:undefined} +idp.attribute.resolver.LDAP.useStartTLS = %{idp.authn.LDAP.useStartTLS:true} +idp.attribute.resolver.LDAP.trustCertificates = %{idp.authn.LDAP.trustCertificates:undefined} +idp.attribute.resolver.LDAP.searchFilter = (uid=$resolutionContext.principal) + +# LDAP pool configuration, used for both authn and DN resolution +#idp.pool.LDAP.minSize = 3 +#idp.pool.LDAP.maxSize = 10 +#idp.pool.LDAP.validateOnCheckout = false +#idp.pool.LDAP.validatePeriodically = true +#idp.pool.LDAP.validatePeriod = PT5M +#idp.pool.LDAP.prunePeriod = PT5M +#idp.pool.LDAP.idleTime = PT10M +#idp.pool.LDAP.blockWaitTime = PT3S +#idp.pool.LDAP.failFastInitialize = false diff --git a/shib-idp/customized-shibboleth-idp/conf/metadata-providers.xml b/shib-idp/customized-shibboleth-idp/conf/metadata-providers.xml new file mode 100644 index 0000000..fbd2a6d --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/metadata-providers.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shib-idp/customized-shibboleth-idp/conf/relying-party.xml b/shib-idp/customized-shibboleth-idp/conf/relying-party.xml new file mode 100644 index 0000000..28c9193 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/relying-party.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shib-idp/customized-shibboleth-idp/conf/saml-nameid.xml b/shib-idp/customized-shibboleth-idp/conf/saml-nameid.xml new file mode 100644 index 0000000..ea97448 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/conf/saml-nameid.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shib-idp/customized-shibboleth-idp/credentials/idp-backchannel.crt b/shib-idp/customized-shibboleth-idp/credentials/idp-backchannel.crt new file mode 100644 index 0000000..ef29ec6 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/credentials/idp-backchannel.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAfegAwIBAgIUNhoGlKP7mWuGizduv8qofntjgygwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE3MDQxMzIxMTk1M1oXDTM3MDQx +MzIxMTk1M1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAks/QokbcrFosPTXL+i2iMFQMfZvoFxgqIXH+xxrpljrL +sglonsbmHGuinnSeywRzfcBB6mEf3BnYzyezP0aB1GJYzItRSd4AoWAx8WblFfgM +ununMmDpfF1dyTxZxRg/vmhN9EttVugsAoynA17RbiF4vVxx3zhNGS0u3MbaYtH1 +kYIdY9xZMR2wvDo584CQc0/20/FooPnlL0I1s2FD6LFEgvl1sux5owL0ELITSTUF +KEkQVxpYoFZhsq6qhWQJfVvT98W4CMVpXgggQilAWAK1QgLxJtyx54Y3YruFkXsy +Yahi04wwaQXmSHDfQbOzy8yzO65on2VjEPGid6PQvQIDAQABo1kwVzAdBgNVHQ4E +FgQUDkHIVBHNiAcr6vQv/P+5PlKjeAcwNgYDVR0RBC8wLYIJbG9jYWxob3N0hiBo +dHRwczovL2xvY2FsaG9zdC9pZHAvc2hpYmJvbGV0aDANBgkqhkiG9w0BAQsFAAOC +AQEAioMgLmAx1nQwFRuiKe9zhHyl9QClOZ/qI1A/pV3QQfItxpnkjecElvpN0MLX +ugmT0kb0tgyIUxOjHd78kSJOkFKmWPv+iSLouaU4/Y3yOW0uUWOwlExKJNegczBC +t1OCtSAyStnYWSMUHk/Lgq4LcNKwjeaVczEbBoJO8nC/Zx0VMvLEsiCeWR+1acpT +BHcQbEkiSJg2WS3krKt0Wq4iL+WjQhkva6zugM0Lxfkyeeg/imcn6A93zr7e6N+/ +SeKGUN2EpNRAAgEVQMVuMuKo7uFzxl2KxmkKckBG4dnDIvco/OE7khgnbNgszaqX +xDkRFm7ZnBhVnGde7W9xjmw+eA== +-----END CERTIFICATE----- diff --git a/shib-idp/customized-shibboleth-idp/credentials/idp-backchannel.p12 b/shib-idp/customized-shibboleth-idp/credentials/idp-backchannel.p12 new file mode 100644 index 0000000..6e4487a Binary files /dev/null and b/shib-idp/customized-shibboleth-idp/credentials/idp-backchannel.p12 differ diff --git a/shib-idp/customized-shibboleth-idp/credentials/idp-browser.p12 b/shib-idp/customized-shibboleth-idp/credentials/idp-browser.p12 new file mode 100644 index 0000000..7c0df53 Binary files /dev/null and b/shib-idp/customized-shibboleth-idp/credentials/idp-browser.p12 differ diff --git a/shib-idp/customized-shibboleth-idp/credentials/idp-encryption.crt b/shib-idp/customized-shibboleth-idp/credentials/idp-encryption.crt new file mode 100644 index 0000000..2f3e4a4 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/credentials/idp-encryption.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEDCCAfigAwIBAgIVAK/i6INNo2HZzO676jmYDSMUL8pyMA0GCSqGSIb3DQEB +CwUAMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNzA0MTMyMTE5NTBaFw0zNzA0 +MTMyMTE5NTBaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAJbpEl+MgBuKc4gzGni76gcQO/sa/IupoK2RRsnGEKPS +x7q93ZCe4/TTIR8ZArk7aoTtOrV3s7xhOlvwwlUmQEhIupHtk0EDyWxXV4xK8i99 +3rqNkYcHM/C1iZfoKcoEhwQ5pBVukEgxtSIAfsN7UCE88oTRPhTHV8XJkNjw66Vl +P1MBsO5KQaoKW/Ap86nuhDUHMNFAt/jJ2UFGhEVle4ubckBTltrZDV98m6hHYUws +nCuRGEXusGDsqgEt93C8zRjAVhyNBNp+jQUHCBPy/6TG7AZ0TkPuQ3AxhDt34y6A +dgSaCDmy5sI14oa1S1UagSKt8AXpzC0ao8pwqz+t8usCAwEAAaNZMFcwHQYDVR0O +BBYEFMDqVDwUdJ6wzRLBR0jb3QdW1CFpMDYGA1UdEQQvMC2CCWxvY2FsaG9zdIYg +aHR0cHM6Ly9sb2NhbGhvc3QvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQELBQAD +ggEBAFk6YtMiqkuJXY10aeUhabGgkBdpj6RgHreBvhSmn9UTq/4EGgEWNGNYBVn6 +i9i55GzGCtp7RUAuVUTqH5V3Mbp6drUlNbVex05ypYnYM/wIq5W8EENClugPHepZ +OX0gVUVOeayVUMRHPntNI7HicUDYVvXI/Wjhko/GLqwArNKyenmKlRo1yyedkEKF +fhy9QowXYTvG82i3nu0JS9v/103WApXjIr3eP8LZpGpurOxyG3D+8vW3oML6C1eV +FsLdhy3a5kOvGXbzXHn4tFdVCE3oa72FkrsDHZ8YGHb+s2JFHFRsRzDRSmBRV+LA +3ffQkUP9K+ZGyGQijt6gAEJXcsw= +-----END CERTIFICATE----- diff --git a/shib-idp/customized-shibboleth-idp/credentials/idp-encryption.key b/shib-idp/customized-shibboleth-idp/credentials/idp-encryption.key new file mode 100644 index 0000000..5240e81 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/credentials/idp-encryption.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAlukSX4yAG4pziDMaeLvqBxA7+xr8i6mgrZFGycYQo9LHur3d +kJ7j9NMhHxkCuTtqhO06tXezvGE6W/DCVSZASEi6ke2TQQPJbFdXjEryL33euo2R +hwcz8LWJl+gpygSHBDmkFW6QSDG1IgB+w3tQITzyhNE+FMdXxcmQ2PDrpWU/UwGw +7kpBqgpb8Cnzqe6ENQcw0UC3+MnZQUaERWV7i5tyQFOW2tkNX3ybqEdhTCycK5EY +Re6wYOyqAS33cLzNGMBWHI0E2n6NBQcIE/L/pMbsBnROQ+5DcDGEO3fjLoB2BJoI +ObLmwjXihrVLVRqBIq3wBenMLRqjynCrP63y6wIDAQABAoIBABemmXGOFHm8fhTH +ZYusb6YBvlTBSvkccYkiLoTq3KrAGvtCTFog/Lre5972zX14OV5xy3SrOOj6F+pW +1i4AG6z4cPzzzdMvo76uBZOAH2qgAGseSsNtto8v9EtxYDM/+GUKH5QYStZ1q9yT +VUqPpeQ/qAZ2wJMDFtdxmpjVUSkPcnSW5yGQ0kZ82gNCUC4matqwN9glyhNenYKq +y9h+5Rj+JjP3Xyf7lzJqzyKel9qJ/aSyMpzpA4JeyVbHdAAFL4GihaBnmSBkNrX4 +DuHghMLS+WOk4EeGLRaZIatwKvSBMqeb2gyI6vPyPRxzaQd2OevGvATOsltqjmow +5ocwAgECgYEAytEE5jKjDMRVvEC42aH2dg6QUXWirz8DmlWaF8C5FJjaJISdUmny +pxhLZ/GyD1XwaH/RQawBYSq+HPyaUO0xIIzduxyLaZmlu/bLuA/+riLtfvdp3k3z +j1NlPzer4MnrJ8yZfHehNDm+6tv2PcySxZyXXvW8joQZ52FymqqIsesCgYEAvnuf +bnnA+4nH2mE+0WOziZ+yDhUQqBB4PCWdjlvHWw/iv1yCxSreS2jD8acJgbBmhOhl +Di4pncoG4NM0182EW6VVGjEaHnTUwFoCEIjEbCSc+oo8dnsqK2gwb0XNGKI+I/OY +uAOyP8iqYqae6cUQyHWlg5cmdRCKpc9TI6XOgwECgYEAg+VChmHP33GfP/nnPMEz +grsd55vU3JriQPACcggHVPnCg5Uqqnn0L+6Au2xXG9oLqinVcBvoGcSuNjOgN5jJ +Jh315MU/dMFTItXwzha4zY4xXSyRUNzo1ACsC1ytDlbB8vP/rQ4va8NSAXJixPXR +TWn0lvDAWv5Vyj95RFQ66VkCgYA5OFupTSvapAYEJOhA8ElTk0RilJNfWSs1LjuJ +MyrMwRXlVD34SqtiTcNmyT3C1qHFVSZePyHDQ5gTW37pQNR8z0qkRpHJCmGKsr8i +BmOy9MCvRm1pThBZ37+E/ZvhxYMTO67pwDqAjKAaaGEealNjVGv2/qXPzrtHmeMo +tzs1AQKBgE4zeVwa9ZzHjgAz+mkHtxdXvM1pEYa3drTqyME3eGvttwHj5JoF9P4k +N9/BMeQqXMa5lS8Y7iL4LkTxxGS8Rld6L3WkY8XwvaMgGxsrPP8GQJp++Nt89dhB +fd86T52Rs5vBmin6QVTmAfjleqnlk1/DIysc4vNugFTy2PWM5jB5 +-----END RSA PRIVATE KEY----- diff --git a/shib-idp/customized-shibboleth-idp/credentials/idp-signing.crt b/shib-idp/customized-shibboleth-idp/credentials/idp-signing.crt new file mode 100644 index 0000000..7318637 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/credentials/idp-signing.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEDCCAfigAwIBAgIVAI427wUmgnuo//BnofLWvDbJ5LFZMA0GCSqGSIb3DQEB +CwUAMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNzA0MTMyMTE5NDlaFw0zNzA0 +MTMyMTE5NDlaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANrbeJysRIIfnV4NCBkglD7TnnsBiAP8rmYMlKNzB/8P +lh8T8A/m3ZcSfK5XOooV9HYrJ4zkPYWQfmMTc7gPohtEnVvU2T0BhqXVGItRNPq0 +W8PPyJiaf5cPTej2UU0mvEj6RXzswPmpdabti+hFMK1rwKDGAgyNz7O+ODbtUeEu +84B4OVehjgc0DOeeIMOpCa0ZZURtGcmWa2J/2D8ONtsT6YLzrBHSjea8ahu2MnC0 +3TmQ008yWlXztWiNkccVstQ7WwT1aEon6ni608OtRLZ64UHRmaM6MZHft2DcyYgd +bE7wArKpauLscEzAXRaSdJ4lvtgAdjneACbPbTXpvgUCAwEAAaNZMFcwHQYDVR0O +BBYEFGIsJ7ChRjGGKOTuK+Gf79XdnhazMDYGA1UdEQQvMC2CCWxvY2FsaG9zdIYg +aHR0cHM6Ly9sb2NhbGhvc3QvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQELBQAD +ggEBACzq9+IaRqb44oWy3cX+oQUxBozCOd0dn3cAHn/7U2EAt47YLucaT66K5LYq +VpfqYUYP7FXq9lqpYXQgUNn8DuSDroBzQIOx0YVsS4sRKMv+pTBr6WqrIcbDB9Np +VHqdIxIDD9kxwy8eTEKmeDmjl6ZjGnxa8WjwP6PFXBWJI/vQvxNACqnThIsoKLGv +KPta+ROPrtMMbphsVyHClHlLWp/r015B545FBiasFW+jHzS0/pc8eknNafQ2+chX +GPNfHvJXgg3kDHtW6bydWnWIcCKqaTHFSObgEivuMoCJ0cZVjVEFIpzB3J71qMkc +SJ5zygjKVMFLsbAkzGUFYG1DbBM= +-----END CERTIFICATE----- diff --git a/shib-idp/customized-shibboleth-idp/credentials/idp-signing.key b/shib-idp/customized-shibboleth-idp/credentials/idp-signing.key new file mode 100644 index 0000000..ebc8880 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/credentials/idp-signing.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA2tt4nKxEgh+dXg0IGSCUPtOeewGIA/yuZgyUo3MH/w+WHxPw +D+bdlxJ8rlc6ihX0disnjOQ9hZB+YxNzuA+iG0SdW9TZPQGGpdUYi1E0+rRbw8/I +mJp/lw9N6PZRTSa8SPpFfOzA+al1pu2L6EUwrWvAoMYCDI3Ps744Nu1R4S7zgHg5 +V6GOBzQM554gw6kJrRllRG0ZyZZrYn/YPw422xPpgvOsEdKN5rxqG7YycLTdOZDT +TzJaVfO1aI2RxxWy1DtbBPVoSifqeLrTw61EtnrhQdGZozoxkd+3YNzJiB1sTvAC +sqlq4uxwTMBdFpJ0niW+2AB2Od4AJs9tNem+BQIDAQABAoIBAQDFNE949S0CB1S4 +g4uRgK6z8eFyuw2BcjT/VUS2Bxfkd3nw5PlCiueOkiTwvz7LYD8YH4iSxrK84FdS +FRwHdWa/pVMZhTB+bRqT4PEtz+2qHcw2I8t/3m8rganVSeY2W7n7FDB7AaZdEJon +4RJZJ8dV7Kr085azEzFdqABlVfCasxX8SdG6XyTiSRBla1SHhw7DB1OYphWTHob5 +1NOM3GYefgI+hcMnCFDNyXJcdyYoHAMqt6dVbJjMFO5yu0AcSI5gxtNpU6bG7E36 +Bm/hGUG1WYdl1EkWFfogo0Fw0Sm9h4hZDyYgm0j/ZCdGh8PI6JSR2Dbs41aPpzHu +9IFDnFqBAoGBAPTSKSLqDMiEQxyTFhkxnvZE6p7z27UW6sf9wwncEkM8bB9FmnZs +/5x/HRnBjsQMxoYeKX+5w7XRo2qlAmAwo4wGAipkEswzqYmKIxXZaL1VquJ9zQWa +G5nY6ybARLW2JEtod3rnqXYqL7/OkS5QN4JRkm/KWxOYWlXpYUwNOzohAoGBAOTZ +zt1BjfXCWK3I1HmJRo2qLgJMqLlM9umOLFQ734xYbA7V9f5oMzjAUBSwT8v/Ls1F +DTVdDOKroBpivhRkk5S3SRpuoNQhIJXIsqv91NPSDF3hXQyTU4F+ar5T19BWU5oz +wS+LbIjHgY00517fwd4662c0Ib54RXZtI+lvZ+9lAoGBAIftg595+Zz/Kk/cLoHQ +diTfwLB+TrctwS9G6po30P/5tUJrn8Yu4IDgZqTdPcoGGddvObVLy6jQe34Dnd0Q +RE3DLEKjC3jLGk9eHfrMmgW9YcKc/E8m8DosIOuEBuIo/d/MYcIgi4srAxXot9zR +9u/pIHfnD0hC560Zhcb29bJhAoGAYGw5EdZWFu9M5+QPSioB1RyYCBX+nRyFiECE +AvW7KenzlYim/gsvUcENvLnQ1VXuhUSL3SkYjcTcT2G9TuBVojpbjcyA7QAMN6/5 +QChR7PG6ji+vQeYtMAlwtkKjUr+cuAMIaZzoHPVaa4GX3syOZbETkEdR1GvecJhp +oihzdVUCgYEAqkMNBgZuVKaQA0WbrQvVfOp657kGFObvVu/lzCVHhGw83MN6kCUP +cIMhZGxaBpSdXY4LqYnqP5A/NYMbpB+SHve5kMxTd5bGqmZRjleR2z5sH/nlGucP +YTo0H8nFFUzK5h5Xi4X/uYMlv1o/7TqdCUfPCfVLRN0ZKv28N1C/11o= +-----END RSA PRIVATE KEY----- diff --git a/shib-idp/customized-shibboleth-idp/credentials/jetty.crt b/shib-idp/customized-shibboleth-idp/credentials/jetty.crt new file mode 100644 index 0000000..7a58283 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/credentials/jetty.crt @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIErTCCA5WgAwIBAgIJAOSlrj6xJUHHMA0GCSqGSIb3DQEBCwUAMIGVMQswCQYD +VQQGEwJVUzELMAkGA1UECBMCV0kxEDAOBgNVBAcTB01hZGlzb24xGDAWBgNVBAoT +D1RJRVIgVW5pdmVyc2l0eTESMBAGA1UECxMJSW50ZXJuZXQyMRIwEAYDVQQDEwls +b2NhbGhvc3QxJTAjBgkqhkiG9w0BCQEWFnRpZXItYXBpQGludGVybmV0Mi5lZHUw +HhcNMTcwNDEzMjE0MzA5WhcNMTcwNTEzMjE0MzA5WjCBlTELMAkGA1UEBhMCVVMx +CzAJBgNVBAgTAldJMRAwDgYDVQQHEwdNYWRpc29uMRgwFgYDVQQKEw9USUVSIFVu +aXZlcnNpdHkxEjAQBgNVBAsTCUludGVybmV0MjESMBAGA1UEAxMJbG9jYWxob3N0 +MSUwIwYJKoZIhvcNAQkBFhZ0aWVyLWFwaUBpbnRlcm5ldDIuZWR1MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqwTB3FgmlPOh/aw3wgD3xWxbVxLdsEQ5 +2py0IjLVEfFZyzXMIVjtzhS+9m3U5ER9L9XnXlHZTT46rb3M3f74o8/46xr7KGOb +CVRqhjqWErjiYgGwbVoq1UuC1+AvRXX4adqTuIFaUL4ITMHxlm5v/bhPO9RKdUmK +P9PRNdHeZLpMzo5uKINQUFt3DDI+Xf52fiLj7MbLvrVaabZBNRcwm+atSNai8RGn +6bKC2L5dX9QxQ6JQ/uIUYawHETPEeoPsNkCcxq6VLJKNEpR7Dlt78mpty/N0M3y9 +3h8qODjI6XbL30Ug1iBOI4sum688YhePY/t3VCrWOwkEvffZcDAbRwIDAQABo4H9 +MIH6MB0GA1UdDgQWBBTXvg4SGbM+edkQP4ejVF3T2EPPpTCBygYDVR0jBIHCMIG/ +gBTXvg4SGbM+edkQP4ejVF3T2EPPpaGBm6SBmDCBlTELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgTAldJMRAwDgYDVQQHEwdNYWRpc29uMRgwFgYDVQQKEw9USUVSIFVuaXZl +cnNpdHkxEjAQBgNVBAsTCUludGVybmV0MjESMBAGA1UEAxMJbG9jYWxob3N0MSUw +IwYJKoZIhvcNAQkBFhZ0aWVyLWFwaUBpbnRlcm5ldDIuZWR1ggkA5KWuPrElQccw +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZUN0cEMk61Okf8n+R4W1 +hpVgs7q7cpn77OfCG0d8X5mP+NMzrBCFTwHGpTK2FJAM4/B87Im81F9ydPXPCoVN +dkldZddDU6ZcSwlxQQda/lwoosPu2xX3gE6dkrSV8lNvUAHq3b/RyFG3glU17NUB +EtWP8iDpu2d6LuoBmlhSmA+6TsHxynU1wduNOIkDXisGJF19hExiR9ypEDCITvp3 +rfhiXaakPLTLcuVlwTpc1HUwmFQ4yWTH1pxid7ykjN1QRV2rP98RYCubrDpkd7bY +ApwKcoTbcMmfabl13RvDlrrw9srBk4BDVsBTF2TQtFwBlMl1ZzXW1mkKJ/S22/7t +JQ== +-----END CERTIFICATE----- diff --git a/shib-idp/customized-shibboleth-idp/credentials/jetty.key b/shib-idp/customized-shibboleth-idp/credentials/jetty.key new file mode 100644 index 0000000..e6448e8 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/credentials/jetty.key @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,69574AB259C87F77 + +rViCFIARC3FSSYAyrxeTvbow6OcpiWBs/aPJulxYsuJ0FE8QKwFSeBYkt+fP+5bs +x/9OXImLaOgmcDc72URhlhqDF2bNGQJA/dorkUhe4v7co8kV/o1lGoCnF2irBOD7 +3IDv5SJUzveeocW9GCc5mng1YIHNmHh7rCQScAc17mVUEBWwvx46tQP2BNMA6VoP +dVyfCJ/3UoCPCFwel74EMmh9dC7HyTgt/KweBZIEE17jxLFirS1VwKuZ4idDvXKL +5ZvHkXV73OL8UVgWzgCfyKtKlaiZDq4L9/zgjfPK0+35thihzvOum0fB/m4hVDV9 +8iqcLBScRjWLJKfSANWsj/pQC6waXB2oXq/ulOT221EnUDRkITRp/RdkfDSPMNxj +1X7/tVQhFF+Dle+909FRWHt43jK4edRJnMp982lF9YXGcZVe6D30tOomhTR8ABO/ +ANR0SmoR+M8oBTZOPGeTlE5UjzN24QSGFsLwj6ucuARfZU++NppYYe6TwKivxQow +YmoK6QUsLHQthHUYwPB8ohZgP7YXrFZGxZvQFGehrl4JLdAgsQfm4QhcXBjkIrLA +geaZZT9eopy+36adYlsAII4vVpl5YM1wDTF44IsofJYJj67OYF4qbCUmOe4pls9g +lg8vq2C/fJRfWTb+F7q55/VbsHhvEvQtYnXLIlR8pzpDq9UxYOL6coxpBGvjJ8hh +rmeEMqIpbFs5KjxbLN+AK6ZMi7V2q9neI7mHM98WpGuifdVltTa//qt3IwJl8xA2 +PxqYAZ0Mu87o5yKvKg/yoPHKAjx/OleUUckSH0IZ3Bh+xiaQi9TmcR3ohzFgBxgK +TLXw//WjQZlVyIe/FS1JmeCnxT0WMAG/YZFxfrzFDRjYSRgMAAEHl26fFqODBjGF +nnVM2jWwihWCt3gCOmbg+XuoXuWdWEYq2g0rvgn4J2YUmUQe5MEk/yzx+eBBtoZd +4M/ji3GbxShvvPyerkC0GajrWKfr9uJaomFzAvwP2PVsbeLppDLz6px9hu0wdpeD +ECVIPh85QH6/8prvSLsH9amaURhDHxhbI1XXAFqF4HpaAsQ5y2ZY6Y8O29I0onYR +5qisReWIp/NB5cc8aRcyrOPCyxKGEKmsZk09nINwPMl4Kr6RWMQDIV+8F8AGSc/n +bY8gPZYB5yZfZgPkd5J235JxsF6gJuoM4fV6S3WPeqPCabhTJ1ES5N6ZMynDalQh +2jTYqGhLAKGPqHxNsok+Lr3+u4F+Y7AhK5MW6qIYWx4Gw0upon1PZCCUfyASUn5Z +5EyicZvpRLY4UNnRFDjnsB5xdEay9GwJq9qLGicnfCE1Wf5gQEoU7Sk/7hDcEMVk +6X4Z0XC549r6x8B/+IqVgPMbvdJRl8mYuNUluNQmKgsp4Qv7T3GiJGSISyN3GKlW +AjXKAQ3ucBwfXo0ZRt86/Vdtd8hhMfXqoGLWELiLHDP+ey7nTcSQkTvQrpuergi3 +yx5qs65b3Z2+pxpGltos8YSyJGpgbKkD1n5bWf5TWbv3q1cZ/TyY7fD/aHdK/cGK +CKmojrQ65VT6MALnmjoqftRvgq0bpvfhWiQCG8EFD99kv1toh1gDGQ== +-----END RSA PRIVATE KEY----- diff --git a/shib-idp/customized-shibboleth-idp/credentials/sealer.jks b/shib-idp/customized-shibboleth-idp/credentials/sealer.jks new file mode 100644 index 0000000..b015c5e Binary files /dev/null and b/shib-idp/customized-shibboleth-idp/credentials/sealer.jks differ diff --git a/shib-idp/customized-shibboleth-idp/credentials/sealer.kver b/shib-idp/customized-shibboleth-idp/credentials/sealer.kver new file mode 100644 index 0000000..189c664 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/credentials/sealer.kver @@ -0,0 +1,2 @@ +#Thu Apr 13 21:19:57 UTC 2017 +CurrentVersion=1 diff --git a/shib-idp/customized-shibboleth-idp/metadata/idp-metadata.xml b/shib-idp/customized-shibboleth-idp/metadata/idp-metadata.xml new file mode 100644 index 0000000..746ba46 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/metadata/idp-metadata.xml @@ -0,0 +1,213 @@ + + + + + + + + example.edu + + + + + + + +MIIDDzCCAfegAwIBAgIUNhoGlKP7mWuGizduv8qofntjgygwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE3MDQxMzIxMTk1M1oXDTM3MDQx +MzIxMTk1M1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAks/QokbcrFosPTXL+i2iMFQMfZvoFxgqIXH+xxrpljrL +sglonsbmHGuinnSeywRzfcBB6mEf3BnYzyezP0aB1GJYzItRSd4AoWAx8WblFfgM +ununMmDpfF1dyTxZxRg/vmhN9EttVugsAoynA17RbiF4vVxx3zhNGS0u3MbaYtH1 +kYIdY9xZMR2wvDo584CQc0/20/FooPnlL0I1s2FD6LFEgvl1sux5owL0ELITSTUF +KEkQVxpYoFZhsq6qhWQJfVvT98W4CMVpXgggQilAWAK1QgLxJtyx54Y3YruFkXsy +Yahi04wwaQXmSHDfQbOzy8yzO65on2VjEPGid6PQvQIDAQABo1kwVzAdBgNVHQ4E +FgQUDkHIVBHNiAcr6vQv/P+5PlKjeAcwNgYDVR0RBC8wLYIJbG9jYWxob3N0hiBo +dHRwczovL2xvY2FsaG9zdC9pZHAvc2hpYmJvbGV0aDANBgkqhkiG9w0BAQsFAAOC +AQEAioMgLmAx1nQwFRuiKe9zhHyl9QClOZ/qI1A/pV3QQfItxpnkjecElvpN0MLX +ugmT0kb0tgyIUxOjHd78kSJOkFKmWPv+iSLouaU4/Y3yOW0uUWOwlExKJNegczBC +t1OCtSAyStnYWSMUHk/Lgq4LcNKwjeaVczEbBoJO8nC/Zx0VMvLEsiCeWR+1acpT +BHcQbEkiSJg2WS3krKt0Wq4iL+WjQhkva6zugM0Lxfkyeeg/imcn6A93zr7e6N+/ +SeKGUN2EpNRAAgEVQMVuMuKo7uFzxl2KxmkKckBG4dnDIvco/OE7khgnbNgszaqX +xDkRFm7ZnBhVnGde7W9xjmw+eA== + + + + + + + + + +MIIDEDCCAfigAwIBAgIVAI427wUmgnuo//BnofLWvDbJ5LFZMA0GCSqGSIb3DQEB +CwUAMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNzA0MTMyMTE5NDlaFw0zNzA0 +MTMyMTE5NDlaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANrbeJysRIIfnV4NCBkglD7TnnsBiAP8rmYMlKNzB/8P +lh8T8A/m3ZcSfK5XOooV9HYrJ4zkPYWQfmMTc7gPohtEnVvU2T0BhqXVGItRNPq0 +W8PPyJiaf5cPTej2UU0mvEj6RXzswPmpdabti+hFMK1rwKDGAgyNz7O+ODbtUeEu +84B4OVehjgc0DOeeIMOpCa0ZZURtGcmWa2J/2D8ONtsT6YLzrBHSjea8ahu2MnC0 +3TmQ008yWlXztWiNkccVstQ7WwT1aEon6ni608OtRLZ64UHRmaM6MZHft2DcyYgd +bE7wArKpauLscEzAXRaSdJ4lvtgAdjneACbPbTXpvgUCAwEAAaNZMFcwHQYDVR0O +BBYEFGIsJ7ChRjGGKOTuK+Gf79XdnhazMDYGA1UdEQQvMC2CCWxvY2FsaG9zdIYg +aHR0cHM6Ly9sb2NhbGhvc3QvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQELBQAD +ggEBACzq9+IaRqb44oWy3cX+oQUxBozCOd0dn3cAHn/7U2EAt47YLucaT66K5LYq +VpfqYUYP7FXq9lqpYXQgUNn8DuSDroBzQIOx0YVsS4sRKMv+pTBr6WqrIcbDB9Np +VHqdIxIDD9kxwy8eTEKmeDmjl6ZjGnxa8WjwP6PFXBWJI/vQvxNACqnThIsoKLGv +KPta+ROPrtMMbphsVyHClHlLWp/r015B545FBiasFW+jHzS0/pc8eknNafQ2+chX +GPNfHvJXgg3kDHtW6bydWnWIcCKqaTHFSObgEivuMoCJ0cZVjVEFIpzB3J71qMkc +SJ5zygjKVMFLsbAkzGUFYG1DbBM= + + + + + + + + + +MIIDEDCCAfigAwIBAgIVAK/i6INNo2HZzO676jmYDSMUL8pyMA0GCSqGSIb3DQEB +CwUAMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNzA0MTMyMTE5NTBaFw0zNzA0 +MTMyMTE5NTBaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAJbpEl+MgBuKc4gzGni76gcQO/sa/IupoK2RRsnGEKPS +x7q93ZCe4/TTIR8ZArk7aoTtOrV3s7xhOlvwwlUmQEhIupHtk0EDyWxXV4xK8i99 +3rqNkYcHM/C1iZfoKcoEhwQ5pBVukEgxtSIAfsN7UCE88oTRPhTHV8XJkNjw66Vl +P1MBsO5KQaoKW/Ap86nuhDUHMNFAt/jJ2UFGhEVle4ubckBTltrZDV98m6hHYUws +nCuRGEXusGDsqgEt93C8zRjAVhyNBNp+jQUHCBPy/6TG7AZ0TkPuQ3AxhDt34y6A +dgSaCDmy5sI14oa1S1UagSKt8AXpzC0ao8pwqz+t8usCAwEAAaNZMFcwHQYDVR0O +BBYEFMDqVDwUdJ6wzRLBR0jb3QdW1CFpMDYGA1UdEQQvMC2CCWxvY2FsaG9zdIYg +aHR0cHM6Ly9sb2NhbGhvc3QvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQELBQAD +ggEBAFk6YtMiqkuJXY10aeUhabGgkBdpj6RgHreBvhSmn9UTq/4EGgEWNGNYBVn6 +i9i55GzGCtp7RUAuVUTqH5V3Mbp6drUlNbVex05ypYnYM/wIq5W8EENClugPHepZ +OX0gVUVOeayVUMRHPntNI7HicUDYVvXI/Wjhko/GLqwArNKyenmKlRo1yyedkEKF +fhy9QowXYTvG82i3nu0JS9v/103WApXjIr3eP8LZpGpurOxyG3D+8vW3oML6C1eV +FsLdhy3a5kOvGXbzXHn4tFdVCE3oa72FkrsDHZ8YGHb+s2JFHFRsRzDRSmBRV+LA +3ffQkUP9K+ZGyGQijt6gAEJXcsw= + + + + + + + + + + + + + + + + + + + + + + + example.edu + + + + + + +MIIDDzCCAfegAwIBAgIUNhoGlKP7mWuGizduv8qofntjgygwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE3MDQxMzIxMTk1M1oXDTM3MDQx +MzIxMTk1M1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAks/QokbcrFosPTXL+i2iMFQMfZvoFxgqIXH+xxrpljrL +sglonsbmHGuinnSeywRzfcBB6mEf3BnYzyezP0aB1GJYzItRSd4AoWAx8WblFfgM +ununMmDpfF1dyTxZxRg/vmhN9EttVugsAoynA17RbiF4vVxx3zhNGS0u3MbaYtH1 +kYIdY9xZMR2wvDo584CQc0/20/FooPnlL0I1s2FD6LFEgvl1sux5owL0ELITSTUF +KEkQVxpYoFZhsq6qhWQJfVvT98W4CMVpXgggQilAWAK1QgLxJtyx54Y3YruFkXsy +Yahi04wwaQXmSHDfQbOzy8yzO65on2VjEPGid6PQvQIDAQABo1kwVzAdBgNVHQ4E +FgQUDkHIVBHNiAcr6vQv/P+5PlKjeAcwNgYDVR0RBC8wLYIJbG9jYWxob3N0hiBo +dHRwczovL2xvY2FsaG9zdC9pZHAvc2hpYmJvbGV0aDANBgkqhkiG9w0BAQsFAAOC +AQEAioMgLmAx1nQwFRuiKe9zhHyl9QClOZ/qI1A/pV3QQfItxpnkjecElvpN0MLX +ugmT0kb0tgyIUxOjHd78kSJOkFKmWPv+iSLouaU4/Y3yOW0uUWOwlExKJNegczBC +t1OCtSAyStnYWSMUHk/Lgq4LcNKwjeaVczEbBoJO8nC/Zx0VMvLEsiCeWR+1acpT +BHcQbEkiSJg2WS3krKt0Wq4iL+WjQhkva6zugM0Lxfkyeeg/imcn6A93zr7e6N+/ +SeKGUN2EpNRAAgEVQMVuMuKo7uFzxl2KxmkKckBG4dnDIvco/OE7khgnbNgszaqX +xDkRFm7ZnBhVnGde7W9xjmw+eA== + + + + + + + + + +MIIDEDCCAfigAwIBAgIVAI427wUmgnuo//BnofLWvDbJ5LFZMA0GCSqGSIb3DQEB +CwUAMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNzA0MTMyMTE5NDlaFw0zNzA0 +MTMyMTE5NDlaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANrbeJysRIIfnV4NCBkglD7TnnsBiAP8rmYMlKNzB/8P +lh8T8A/m3ZcSfK5XOooV9HYrJ4zkPYWQfmMTc7gPohtEnVvU2T0BhqXVGItRNPq0 +W8PPyJiaf5cPTej2UU0mvEj6RXzswPmpdabti+hFMK1rwKDGAgyNz7O+ODbtUeEu +84B4OVehjgc0DOeeIMOpCa0ZZURtGcmWa2J/2D8ONtsT6YLzrBHSjea8ahu2MnC0 +3TmQ008yWlXztWiNkccVstQ7WwT1aEon6ni608OtRLZ64UHRmaM6MZHft2DcyYgd +bE7wArKpauLscEzAXRaSdJ4lvtgAdjneACbPbTXpvgUCAwEAAaNZMFcwHQYDVR0O +BBYEFGIsJ7ChRjGGKOTuK+Gf79XdnhazMDYGA1UdEQQvMC2CCWxvY2FsaG9zdIYg +aHR0cHM6Ly9sb2NhbGhvc3QvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQELBQAD +ggEBACzq9+IaRqb44oWy3cX+oQUxBozCOd0dn3cAHn/7U2EAt47YLucaT66K5LYq +VpfqYUYP7FXq9lqpYXQgUNn8DuSDroBzQIOx0YVsS4sRKMv+pTBr6WqrIcbDB9Np +VHqdIxIDD9kxwy8eTEKmeDmjl6ZjGnxa8WjwP6PFXBWJI/vQvxNACqnThIsoKLGv +KPta+ROPrtMMbphsVyHClHlLWp/r015B545FBiasFW+jHzS0/pc8eknNafQ2+chX +GPNfHvJXgg3kDHtW6bydWnWIcCKqaTHFSObgEivuMoCJ0cZVjVEFIpzB3J71qMkc +SJ5zygjKVMFLsbAkzGUFYG1DbBM= + + + + + + + + + +MIIDEDCCAfigAwIBAgIVAK/i6INNo2HZzO676jmYDSMUL8pyMA0GCSqGSIb3DQEB +CwUAMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xNzA0MTMyMTE5NTBaFw0zNzA0 +MTMyMTE5NTBaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAJbpEl+MgBuKc4gzGni76gcQO/sa/IupoK2RRsnGEKPS +x7q93ZCe4/TTIR8ZArk7aoTtOrV3s7xhOlvwwlUmQEhIupHtk0EDyWxXV4xK8i99 +3rqNkYcHM/C1iZfoKcoEhwQ5pBVukEgxtSIAfsN7UCE88oTRPhTHV8XJkNjw66Vl +P1MBsO5KQaoKW/Ap86nuhDUHMNFAt/jJ2UFGhEVle4ubckBTltrZDV98m6hHYUws +nCuRGEXusGDsqgEt93C8zRjAVhyNBNp+jQUHCBPy/6TG7AZ0TkPuQ3AxhDt34y6A +dgSaCDmy5sI14oa1S1UagSKt8AXpzC0ao8pwqz+t8usCAwEAAaNZMFcwHQYDVR0O +BBYEFMDqVDwUdJ6wzRLBR0jb3QdW1CFpMDYGA1UdEQQvMC2CCWxvY2FsaG9zdIYg +aHR0cHM6Ly9sb2NhbGhvc3QvaWRwL3NoaWJib2xldGgwDQYJKoZIhvcNAQELBQAD +ggEBAFk6YtMiqkuJXY10aeUhabGgkBdpj6RgHreBvhSmn9UTq/4EGgEWNGNYBVn6 +i9i55GzGCtp7RUAuVUTqH5V3Mbp6drUlNbVex05ypYnYM/wIq5W8EENClugPHepZ +OX0gVUVOeayVUMRHPntNI7HicUDYVvXI/Wjhko/GLqwArNKyenmKlRo1yyedkEKF +fhy9QowXYTvG82i3nu0JS9v/103WApXjIr3eP8LZpGpurOxyG3D+8vW3oML6C1eV +FsLdhy3a5kOvGXbzXHn4tFdVCE3oa72FkrsDHZ8YGHb+s2JFHFRsRzDRSmBRV+LA +3ffQkUP9K+ZGyGQijt6gAEJXcsw= + + + + + + + + + + + + + diff --git a/shib-idp/customized-shibboleth-idp/metadata/web-app.xml b/shib-idp/customized-shibboleth-idp/metadata/web-app.xml new file mode 100644 index 0000000..0aeeee1 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/metadata/web-app.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + MIID6zCCAlOgAwIBAgIJAPytI1UztGxDMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV BAMTDGY4NWM1NTNjMTQ5NjAeFw0xNzA0MTUyMjMwMDBaFw0yNzA0MTMyMjMwMDBa MBcxFTATBgNVBAMTDGY4NWM1NTNjMTQ5NjCCAaIwDQYJKoZIhvcNAQEBBQADggGP ADCCAYoCggGBAMffMetKpvMjTIDwDvztGCCMiY7od0QMwbmAKuMhIiU/eyqc1/2Z VFlwlABAq7s6fGZ+fbqbGNaP471K+KFme8gpFKWeAJ3ITGp2mIHHMqvgQXLantvE yF2fQadJtJW/10r5xvkgJBndOkNANJSbMq2vJuptU3wOYkyflxjRPfRjQmuy+1zS sPyW+cM1svjqq5/GO8Q70hRgko7Z/Y9KIdbT7/ULgGd7OoAhYBjJvSTTLZM0Y3FJ pSZXODEN0g2ZBBDqBXl9q1obQejVuzsFROZC7BN6t0WcIeacCIha3VgebbfRO5Cv FBGvUprqj9w/kkq5VkHDAwMxqdJ03GKq9T42wybuF86++1rQd95D+qhxUz79fnCJ JlW0TAHEJ86Wj04mb981xfIvztW2oyyj77hUljhddS6SL1UbunRa3f5ciOm4pdjK n/fw5unfs0YvLNPrHwcXUakf4ldCRuwNGJhqGVlcwp89Dou5VhWijEL4xz6kBPWU ECZD/JvWY2zL0wIDAQABozowODAXBgNVHREEEDAOggxmODVjNTUzYzE0OTYwHQYD VR0OBBYEFF1CDIxF0OQoxdFdJGjhqccMfJQkMA0GCSqGSIb3DQEBCwUAA4IBgQBE ofEja+2tqIAnTd2gGhA2oyGoC1uyxZIRtKyrakhuhpWpmQ4xgfTEcUGnACxZfjhD j4CvxwnJpEIqdVS3c0Bje2sep3Flr87jPJh5OWvmssoDNqQ+QANLBxV8MhmKsM8Z ZgVO+Fm83OciaKnxD0a9MJ7qtZPA1g8V7NGoeGzg9IwowuVg/wC1frCw4Pw5OD4K /GcgJVQGhkPxvn8z3MoDLv6y2BilQB0WCoxJ/rvVbVmPWU79srCwot74RFkPHRqj UhoUIht1wd3F+wTKHJ0cT2lQ1YRBOirOX43Nzc1K2fM0DQtlH/X42F4K+6qJQ8Cx FeuyEki6GgwLQ7xTblkmHCtMmRLBjjTlfqFSGFPy+MBE8UQzI08RRMyYtwR9/Z3T Rr+2DYvzBFoBQtsJhYb318Pjvs1Pr4uNzM5cuDwUQ6FQLRaCRAzSYLwUqCP0gVge jC3D/ZtBqA7uP5DQGPh8SXEH8Ivax4pmVSKX8wbTQBeUirVoOSw7/FMuC56bv48= + + + + + + + MIID6zCCAlOgAwIBAgIJAPytI1UztGxDMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV BAMTDGY4NWM1NTNjMTQ5NjAeFw0xNzA0MTUyMjMwMDBaFw0yNzA0MTMyMjMwMDBa MBcxFTATBgNVBAMTDGY4NWM1NTNjMTQ5NjCCAaIwDQYJKoZIhvcNAQEBBQADggGP ADCCAYoCggGBAMffMetKpvMjTIDwDvztGCCMiY7od0QMwbmAKuMhIiU/eyqc1/2Z VFlwlABAq7s6fGZ+fbqbGNaP471K+KFme8gpFKWeAJ3ITGp2mIHHMqvgQXLantvE yF2fQadJtJW/10r5xvkgJBndOkNANJSbMq2vJuptU3wOYkyflxjRPfRjQmuy+1zS sPyW+cM1svjqq5/GO8Q70hRgko7Z/Y9KIdbT7/ULgGd7OoAhYBjJvSTTLZM0Y3FJ pSZXODEN0g2ZBBDqBXl9q1obQejVuzsFROZC7BN6t0WcIeacCIha3VgebbfRO5Cv FBGvUprqj9w/kkq5VkHDAwMxqdJ03GKq9T42wybuF86++1rQd95D+qhxUz79fnCJ JlW0TAHEJ86Wj04mb981xfIvztW2oyyj77hUljhddS6SL1UbunRa3f5ciOm4pdjK n/fw5unfs0YvLNPrHwcXUakf4ldCRuwNGJhqGVlcwp89Dou5VhWijEL4xz6kBPWU ECZD/JvWY2zL0wIDAQABozowODAXBgNVHREEEDAOggxmODVjNTUzYzE0OTYwHQYD VR0OBBYEFF1CDIxF0OQoxdFdJGjhqccMfJQkMA0GCSqGSIb3DQEBCwUAA4IBgQBE ofEja+2tqIAnTd2gGhA2oyGoC1uyxZIRtKyrakhuhpWpmQ4xgfTEcUGnACxZfjhD j4CvxwnJpEIqdVS3c0Bje2sep3Flr87jPJh5OWvmssoDNqQ+QANLBxV8MhmKsM8Z ZgVO+Fm83OciaKnxD0a9MJ7qtZPA1g8V7NGoeGzg9IwowuVg/wC1frCw4Pw5OD4K /GcgJVQGhkPxvn8z3MoDLv6y2BilQB0WCoxJ/rvVbVmPWU79srCwot74RFkPHRqj UhoUIht1wd3F+wTKHJ0cT2lQ1YRBOirOX43Nzc1K2fM0DQtlH/X42F4K+6qJQ8Cx FeuyEki6GgwLQ7xTblkmHCtMmRLBjjTlfqFSGFPy+MBE8UQzI08RRMyYtwR9/Z3T Rr+2DYvzBFoBQtsJhYb318Pjvs1Pr4uNzM5cuDwUQ6FQLRaCRAzSYLwUqCP0gVge jC3D/ZtBqA7uP5DQGPh8SXEH8Ivax4pmVSKX8wbTQBeUirVoOSw7/FMuC56bv48= + + + + + + + + + + + + + + + + + + + + + TIER API and Ent Reg Working Group + tier-api@internet2.edu + + diff --git a/shib-idp/customized-shibboleth-idp/views/client-storage/client-storage-read.vm b/shib-idp/customized-shibboleth-idp/views/client-storage/client-storage-read.vm new file mode 100644 index 0000000..1993c14 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/client-storage/client-storage-read.vm @@ -0,0 +1,53 @@ +## +## Velocity template to read from local storage. +## +## Velocity context will contain the following properties +## flowExecutionUrl - the form action location +## flowRequestContext - the Spring Web Flow RequestContext +## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl) +## profileRequestContext - root of context tree +## loadContext - context with details about the storage keys to load +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +#set ($title = $springMacroRequestContext.getMessage("idp.title", "Web Login Service")) +#set ($titleSuffix = $springMacroRequestContext.getMessage("idp.client-storage-read.suffix", "Loading Session Information")) +## + + + + + + $title - $titleSuffix + + + + +
+
+
+

$title - $titleSuffix

+
+
+ $springMacroRequestContext.getMessage("idp.client-storage-read.text", "Loading login session information from the browser...") +
+ + #parse( "client-storage/read.vm" ) +
+
+ +
+
+ + diff --git a/shib-idp/customized-shibboleth-idp/views/client-storage/client-storage-write.vm b/shib-idp/customized-shibboleth-idp/views/client-storage/client-storage-write.vm new file mode 100644 index 0000000..4b92d6b --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/client-storage/client-storage-write.vm @@ -0,0 +1,53 @@ +## +## Velocity template to write to local storage. +## +## Velocity context will contain the following properties +## flowExecutionUrl - the form action location +## flowRequestContext - the Spring Web Flow RequestContext +## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl) +## profileRequestContext - root of context tree +## saveContext - context with details about the storage data to save +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +#set ($title = $springMacroRequestContext.getMessage("idp.title", "Web Login Service")) +#set ($titleSuffix = $springMacroRequestContext.getMessage("idp.client-storage-write.suffix", "Saving Session Information...")) +## + + + + + + $title - $titleSuffix + + + + +
+
+
+

$title - $titleSuffix

+
+
+ $springMacroRequestContext.getMessage("idp.client-storage-write.text", "Saving login session information to the browser...") +
+ + #parse( "client-storage/write.vm" ) +
+
+ +
+
+ + \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/views/duo.vm b/shib-idp/customized-shibboleth-idp/views/duo.vm new file mode 100644 index 0000000..cf4f96a --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/duo.vm @@ -0,0 +1,83 @@ +## +## Velocity Template for Duo login view-state +## +## Velocity context will contain the following properties +## flowExecutionUrl - the form action location +## flowRequestContext - the Spring Web Flow RequestContext +## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl) +## profileRequestContext - root of context tree +## authenticationContext - context with authentication request information +## rpUIContext - the context with SP UI information from the metadata +## canonicalUsername - name of user passed to Duo +## duoHost - API hostname for Duo frame +## duoRequest - signed Duo request message +## duoScriptPath - path to Duo JavaScript source +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +## custom - arbitrary object injected by deployer +## + + + + + + + #springMessageText("idp.title", "Web Login Service") + + + + +
+
+
+ #springMessageText( +
+ +
+
+ +

#springMessageText("idp.login.duoRequired", "Authentication with Duo is required for the requested service.")

+ + + + +
+ + +
+ +

+ #springMessageText("idp.login.duoCancel", "Cancel this Request") +

+
+ +
+
+ +
+ +
+
+ + diff --git a/shib-idp/customized-shibboleth-idp/views/error.vm b/shib-idp/customized-shibboleth-idp/views/error.vm new file mode 100644 index 0000000..dcb8e2b --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/error.vm @@ -0,0 +1,73 @@ +## +## Velocity Template for error end-state +## +## Velocity context will contain the following properties +## flowRequestContext - the Spring Web Flow RequestContext +## profileRequestContext - root of context tree +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +## custom - arbitrary object injected by deployer +## +#set ($title = $springMacroRequestContext.getMessage("idp.title", "Web Login Service")) +#set ($defaultTitleSuffix = $springMacroRequestContext.getMessage("idp.title.suffix", "Error")) +## +#if ($flowRequestContext) + ## This handles flow events, the most common case. + #set ($eventId = $flowRequestContext.getCurrentEvent().getId()) + #set ($eventKey = $springMacroRequestContext.getMessage("$eventId", "error")) + #set ($titleSuffix = $springMacroRequestContext.getMessage("${eventKey}.title", "$defaultTitleSuffix")) + #set ($message = $springMacroRequestContext.getMessage("${eventKey}.message", "$defaultTitleSuffix: $eventId")) + #if ($eventId == "AccessDenied" or $eventId == "ContextCheckDenied") + $response.setStatus(403) + #elseif ($eventId == "AttributeReleaseRejected" || $eventId == "TermsRejected") + $response.setStatus(200) + #elseif ($eventKey == "unexpected" || $eventKey == "runtime-error" || $eventKey == "error") + $response.setStatus(500) + #else + $response.setStatus(400) + #end +#elseif ($exception) + ## This handles exceptions that reach the Spring-MVC exception handler. + #set ($eventId = $exception.getClass().getSimpleName()) + #set ($eventKey = $springMacroRequestContext.getMessage("$eventId", "error")) + #set ($titleSuffix = $springMacroRequestContext.getMessage("${eventKey}.title", "$defaultTitleSuffix")) + #set ($message = $springMacroRequestContext.getMessage("${eventKey}.message", "$defaultTitleSuffix: $eventId")) +#else + ## This is a catch-all that theoretically shouldn't happen? + #set ($titleSuffix = $defaultTitleSuffix) + #set ($message = $springMacroRequestContext.getMessage("idp.message", "An unidentified error occurred.")) +#end +## + + + + + + $title - $titleSuffix + + + + +
+
+
+ #springMessageText( +

$title - $titleSuffix

+
+ +
+ #evaluate($message) +
+
+ +
+ +
+ +
+ + \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/views/intercept/attribute-release.vm b/shib-idp/customized-shibboleth-idp/views/intercept/attribute-release.vm new file mode 100644 index 0000000..0b74551 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/intercept/attribute-release.vm @@ -0,0 +1,158 @@ +## +## Velocity Template for DisplayAttributeReleasePage view-state +## +## Velocity context will contain the following properties : +## +## attributeReleaseContext - context holding consentable attributes +## attributeReleaseFlowDescriptor - attribute consent flow descriptor +## attributeDisplayNameFunction - function to display attribute name +## consentContext - context representing the state of a consent flow +## encoder - HTMLEncoder class +## flowExecutionKey - SWF execution key (this is built into the flowExecutionUrl) +## flowExecutionUrl - form action location +## flowRequestContext - Spring Web Flow RequestContext +## profileRequestContext - OpenSAML profile request context +## request - HttpServletRequest +## response - HttpServletResponse +## rpUIContext - context with SP UI information from the metadata +## environment - Spring Environment object for property resolution +#set ($serviceName = $rpUIContext.serviceName) +#set ($serviceDescription = $rpUIContext.serviceDescription) +#set ($informationURL = $rpUIContext.informationURL) +#set ($privacyStatementURL = $rpUIContext.privacyStatementURL) +#set ($rpOrganizationLogo = $rpUIContext.getLogo()) +#set ($rpOrganizationName = $rpUIContext.organizationName) +#set ($replaceDollarWithNewline = true) +## + + + + + + + #springMessageText("idp.attribute-release.title", "Information Release") + + +
+
+
+ + #if ($rpOrganizationLogo) + + #end +
+ #if ($serviceName) +

+ #springMessageText("idp.attribute-release.serviceNameLabel", "You are about to access the service:")
+ $serviceName + #if ($rpOrganizationName) + #springMessageText("idp.attribute-release.of", "of") $encoder.encodeForHTML($rpOrganizationName) + #end +

+ #end + #if ($serviceDescription) +

+ #springMessageText("idp.attribute-release.serviceDescriptionLabel", "Description as provided by this service:")
+ $encoder.encodeForHTML($serviceDescription) +
+

+ #end + #if ($informationURL) +

+ #springMessageText("idp.attribute-release.informationURLLabel", "Additional information about the service") +

+ #end +
+ + + + + + + + #foreach ($attribute in $attributeReleaseContext.getConsentableAttributes().values()) + + + + + + #end + +
+ #springMessageText("idp.attribute-release.attributesHeader", "Information to be Provided to Service") +
$encoder.encodeForHTML($attributeDisplayNameFunction.apply($attribute)) + #foreach ($value in $attribute.values) + #if ($replaceDollarWithNewline) + #set ($encodedValue = $encoder.encodeForHTML($value.getDisplayValue()).replaceAll($encoder.encodeForHTML("$"),"
")) + #else + #set ($encodedValue = $encoder.encodeForHTML($value.getDisplayValue())) + #end + #if ($attributeReleaseFlowDescriptor.perAttributeConsentEnabled) + + #else + $encodedValue + #end +
+ #end +
+ #if ($attributeReleaseFlowDescriptor.perAttributeConsentEnabled) + #set ($inputType = "checkbox") + #else + #set ($inputType = "hidden") + #end + +
+
+ #if ($privacyStatementURL) +

+ #springMessageText("idp.attribute-release.privacyStatementURLLabel", "Data privacy information of the service") +

+ #end +
+

+ #springMessageText("idp.attribute-release.confirmationQuestion", "The information above would be shared with the service if you proceed. Do you agree to release this information to the service every time you access it?") +

+ #if ($attributeReleaseFlowDescriptor.doNotRememberConsentAllowed || $attributeReleaseFlowDescriptor.globalConsentAllowed) +
+ #springMessageText("idp.attribute-release.consentMethod", "Select an information release consent duration:") + #end + #if ($attributeReleaseFlowDescriptor.doNotRememberConsentAllowed) +

+ + +

    +
  • #springMessageText("idp.attribute-release.doNotRememberConsentItem", "I agree to send my information this time.")
  • +
+

+ #end + #if ($attributeReleaseFlowDescriptor.doNotRememberConsentAllowed || $attributeReleaseFlowDescriptor.globalConsentAllowed) +

+ + +

    +
  • #springMessageText("idp.attribute-release.rememberConsentItem", "I agree that the same information will be sent automatically to this service in the future.")
  • +
+

+ #end + #if ($attributeReleaseFlowDescriptor.globalConsentAllowed) +

+ + +

    +
  • #springMessageText("idp.attribute-release.globalConsentItem", "I agree that all of my information will be released to any service.")
  • +
+

+ #end + #if ($attributeReleaseFlowDescriptor.doNotRememberConsentAllowed || $attributeReleaseFlowDescriptor.globalConsentAllowed) + #springMessageText("idp.attribute-release.consentMethodRevoke", "This setting can be revoked at any time with the checkbox on the login page.") +
+ #end +

+ + +

+
+
+
+ + diff --git a/shib-idp/customized-shibboleth-idp/views/intercept/expiring-password.vm b/shib-idp/customized-shibboleth-idp/views/intercept/expiring-password.vm new file mode 100644 index 0000000..4395844 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/intercept/expiring-password.vm @@ -0,0 +1,54 @@ +## +## Velocity Template for expiring password view +## +## Velocity context will contain the following properties +## flowExecutionUrl - the form action location +## flowRequestContext - the Spring Web Flow RequestContext +## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl) +## profileRequestContext - root of context tree +## authenticationContext - context with authentication request information +## authenticationErrorContext - context with login error state +## authenticationWarningContext - context with login warning state +## ldapResponseContext - context with LDAP state (if using native LDAP) +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +## custom - arbitrary object injected by deployer +## + + + + + + #springMessageText("idp.title", "Web Login Service") + + + + + +
+
+
+ #springMessageText( +

#springMessageText("idp.login.expiringSoon", "Your password will be expiring soon!")

+
+ +
+

#springMessageText("idp.login.changePassword", "To create a new password now, go to") + #.

+

#springMessageText("idp.login.proceedBegin", "Your login will proceed in 20 seconds or you may click") + #springMessageText("idp.login.proceedHere", "here") + #springMessageText("idp.login.proceedEnd", "to continue").

+
+
+ +
+ +
+ +
+ + \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/views/intercept/terms-of-use.vm b/shib-idp/customized-shibboleth-idp/views/intercept/terms-of-use.vm new file mode 100644 index 0000000..1bf12c7 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/intercept/terms-of-use.vm @@ -0,0 +1,67 @@ +## +## Velocity Template for DisplayTermsOfUsePage view-state +## +## Velocity context will contain the following properties : +## +## encoder - HTMLEncoder class +## flowExecutionKey - SWF execution key (this is built into the flowExecutionUrl) +## flowExecutionUrl - form action location +## flowRequestContext - Spring Web Flow RequestContext +## request - HttpServletRequest +## response - HttpServletResponse +## rpUIContext - context with SP UI information from the metadata +## termsOfUseId - terms of use ID to lookup message strings +## environment - Spring Environment object for property resolution +#set ($serviceName = $rpUIContext.serviceName) +#set ($rpOrganizationLogo = $rpUIContext.getLogo()) +## + + + + + + + #springMessageText("${termsOfUseId}.title", "Terms of Use") + + +
+
+ + #if ($rpOrganizationLogo) + + #end +
+ #if ($rpOrganizationLogo) +
+

#springMessageText("${termsOfUseId}.title", "Terms of Use")

+
+ #end +
+ #springMessageText("${termsOfUseId}.text", "Terms of Use Text...") +
+
+
+
+ +
+
+
+
+ + + #if ($requireCheckbox) +

#springMessageText("idp.terms-of-use.required", "Please check this box if you want to proceed.")

+ #end + +
+
+
+
+
+ +
+
+ + diff --git a/shib-idp/customized-shibboleth-idp/views/login-error.vm b/shib-idp/customized-shibboleth-idp/views/login-error.vm new file mode 100644 index 0000000..44676b3 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/login-error.vm @@ -0,0 +1,24 @@ +## Velocity Template for login error message production, included by login.vm +## +## authenticationErrorContext - context containing error data, if available +## +#if ($authenticationErrorContext && $authenticationErrorContext.getClassifiedErrors().size() > 0 && $authenticationErrorContext.getClassifiedErrors().iterator().next() != "ReselectFlow") + ## This handles errors that are classified by the message maps in the authentication config. + #set ($eventId = $authenticationErrorContext.getClassifiedErrors().iterator().next()) + #set ($eventKey = $springMacroRequestContext.getMessage("$eventId", "login")) + #set ($message = $springMacroRequestContext.getMessage("${eventKey}.message", "Login Failure: $eventId")) +#elseif ($authenticationErrorContext && $authenticationErrorContext.getExceptions().size() > 0) + ## This handles login exceptions that are left unclassified. + #set ($loginException = $authenticationErrorContext.getExceptions().get(0)) + #if ($loginException.getMessage()) + #set ($message = "Login Failure: $loginException.getMessage()") + #else + #set ($message = $loginException.toString()) + #end +#end + +#if ($message) +
+

$encoder.encodeForHTML($message)

+
+#end diff --git a/shib-idp/customized-shibboleth-idp/views/login.vm b/shib-idp/customized-shibboleth-idp/views/login.vm new file mode 100644 index 0000000..c421a99 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/login.vm @@ -0,0 +1,140 @@ +## +## Velocity Template for DisplayUsernamePasswordPage view-state +## +## Velocity context will contain the following properties +## flowExecutionUrl - the form action location +## flowRequestContext - the Spring Web Flow RequestContext +## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl) +## profileRequestContext - root of context tree +## authenticationContext - context with authentication request information +## authenticationErrorContext - context with login error state +## authenticationWarningContext - context with login warning state +## ldapResponseContext - context with LDAP state (if using native LDAP) +## rpUIContext - the context with SP UI information from the metadata +## extendedAuthenticationFlows - collection of "extended" AuthenticationFlowDescriptor objects +## passwordPrincipals - contents of the shibboleth.authn.Password.PrincipalOverride bean +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +## custom - arbitrary object injected by deployer +## +#set ($rpContext = $profileRequestContext.getSubcontext('net.shibboleth.idp.profile.context.RelyingPartyContext')) +#set ($username = $authenticationContext.getSubcontext('net.shibboleth.idp.authn.context.UsernamePasswordContext', true).getUsername()) +#set ($passwordEnabled = false) +#if (!$passwordPrincipals or $passwordPrincipals.isEmpty() or $authenticationContext.isAcceptable($passwordPrincipals)) + #set ($passwordEnabled = true) +#end +## + + + + + + #springMessageText("idp.title", "Web Login Service") + + + +
+
+
+ #springMessageText( +
+ +
+
+ #parse("login-error.vm") + +
+ + #set ($serviceName = $rpUIContext.serviceName) + #if ($serviceName && !$rpContext.getRelyingPartyId().contains($serviceName)) + + #springMessageText("idp.login.loginTo", "Login to") $encoder.encodeForHTML($serviceName) + + #end + + #if ($passwordEnabled) +
+ + +
+ +
+ + +
+ +
+ + +
+ #end + +
+ + +
+ + #if ($passwordEnabled) +
+ +
+ #end + + #foreach ($extFlow in $extendedAuthenticationFlows) + #if ($authenticationContext.isAcceptable($extFlow) and $extFlow.apply(profileRequestContext)) +
+ +
+ #end + #end +
+ + #* + // + // SP Description & Logo (optional) + // These idpui lines will display added information (if available + // in the metadata) about the Service Provider (SP) that requested + // authentication. These idpui lines are "active" in this example + // (not commented out) - this extra SP info will be displayed. + // Remove or comment out these lines to stop the display of the + // added SP information. + // + *# + #set ($logo = $rpUIContext.getLogo()) + #if ($logo) + $encoder.encodeForHTMLAttribute($serviceName) + #end + #set ($desc = $rpUIContext.getServiceDescription()) + #if ($desc) + $encoder.encodeForHTML($desc) + #end + +
+ +
+
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/views/logout-complete.vm b/shib-idp/customized-shibboleth-idp/views/logout-complete.vm new file mode 100644 index 0000000..d780252 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/logout-complete.vm @@ -0,0 +1,59 @@ +## +## Velocity Template for logout flow's concluding view-state (no propagation) +## +## Velocity context will contain the following properties +## flowExecutionUrl - the form action location +## flowRequestContext - the Spring Web Flow RequestContext +## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl) +## profileRequestContext - root of context tree +## logoutContext - context with SPSession details for logout operation +## multiRPContext - context with RelyingPartyContexts and possibly SP UI information from the metadata +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +## custom - arbitrary object injected by deployer +## + + + + + + #springMessageText("idp.title", "Web Login Service") + + + + +
+
+
+ #springMessageText( +
+ +
+
+

#springMessageText("idp.logout.local", "You elected not to log out of all the applications accessed during your session.")

+
+ +
+
+ + + #if ( $profileRequestContext.getProfileId().contains("saml2/logout") ) + + #end + +
+ +
+
+ + + \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/views/logout-propagate.vm b/shib-idp/customized-shibboleth-idp/views/logout-propagate.vm new file mode 100644 index 0000000..86b3fa1 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/logout-propagate.vm @@ -0,0 +1,58 @@ +## +## Velocity Template for logout flow's concluding view-state (with propagation) +## +## Velocity context will contain the following properties +## flowExecutionUrl - the form action location +## flowRequestContext - the Spring Web Flow RequestContext +## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl) +## profileRequestContext - root of context tree +## logoutContext - context with SPSession details for logout operation +## multiRPContext - context with RelyingPartyContexts and possibly SP UI information from the metadata +## htmlEncoder - HTMLEncoder class +## urlEncoder - urlEncoder class +## codecUtil - CodecUtil class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +## custom - arbitrary object injected by deployer +## + + + + + + #springMessageText("idp.title", "Web Login Service") + + + + + +
+
+
+ #springMessageText( +
+ +
+
+

#springMessageText("idp.logout.attempt", "Attempting to log out of the following services:")

+ #parse("logout/propagate.vm") +
+ +
+
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/views/logout.vm b/shib-idp/customized-shibboleth-idp/views/logout.vm new file mode 100644 index 0000000..2342855 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/logout.vm @@ -0,0 +1,91 @@ +## +## Velocity Template for logout flow's starting view-state +## +## Velocity context will contain the following properties +## flowExecutionUrl - the form action location +## flowRequestContext - the Spring Web Flow RequestContext +## flowExecutionKey - the SWF execution key (this is built into the flowExecutionUrl) +## profileRequestContext - root of context tree +## logoutContext - context with SPSession details for logout operation +## multiRPContext - context with RelyingPartyContexts and possibly SP UI information from the metadata +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +## custom - arbitrary object injected by deployer +## + + + + + + #if ( $logoutContext and !$logoutContext.getSessionMap().isEmpty() ) + + #end + #springMessageText("idp.title", "Web Login Service") + + + + +
+
+
+ #springMessageText( +
+ +
+
+

This page is displayed when a logout operation at the Identity Provider completes. This page is an example + and should be customized. It is not fully internationalized because the presentation will be a highly localized + decision, and we don't have a good suggestion for a default.

+
+ + #if ( $logoutContext and !$logoutContext.getSessionMap().isEmpty() ) +

#springMessageText("idp.logout.ask", "Would you like to attempt to log out of all services accessed during your session? Please select Yes or No to ensure the logout operation completes, or wait a few seconds for Yes.")

+
+ +
+ + +
+ +
+

#springMessageText("idp.logout.contactServices", "If you proceed, the system will attempt to contact the following services:")

+
    + #foreach ($sp in $logoutContext.getSessionMap().keySet()) + #set ($rpCtx = $multiRPContext.getRelyingPartyContextById($sp)) + #if ($rpCtx) + #set ($rpUIContext = $rpCtx.getSubcontext("net.shibboleth.idp.ui.context.RelyingPartyUIContext")) + #end + #if ($rpUIContext and $rpUIContext.getServiceName()) +
  1. $encoder.encodeForHTML($rpUIContext.getServiceName())
  2. + #else +
  3. $encoder.encodeForHTML($sp)
  4. + #end + #end +
+ #else +

#springMessageText("idp.logout.complete", "The logout operation is complete, and no other services appear to have been accessed during this session.")

+ + + #end + +
+ +
+
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/views/spnego-unavailable.vm b/shib-idp/customized-shibboleth-idp/views/spnego-unavailable.vm new file mode 100644 index 0000000..3673f02 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/spnego-unavailable.vm @@ -0,0 +1,49 @@ +## +## Velocity Template for SPNEGO unauthorized page +## +## This is not a Spring Webflow view, but a special view internal to the +## SPNEGO login flow, so it doesn't contain all of the usual SWF variables. +## +## Velocity context will contain the following properties +## encoder - HTMLEncoder class +## request - HttpServletRequest +## response - HttpServletResponse +## profileRequestContext - root of context tree +## errorUrl - URL to call to indicate error and return back to the login flow +## +#set ($eventKey = $springMacroRequestContext.getMessage("SPNEGOUnavailable", "spnego-unavailable")) + + + + + + #springMessageText("idp.title", "Web Login Sevice") - #springMessageText("${eventKey}.title", "Error") + + + + +
+
+
+ #springMessageText( +

#springMessageText("idp.title", "Web Login Sevice") - #springMessage("idp.title.suffix", "Error")

+
+ +
+ #springMessageText("${eventKey}.message", "Your web browser doesn't support authentication with your desktop login credentials.") + +
+
+ +
+ +
+
+ + diff --git a/shib-idp/customized-shibboleth-idp/views/user-prefs.vm b/shib-idp/customized-shibboleth-idp/views/user-prefs.vm new file mode 100644 index 0000000..8de0503 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/views/user-prefs.vm @@ -0,0 +1,60 @@ +## +## Velocity Template for user preferences view +## +## Velocity context will contain the following properties +## request - HttpServletRequest +## response - HttpServletResponse +## environment - Spring Environment object for property resolution +## custom - arbitrary object injected by deployer +## + + + + + + #springMessageText("idp.userprefs.title", "Web Login Service") - #springMessageText("idp.userprefs.title.suffix", "Login Preferences") + + + + +
+
+
+ #springMessageText( +

#springMessageText("idp.title", "Web Login Service") - #springMessageText("idp.userprefs.title.suffix", "Login Preferences")

+

+ #springMessage("idp.userprefs.info") +

+
+ + + + +
+ +
+ +
+
+ + + diff --git a/shib-idp/customized-shibboleth-idp/webapp/css/consent.css b/shib-idp/customized-shibboleth-idp/webapp/css/consent.css new file mode 100644 index 0000000..5daabee --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/webapp/css/consent.css @@ -0,0 +1,150 @@ +.box { + width:600px; + margin-left: auto; + margin-right: auto; + margin-top: 50px; + background-color: white; + -webkit-box-shadow: 1px 1px 15px #999999; + -moz-box-shadow: 1px 1px 15px #999999; + box-shadow: 1px 1px 15px #999999; + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + border-radius: 8px; + overflow: auto; + padding: 1.268em; +} + +body { + font-family:Verdana, Geneva, sans-serif; + font-size: 12px; +} + +h1 { + font-size: 13px; + padding-bottom: 12px; +} + +a { + color: #00247D; + text-decoration: underline; +} + +a:visited { + color: #00247D; + text-decoration: underline; +} + +a:focus, a:hover, a:active { + color: #F39800; + text-decoration: underline; +} + +#tou-content { + font-family:monospace; + width: 95%; + border: solid 1px #666; + margin: 4px; + padding: 10px; + overflow: hidden; +} + +#tou-content li{ + margin-bottom:10px; +} + +#tou-acceptance { + width: 95%; + border: solid 1px #666; + background-color: #F0F0F0; + margin: 4px; + padding: 10px; + text-align: left; + overflow: hidden; +} + +.service_name { + font-weight: bold; +} + +.service_description { + font-style: italic; +} + +.organization_name { +} + +#attributeRelease-consent { + width: 95%; + border: solid 1px #666; + background-color: #F0F0F0; + margin: 4px; + overflow: hidden; +} + +#attributeRelease { + width: 95%; + margin: 4px; + border: solid 1px black; + overflow: auto; +} + +#attributeRelease table { + border-collapse: collapse; + border: none 0px white; + width: 100%; +} + +#attributeRelease td { + padding: 3px 7px; + vertical-align: top; +} + +#attributeRelease th { + text-align: left; + font-size: 18px; + padding: 5px 7px; + background-color:#00247D; + color: white; +} + +#attributeRelease tr:nth-of-type(even) { + background-color: #E4E5E3; +} + +.federation_logo +{ + width: 50%; + float: left; + padding-top: 35px; + border: 0; +} +.organization_logo +{ + width: 50%; + float: right; + border: 0; +} + +.form-error { + padding: 0; + color: #B61601; +} + +/* Device specific styles */ +@media only screen and (max-device-width: 721px){ + .box { + width: auto; + box-shadow: none; + border-radius: 0; + -webkit-box-shadow: none; + -webkit-border-radius: 0; + -moz-box-shadow: none; + -moz-border-radius: 0; + padding: 0; + margin-top:0; + } + #tou-content, #tou-acceptance{ + /*width:87%;*/ + width:auto; + } +} diff --git a/shib-idp/customized-shibboleth-idp/webapp/css/logout.css b/shib-idp/customized-shibboleth-idp/webapp/css/logout.css new file mode 100644 index 0000000..26f1893 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/webapp/css/logout.css @@ -0,0 +1,12 @@ +/* Success/Failure indicators for logout propagation. */ + +.success { + background: url(../images/success-32x32.png) no-repeat left center; + line-height: 36px; + padding-left: 36px; +} +.failure { + background: url(../images/failure-32x32.png) no-repeat left center; + line-height: 36px; + padding-left: 36px; +} diff --git a/shib-idp/customized-shibboleth-idp/webapp/css/main.css b/shib-idp/customized-shibboleth-idp/webapp/css/main.css new file mode 100644 index 0000000..54827ce --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/webapp/css/main.css @@ -0,0 +1,165 @@ +* { + margin: 0; + padding: 0; +} +header, footer, section, nav { + display: block; +} +html, body { + height: 100%; +} +body { + font-family:Verdana, Geneva, sans-serif; + font-size: 12px; + line-height: 1.5; + color: #717171; + background: #717171; +} +a:link, +a:visited { + text-decoration: none; + color: #717171; +} +img { + max-width: 100%; + margin-bottom: 12px; +} + +.wrapper { + background: #ffffff; +} + +.container { + position: relative; + left: 34%; + width: 540px; + margin-left: -270px; +} +.container-footer { + padding-top: 12px; +} +@media only screen and (max-width: 1020px) { + .container { + left: 45%; + } +} +@media only screen and (max-width: 650px) { + .container { + position: static; + margin: 0 auto; + width: 280px; + } +} + +header { + padding: 20px 0; +} + +.logo img { + border: none; +} +@media only screen and (max-width: 650px) { + .logo img { + display: none; + } + .logo { + background: url(../images/TIER_logo-249.png) no-repeat top center; + display: block; + height: 115px; + width: 100px; + margin: 0 auto; + } +} + +.content { + padding-bottom: 80px; + overflow: hidden; +} + +.column { + float: left; +} +.column.one { + width: 50%; + margin-right: 48px; +} + +form { + width: 240px; + padding-bottom: 21px; +} +form label { /* labels are hidden */ + font-weight: bold; +} +form legend { + font-size:1.2em; + margin-bottom: 12px; +} +.form-element-wrapper { + margin-bottom: 12px; +} +.form-element { + width: 100%; + padding: 13px 12px; + border: none; + font-size: 14px; + border-radius: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; +} +.form-field { + color: #B7B7B7; + border: 1px solid #B7B7B7; +} +.form-field-focus, +.form-field:focus, +input[type="text"]:focus { + color: #333333; + border-color: #333; +} +.form-button { + background: #B61601; + box-sizing: content-box; + -moz-box-sizing: content-box; + color: #ffffff; + cursor: pointer; +} +.form-button:hover { + background: #FF6400; +} +.form-error { + padding: 0; + color: #B61601; +} + +.list-help { + margin-top: 40px; /* offset padding on first anchor */ + list-style: none; +} +.list-help-item a { + display: block; + padding: 6px 0; +} +.item-marker { + color: #be0000; +} + +footer { + color: #ffffff; + font-size: 11px; + background: #717171; +} +.footer-text { + margin-bottom: 12px; +} +.footer-links a:link, +.footer-links a:visited { + color: #ffffff; + font-weight: bold; +} +.footer-links a:after { + content: "\00a0\00a0\00a0|\00a0\00a0"; +} +.footer-links a.last:after { + content: ""; +} diff --git a/shib-idp/customized-shibboleth-idp/webapp/images/TIER_logo-249.png b/shib-idp/customized-shibboleth-idp/webapp/images/TIER_logo-249.png new file mode 100644 index 0000000..b188cc3 Binary files /dev/null and b/shib-idp/customized-shibboleth-idp/webapp/images/TIER_logo-249.png differ diff --git a/shib-idp/customized-shibboleth-idp/webapp/images/dummylogo-mobile.png b/shib-idp/customized-shibboleth-idp/webapp/images/dummylogo-mobile.png new file mode 100644 index 0000000..8ba3c95 Binary files /dev/null and b/shib-idp/customized-shibboleth-idp/webapp/images/dummylogo-mobile.png differ diff --git a/shib-idp/customized-shibboleth-idp/webapp/images/dummylogo.png b/shib-idp/customized-shibboleth-idp/webapp/images/dummylogo.png new file mode 100644 index 0000000..4f5b4a5 Binary files /dev/null and b/shib-idp/customized-shibboleth-idp/webapp/images/dummylogo.png differ diff --git a/shib-idp/customized-shibboleth-idp/webapp/images/failure-32x32.png b/shib-idp/customized-shibboleth-idp/webapp/images/failure-32x32.png new file mode 100644 index 0000000..3c48e46 Binary files /dev/null and b/shib-idp/customized-shibboleth-idp/webapp/images/failure-32x32.png differ diff --git a/shib-idp/customized-shibboleth-idp/webapp/images/success-32x32.png b/shib-idp/customized-shibboleth-idp/webapp/images/success-32x32.png new file mode 100644 index 0000000..aa51204 Binary files /dev/null and b/shib-idp/customized-shibboleth-idp/webapp/images/success-32x32.png differ diff --git a/shib-idp/customized-shibboleth-idp/webapp/js/Duo-Web-v2.min.js b/shib-idp/customized-shibboleth-idp/webapp/js/Duo-Web-v2.min.js new file mode 100644 index 0000000..393900d --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/webapp/js/Duo-Web-v2.min.js @@ -0,0 +1 @@ +window.Duo=function(e,t){var i=/^(?:AUTH|ENROLL)+\|[A-Za-z0-9\+\/=]+\|[A-Za-z0-9\+\/=]+$/;var o=/^ERR\|[\w\s\.\(\)]+$/;var n="duo_iframe",a="",s="sig_response",r,f,u,d,m,c;function h(e,t){throw new Error("Duo Web SDK error: "+e+(t?"\n"+"See "+t+" for more information":""))}function g(e){return e.replace(/([a-z])([A-Z])/,"$1-$2").toLowerCase()}function l(e,t){if("dataset"in e){return e.dataset[t]}else{return e.getAttribute("data-"+g(t))}}function p(e,i,o,n){if("addEventListener"in t){e.addEventListener(i,n,false)}else{e.attachEvent(o,n)}}function w(e,i,o,n){if("removeEventListener"in t){e.removeEventListener(i,n,false)}else{e.detachEvent(o,n)}}function v(t){p(e,"DOMContentLoaded","onreadystatechange",t)}function b(t){w(e,"DOMContentLoaded","onreadystatechange",t)}function E(e){p(t,"message","onmessage",e)}function _(e){w(t,"message","onmessage",e)}function y(e){if(!e){return}if(e.indexOf("ERR|")===0){h(e.split("|")[1])}if(e.indexOf(":")===-1||e.split(":").length!==2){h("Duo was given a bad token. This might indicate a configuration "+"problem with one of Duo's client libraries.","https://www.duosecurity.com/docs/duoweb#first-steps")}var t=e.split(":");f=e;u=t[0];d=t[1];return{sigRequest:e,duoSig:t[0],appSig:t[1]}}function D(){m=e.getElementById(n);if(!m){throw new Error("This page does not contain an iframe for Duo to use."+'Add an element like '+"to this page. "+"See https://www.duosecurity.com/docs/duoweb#3.-show-the-iframe "+"for more information.")}B();b(D)}function A(e){return Boolean(e.origin==="https://"+r&&typeof e.data==="string"&&(e.data.match(i)||e.data.match(o)))}function L(t){if(t){if(t.host){r=t.host}if(t.sig_request){y(t.sig_request)}if(t.post_action){a=t.post_action}if(t.post_argument){s=t.post_argument}if(t.iframe){if("tagName"in t.iframe){m=t.iframe}else if(typeof t.iframe==="string"){n=t.iframe}}if(typeof t.submit_callback==="function"){c=t.submit_callback}}if(m){B()}else{m=e.getElementById(n);if(m){B()}else{v(D)}}b(L)}function q(e){if(A(e)){R(e.data);_(q)}}function B(){if(!r){r=l(m,"host");if(!r){h("No API hostname is given for Duo to use. Be sure to pass "+"a `host` parameter to Duo.init, or through the `data-host` "+"attribute on the iframe element.","https://www.duosecurity.com/docs/duoweb#3.-show-the-iframe")}}if(!u||!d){y(l(m,"sigRequest"));if(!u||!d){h("No valid signed request is given. Be sure to give the "+"`sig_request` parameter to Duo.init, or use the "+"`data-sig-request` attribute on the iframe element.","https://www.duosecurity.com/docs/duoweb#3.-show-the-iframe")}}if(a===""){a=l(m,"postAction")||a}if(s==="sig_response"){s=l(m,"postArgument")||s}m.src=["https://",r,"/frame/web/v1/auth?tx=",u,"&parent=",encodeURIComponent(e.location.href),"&v=2.3"].join("");E(q)}function R(t){var i=e.createElement("input");i.type="hidden";i.name=s;i.value=t+":"+d;var o=e.getElementById("duo_form");if(!o){o=e.createElement("form");m.parentElement.insertBefore(o,m.nextSibling)}o.method="POST";o.action=a;o.appendChild(i);if(typeof c==="function"){c.call(null,o)}else{o.submit()}}v(L);return{init:L,_parseSigRequest:y,_isDuoMessage:A,_doPostBack:R}}(document,window); \ No newline at end of file diff --git a/shib-idp/customized-shibboleth-idp/webapp/js/jquery-2.1.4.min.js b/shib-idp/customized-shibboleth-idp/webapp/js/jquery-2.1.4.min.js new file mode 100644 index 0000000..49990d6 --- /dev/null +++ b/shib-idp/customized-shibboleth-idp/webapp/js/jquery-2.1.4.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("