Fixed check in
authorHolden Karau <hkarau@csclub.uwaterloo.ca>
Tue, 11 Jul 2006 21:17:40 +0000 (21:17 +0000)
committerHolden Karau <hkarau@csclub.uwaterloo.ca>
Tue, 11 Jul 2006 21:17:40 +0000 (21:17 +0000)
ceo.pl.in
modules/Accounts.pm
modules/Books.pm

index 1dd9b1f..2c204d2 100755 (executable)
--- a/ceo.pl.in
+++ b/ceo.pl.in
@@ -43,6 +43,7 @@ sub menu_ceo {
                 ['i', 'Search for a member by student id', \&action_list_by_studentid],
                 ['nil'],
                ['a', 'Create an account', \&action_create_account],
+               ['r', 'Re Create an account', \&action_re_create_account],
                 ['nil'],
                 ['l', 'Library functions', \&menu_library],
                ['nil'],
@@ -197,6 +198,55 @@ sub action_create_account {
 #}}}
 }
 
+sub action_re_create_account {
+#{{{
+       # takes an optional argument specifying memberid (if this method
+       # is invoked after action_new_member)
+       my ($memberid) = @_;
+
+       if(!$memberid) {
+               # memberid was not provided in the arg, prompt for one
+               $memberid = &UI::Prompt(
+                       'Enter member ID (exit to cancel): ',
+                       'custom',
+                       \&prompt_memberid_or_userid);
+       }
+
+       my $member = &Members::Get($memberid);
+       if(!$member) {
+               &UI::MsgWait("No member with id: $memberid");
+                return 1;
+       } else {
+               &Members::Print($member);
+       }
+
+        if (!(&UI::Prompt("Is this the correct member?", 'yesno'))) {
+            &UI::MsgWait("I suggest searching for the member by userid or name from the main menu.");
+            return 1;
+        }
+
+       # get the account's userid
+       my $userid = &UI::Prompt('Userid: ', 'regex', q(^\\w+$));
+
+       # add the account
+        my $result = &Accounts::ReAdd($memberid, $userid);
+
+       if(!$result) {
+               &UI::MsgWait(
+                       "Error adding your account to the database.\n" .
+                       "Please talk to the sysadmin");
+               return 1;
+       }
+
+       # all good
+       &UI::MsgWait("Success! Your account has been added");
+
+       return 1;
+
+#}}}
+}
+
+
 sub action_list_registered {
     my $term = &UI::Prompt(
                            'Which term to list members for ([fws]20nn): ',
index 457dfd1..bff686e 100644 (file)
@@ -12,6 +12,8 @@ use strict;
 use Net::LDAP;
 use User::pwent;
 use English;
+use Authen::Krb5;
+use Authen::Krb5::Admin qw(:constants);
 
 require Common;
 
@@ -63,6 +65,194 @@ sub Add($) {
             # TODO: Really fix this sometime
             die 1;
         }
+        $uidnum = $maxid + 2;
+
+        open LDAPSECRET, "</etc/ldap.ceo";
+
+        my $secret = <LDAPSECRET>;
+        chomp $secret;
+        close LDAPSECRET;
+        
+        my $ldap = Net::LDAP->new('localhost');
+        if (!$ldap) {
+            # TODO: Print error in $@
+            return 0;
+        }
+
+        my $result = $ldap->bind('cn=ceo,dc=csclub,dc=uwaterloo,dc=ca',
+                      password => $secret);
+
+        if ($result->code) {
+            # TODO: Print $result->error
+           die "Could not bind to LDAP! , ". $result->error ."\n";
+            return 0;
+        }
+
+        my $userpass;
+        my $repeat;
+        # TODO: Use some UI Password prompting function
+        do {
+            $userpass = &UI::Prompt("User password: ", 'custom', \&prompt_password, 1);
+            $repeat = &UI::Prompt("Enter the password again: ", 'custom', \&prompt_password, 1);
+        } while ($userpass ne $repeat);
+        
+        $result =
+            $ldap->add("uid=$userid,ou=People,dc=csclub,dc=uwaterloo,dc=ca",
+                       attr => ['uid' => "$userid",
+                                'cn'  => "$realname",
+                                'objectClass' => ['account',
+                                                  'posixAccount',
+                                                  'top'],
+                                'userPassword' => "x",
+                                'loginShell'   => "$shell",
+                                'uidNumber'    => "$uidnum",
+                                'gidNumber'    => "1",
+                                'homeDirectory'=> "/users/$userid",
+                                'gecos'        => "$realname"]
+               );
+
+        if ($result->code) {
+            # TODO: Print $result->error
+           die "Could not do stuff , ". $result->error ." ";
+            return 0;
+        }
+
+        $ldap->unbind();
+
+       #Add them to kerberose
+       my $krb5context;
+       eval {
+               $krb5context = Authen::Krb5::init_context();
+               Authen::Krb5::init_ets();
+       };
+       if ( $@ ) {
+               #TODO: Print error
+               #return 0;
+               warn $@;
+               die $@;
+       }
+
+
+       my $kadm5_config =  Authen::Krb5::Admin::Config->new(); 
+
+       my $kadm5 =
+         Authen::Krb5::Admin->init_with_skey( "ceo/admin\@CSCLUB.UWATERLOO.CA" , "/etc/ceo.keytab" , "kadmin/admin" , $kadm5_config )
+         or die Authen::Krb5::Admin::error;
+       
+
+       my $krb5_princ;
+       # get valid kerb5 principal from uid
+       $krb5_princ = Authen::Krb5::parse_name($userid)
+         or die Authen::Krb5::error;
+       # get a new principal object
+       my $kadm5_princ = Authen::Krb5::Admin::Principal->new
+         or die Authen::Krb5::error;
+       # set the value of the new principal's principal name
+       $kadm5_princ->principal($krb5_princ)
+         or die Authen::Krb5::error;
+       # if principal does not exist, ok to create...
+       #if ( !$kadm5->get_principal($krb5_princ) ) {
+           # set the value of the principals policy
+          #$kadm5_princ->policy( "default" )
+          #     or die Authen::Krb5::Admin::error;
+       
+           # modify principal's pw expiration
+           #$kadm5_princ->pw_expiration( time() )
+           #    or die Authen::Krb5::Admin::error;
+               
+           # create princ
+           $kadm5->create_principal( $kadm5_princ, $userpass )
+               or die Authen::Krb5::Admin::error;
+       
+           #$kadm5->chpass($kadm5_princ , "pants");
+
+       #}
+       #else { 
+       #       warn "WARNING: Principal $userid already existed in Kerberos\n";
+       #}
+
+       # Make the home directory
+       #system("/usr/local/bin/addhomedir_ceo", "$userid");
+        
+        # Add userid to database
+        my $statement = $Common::CEODB->prepare("UPDATE members " .
+                                                "SET userid = ? WHERE memberid = ?");
+
+        $result = $statement->execute($userid, $memberid);
+
+        if (!$result) {
+               &Common::Log(
+                       10,
+                       "Accounts::Add",
+                       "members table",
+                       sprintf("Error: set account for member %s uid %s failed",
+                               $memberid,
+                                $userid));
+               $statement->finish();
+                &UI::MsgWait("The user was created but adding the user ID to the database failed. Please contact the sysadmin.");
+                return 0;
+        }
+
+       &UI::MsgWait("Please run \'addhomedir $userid\'.");
+
+#      MailSysadmin("Account $userid created", "For member $memberid.");
+       return 1;
+}
+
+# function: Add($memberid, $userid)
+#           adds an account to the system
+#
+#      arg: $account - the account hashref
+#
+#  returns: truth on success, false on failure
+sub ReAdd($) {
+       my ($memberid, $userid) = @_;
+
+        # * Check that the member doesn't already have an account
+        # * Check that that account name isn't already taken
+        # * If not, add the account to LDAP and add the appropriate
+        #   account name to the member entry
+        # * Change the password
+
+        my $shell = "/bin/bash";
+
+        my $member = Members::Get($memberid);
+        if (!$member) {
+            # No such member!
+            return 0;
+        }
+        my $currentid = $member->{"userid"};
+        #if ($currentid) {
+        #    UI::MsgWait("Member $memberid already has an account: $currentid\n"
+        #                . "Contact the sysadmin if there are still problems.");
+        #      return 0;
+        #}
+
+       # TODO: Check that member is a member this term
+        # TODO: Check format of userid (alphanumeric, etc.)
+        
+        my $realname = $member->{"name"};
+
+        # Determine what UID number to assign
+        my $maxid = 0;
+        my $uidnum;
+        while (1) { #Keep people from creating uid 0 accounts by mistake
+            my $pw = getpwent() || last;
+            my $idnum = $pw->uid;
+            if ($idnum > $maxid && $idnum < 50000) {
+                $maxid = $idnum;
+            }
+        }
+        if( $maxid < 100 ) {
+            # This is bad.  getpwent() failed miserably.
+            # TODO: Really fix this sometime
+            die 1;
+        }
         $uidnum = $maxid + 1;
 
         open LDAPSECRET, "</etc/ldap.ceo";
@@ -143,6 +333,7 @@ sub Add($) {
        return 1;
 }
 
+
 sub prompt_password($) {
     (my $pw) = @_;
 
index 0499b67..67320f2 100644 (file)
@@ -133,7 +133,7 @@ sub GetISBNFromBarcode($) {
 #           book. Undef if the book doesn't exist or isn't out.
 sub GetBorrower($) {
     my ($bookid) = @_;
-    my $statement = $Common::CEODB->prepare("SELECT memberid FROM members_books WHERE bookid = ?;");
+    my $statement = $Common::CEODB->prepare("SELECT memberid FROM members_books WHERE bookid = ? AND borrowed=1;");
 
     my $result = $statement->execute($bookid);
 
@@ -158,7 +158,7 @@ sub GetBorrower($) {
 #           retrieves a list of books currently on loan, with the
 #           members who have borrowed them.
 sub GetOnLoan() {
-    my $statement = $Common::CEODB->prepare("SELECT books.*, memberid, date_out FROM books, members_books WHERE books.bookid = members_books.bookid ORDER by title, author;");
+    my $statement = $Common::CEODB->prepare("SELECT books.*, memberid, date_out FROM books, members_books WHERE books.bookid = members_books.bookid AND members_books.borrowed = 1 ORDER by title, author;");
 
     my $result = $statement->execute();
 
@@ -213,7 +213,7 @@ sub ReturnBook($$) {
     }
 
     my $statement = $Common::CEODB->prepare(
-             "DELETE FROM members_books WHERE memberid = ? AND bookid = ?");
+             "UPDATE members_books WHERE memberid = ? AND bookid = ? SET returned = 1");
 
     my $result = $statement->execute($memberid, $bookid);