File:
[LON-CAPA] /
loncom /
auth /
lonlogin.pm
Revision
1.179:
download - view:
text,
annotated -
select for diffs
Sun Jan 27 16:02:43 2019 UTC (5 years, 3 months ago) by
raeburn
Branches:
MAIN
CVS tags:
HEAD
- Bug 6400
- Enforce access restrictions for content which is deeplink-only (users
with "advanced priv for current role are exempt).
- Support "key" link type in deeplink parameter (requested link must either
be sent with linkkey as element in POSTed data, or with linkkey in query
string). Corresponding value must match key set in deeplink parameter.
1: # The LearningOnline Network
2: # Login Screen
3: #
4: # $Id: lonlogin.pm,v 1.179 2019/01/27 16:02:43 raeburn Exp $
5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28:
29: package Apache::lonlogin;
30:
31: use strict;
32: use Apache::Constants qw(:common);
33: use Apache::File ();
34: use Apache::lonnet;
35: use Apache::loncommon();
36: use Apache::lonauth();
37: use Apache::lonlocal;
38: use Apache::migrateuser();
39: use lib '/home/httpd/lib/perl/';
40: use LONCAPA qw(:DEFAULT :match);
41: use CGI::Cookie();
42:
43: sub handler {
44: my $r = shift;
45:
46: &Apache::loncommon::get_unprocessed_cgi
47: (join('&',$ENV{'QUERY_STRING'},$env{'request.querystring'},
48: $ENV{'REDIRECT_QUERY_STRING'}),
49: ['interface','username','domain','firsturl','localpath','localres',
50: 'token','role','symb','iptoken','btoken','ltoken','linkkey']);
51: if (!defined($env{'form.firsturl'})) {
52: &Apache::lonacc::get_posted_cgi($r,['firsturl']);
53: }
54: if (!defined($env{'form.firsturl'})) {
55: if ($ENV{'REDIRECT_URL'} =~ m{^/+tiny/+$LONCAPA::match_domain/+\w+$}) {
56: $env{'form.firsturl'} = $ENV{'REDIRECT_URL'};
57: }
58: }
59: if (($env{'form.firsturl'} =~ m{^/+tiny/+$LONCAPA::match_domain/+\w+$}) &&
60: (!$env{'form.ltoken'}) && (!$env{'form.linkkey'})) {
61: &Apache::lonacc::get_posted_cgi($r,['linkkey']);
62: }
63:
64: # -- check if they are a migrating user
65: if (defined($env{'form.token'})) {
66: return &Apache::migrateuser::handler($r);
67: }
68:
69: # For "public user" - remove any exising "public" cookie, as user really wants to log-in
70: my ($handle,$lonidsdir,$expirepub,$userdom);
71: $lonidsdir=$r->dir_config('lonIDsDir');
72: unless ($r->header_only) {
73: $handle = &Apache::lonnet::check_for_valid_session($r,'lonID',undef,\$userdom);
74: if ($handle ne '') {
75: if ($handle=~/^publicuser\_/) {
76: unlink($r->dir_config('lonIDsDir')."/$handle.id");
77: undef($handle);
78: undef($userdom);
79: $expirepub = 1;
80: }
81: }
82: }
83:
84: &Apache::loncommon::no_cache($r);
85: &Apache::lonlocal::get_language_handle($r);
86: &Apache::loncommon::content_type($r,'text/html');
87: if ($expirepub) {
88: my $c = new CGI::Cookie(-name => 'lonPubID',
89: -value => '',
90: -expires => '-10y',);
91: $r->header_out('Set-cookie' => $c);
92: } elsif (($handle eq '') && ($userdom ne '')) {
93: my %cookies=CGI::Cookie->parse($r->header_in('Cookie'));
94: foreach my $name (keys(%cookies)) {
95: next unless ($name =~ /^lon(|S|Link|Pub)ID$/);
96: my $c = new CGI::Cookie(-name => $name,
97: -value => '',
98: -expires => '-10y',);
99: $r->headers_out->add('Set-cookie' => $c);
100: }
101: }
102: $r->send_http_header;
103: return OK if $r->header_only;
104:
105:
106: # Are we re-routing?
107: my $londocroot = $r->dir_config('lonDocRoot');
108: if (-e "$londocroot/lon-status/reroute.txt") {
109: &Apache::lonauth::reroute($r);
110: return OK;
111: }
112:
113: my $lonhost = $r->dir_config('lonHostID');
114: $env{'form.firsturl'} =~ s/(`)/'/g;
115:
116: # Check if browser sent a LON-CAPA load balancer cookie (and this is a balancer)
117:
118: my ($found_server,$balancer_cookie) = &Apache::lonnet::check_for_balancer_cookie($r,1);
119: if ($found_server) {
120: my $hostname = &Apache::lonnet::hostname($found_server);
121: if ($hostname ne '') {
122: my $protocol = $Apache::lonnet::protocol{$found_server};
123: $protocol = 'http' if ($protocol ne 'https');
124: my $dest = '/adm/roles';
125: if ($env{'form.firsturl'} ne '') {
126: $dest = $env{'form.firsturl'};
127: }
128: my %info = (
129: balcookie => $lonhost.':'.$balancer_cookie,
130: );
131: if ($env{'form.ltoken'}) {
132: my %link_info = &Apache::lonnet::tmpget($env{'form.ltoken'});
133: if ($link_info{'linkprot'}) {
134: $info{'linkprot'} = $link_info{'linkprot'};
135: }
136: &Apache::lonnet::tmpdel($env{'form.ltoken'});
137: delete($env{'form.ltoken'});
138: } elsif ($env{'form.linkkey'}) {
139: $info{'linkkey'} = $env{'form.linkkey'};
140: delete($env{'form.linkkey'});
141: }
142: my $balancer_token = &Apache::lonnet::tmpput(\%info,$found_server);
143: if ($balancer_token) {
144: $dest .= (($dest=~/\?/)?'&;':'?') . 'btoken='.$balancer_token;
145: }
146: my $url = $protocol.'://'.$hostname.$dest;
147: my $start_page =
148: &Apache::loncommon::start_page('Switching Server ...',undef,
149: {'redirect' => [0,$url],});
150: my $end_page = &Apache::loncommon::end_page();
151: $r->print($start_page.$end_page);
152: return OK;
153: }
154: }
155:
156: #
157: # Check if a LON-CAPA load balancer sent user here because user's browser sent
158: # it a balancer cookie for an active session on this server.
159: #
160:
161: my ($balcookie,$linkprot,$linkkey);
162: if ($env{'form.btoken'}) {
163: my %info = &Apache::lonnet::tmpget($env{'form.btoken'});
164: $balcookie = $info{'balcookie'};
165: if ($balcookie) {
166: if ($info{'linkprot'}) {
167: $linkprot = $info{'linkprot'};
168: } elsif ($info{'linkkey'}) {
169: $linkkey = $info{'linkkey'};
170: }
171: }
172: &Apache::lonnet::tmpdel($env{'form.btoken'});
173: delete($env{'form.btoken'});
174: }
175:
176: #
177: # If browser sent an old cookie for which the session file had been removed
178: # check if configuration for user's domain has a portal URL set. If so
179: # switch user's log-in to the portal.
180: #
181:
182: if (($handle eq '') && ($userdom ne '')) {
183: my %domdefaults = &Apache::lonnet::get_domain_defaults($userdom);
184: if ($domdefaults{'portal_def'} =~ /^https?\:/) {
185: my $start_page = &Apache::loncommon::start_page('Switching Server ...',undef,
186: {'redirect' => [0,$domdefaults{'portal_def'}],});
187: my $end_page = &Apache::loncommon::end_page();
188: $r->print($start_page.$end_page);
189: return OK;
190: }
191: }
192:
193: # -------------------------------- Prevent users from attempting to login twice
194: if ($handle ne '') {
195: &Apache::lonnet::transfer_profile_to_env($lonidsdir,$handle);
196: my $start_page =
197: &Apache::loncommon::start_page('Already logged in');
198: my $end_page =
199: &Apache::loncommon::end_page();
200: my $dest = '/adm/roles';
201: if ($env{'form.firsturl'} ne '') {
202: $dest = $env{'form.firsturl'};
203: }
204: if (($env{'form.ltoken'}) || ($linkprot)) {
205: unless ($linkprot) {
206: my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
207: $linkprot = $info{'linkprot'};
208: my $delete = &Apache::lonnet::tmpdel($env{'form.ltoken'});
209: delete($env{'form.ltoken'});
210: }
211: if ($linkprot) {
212: my ($linkprotector,$deeplink) = split(/:/,$linkprot,2);
213: if ($env{'user.linkprotector'}) {
214: my @protectors = split(/,/,$env{'user.linkprotector'});
215: unless (grep(/^\Q$linkprotector\E$/,@protectors)) {
216: push(@protectors,$linkprotector);
217: @protectors = sort { $a <=> $b } @protectors;
218: &Apache::lonnet::appenv({'user.linkprotector' => join(',',@protectors)});
219: }
220: } else {
221: &Apache::lonnet::appenv({'user.linkprotector' => $linkprotector });
222: }
223: if ($env{'user.linkproturi'}) {
224: my @proturis = split(/,/,$env{'user.linkproturi'});
225: unless (grep(/^\Q$deeplink\E$/,@proturis)) {
226: push(@proturis,$deeplink);
227: @proturis = sort @proturis;
228: &Apache::lonnet::appenv({'user.linkproturi' => join(',',@proturis)});
229: }
230: } else {
231: &Apache::lonnet::appenv({'user.linkproturi' => $deeplink});
232: }
233: }
234: } elsif (($env{'form.linkkey'}) || ($linkkey)) {
235: if ($env{'form.firsturl'} =~ m{^/tiny/$match_domain/\w+$}) {
236: if ($linkkey eq '') {
237: $linkkey = $env{'form.linkkey'};
238: }
239: if ($env{'user.deeplinkkey'}) {
240: my @linkkeys = split(/,/,$env{'user.deeplinkkey'});
241: unless (grep(/^\Q$linkkey\E$/,@linkkeys)) {
242: push(@linkkeys,$linkkey);
243: &Apache::lonnet::appenv({'user.deeplinkkey' => join(',',sort(@linkkeys))});
244: }
245: } else {
246: &Apache::lonnet::appenv({'user.deeplinkkey' => $linkkey});
247: }
248: my $deeplink = $env{'form.firsturl'};
249: if ($env{'user.keyedlinkuri'}) {
250: my @keyeduris = split(/,/,$env{'user.keyedlinkuri'});
251: unless (grep(/^\Q$deeplink\E$/,@keyeduris)) {
252: push(@keyeduris,$deeplink);
253: &Apache::lonnet::appenv({'user.keyedlinkuri' => join(',',sort(@keyeduris))});
254: }
255: } else {
256: &Apache::lonnet::appenv({'user.keyedlinkuri' => $deeplink});
257: }
258: }
259: }
260: $r->print(
261: $start_page
262: .'<p class="LC_warning">'.&mt('You are already logged in!').'</p>'
263: .'<p>'.&mt('Please either [_1]continue the current session[_2] or [_3]log out[_4].',
264: '<a href="'.$dest.'">','</a>','<a href="/adm/logout">','</a>').'</p>'
265: .$end_page
266: );
267: return OK;
268: }
269:
270: # ---------------------------------------------------- No valid token, continue
271:
272: # ---------------------------- Not possible to really login to domain "public"
273: if ($env{'form.domain'} eq 'public') {
274: $env{'form.domain'}='';
275: $env{'form.username'}='';
276: }
277:
278: # ------ Is this page requested because /adm/migrateuser detected an IP change?
279: my %sessiondata;
280: if ($env{'form.iptoken'}) {
281: %sessiondata = &Apache::lonnet::tmpget($env{'form.iptoken'});
282: unless ($sessiondata{'sessionserver'}) {
283: my $delete = &Apache::lonnet::tmpdel($env{'form.iptoken'});
284: delete($env{'form.iptoken'});
285: }
286: }
287: # ----------------------------------------------------------- Process Interface
288: $env{'form.interface'}=~s/\W//g;
289:
290: (undef,undef,undef,undef,undef,undef,my $clientmobile) =
291: &Apache::loncommon::decode_user_agent();
292:
293: my $iconpath=
294: &Apache::loncommon::lonhttpdurl($r->dir_config('lonIconsURL'));
295:
296: my $domain = &Apache::lonnet::default_login_domain();
297: my $defdom = $domain;
298: if ($lonhost ne '') {
299: unless ($sessiondata{'sessionserver'}) {
300: my $redirect = &check_loginvia($domain,$lonhost,$lonidsdir,$balcookie,$linkprot);
301: if ($redirect) {
302: $r->print($redirect);
303: return OK;
304: }
305: }
306: }
307:
308: if (($sessiondata{'domain'}) &&
309: (&Apache::lonnet::domain($sessiondata{'domain'},'description'))) {
310: $domain=$sessiondata{'domain'};
311: } elsif (($env{'form.domain'}) &&
312: (&Apache::lonnet::domain($env{'form.domain'},'description'))) {
313: $domain=$env{'form.domain'};
314: }
315:
316: my $role = $r->dir_config('lonRole');
317: my $loadlim = $r->dir_config('lonLoadLim');
318: my $uloadlim= $r->dir_config('lonUserLoadLim');
319: my $servadm = $r->dir_config('lonAdmEMail');
320: my $tabdir = $r->dir_config('lonTabDir');
321: my $include = $r->dir_config('lonIncludes');
322: my $expire = $r->dir_config('lonExpire');
323: my $version = $r->dir_config('lonVersion');
324: my $host_name = &Apache::lonnet::hostname($lonhost);
325:
326: # --------------------------------------------- Default values for login fields
327:
328: my ($authusername,$authdomain);
329: if ($sessiondata{'username'}) {
330: $authusername=$sessiondata{'username'};
331: } else {
332: $env{'form.username'} = &Apache::loncommon::cleanup_html($env{'form.username'});
333: $authusername=($env{'form.username'}?$env{'form.username'}:'');
334: }
335: if ($sessiondata{'domain'}) {
336: $authdomain=$sessiondata{'domain'};
337: } else {
338: $env{'form.domain'} = &Apache::loncommon::cleanup_html($env{'form.domain'});
339: $authdomain=($env{'form.domain'}?$env{'form.domain'}:$domain);
340: }
341:
342: # ---------------------------------------------------------- Determine own load
343: my $loadavg;
344: {
345: my $loadfile=Apache::File->new('/proc/loadavg');
346: $loadavg=<$loadfile>;
347: }
348: $loadavg =~ s/\s.*//g;
349:
350: my ($loadpercent,$userloadpercent);
351: if ($loadlim) {
352: $loadpercent=sprintf("%.1f",100*$loadavg/$loadlim);
353: }
354: if ($uloadlim) {
355: $userloadpercent=&Apache::lonnet::userload();
356: }
357:
358: my $firsturl=
359: ($env{'request.firsturl'}?$env{'request.firsturl'}:$env{'form.firsturl'});
360:
361: # ----------------------------------------------------------- Get announcements
362: my $announcements=&Apache::lonnet::getannounce();
363: # -------------------------------------------------------- Set login parameters
364:
365: my @hexstr=('0','1','2','3','4','5','6','7',
366: '8','9','a','b','c','d','e','f');
367: my $lkey='';
368: for (0..7) {
369: $lkey.=$hexstr[rand(15)];
370: }
371:
372: my $ukey='';
373: for (0..7) {
374: $ukey.=$hexstr[rand(15)];
375: }
376:
377: my $lextkey=hex($lkey);
378: if ($lextkey>2147483647) { $lextkey-=4294967296; }
379:
380: my $uextkey=hex($ukey);
381: if ($uextkey>2147483647) { $uextkey-=4294967296; }
382:
383: # -------------------------------------------------------- Store away log token
384: my $tokenextras;
385: if ($env{'form.role'}) {
386: $tokenextras = '&role='.&escape($env{'form.role'});
387: }
388: if ($env{'form.symb'}) {
389: if (!$tokenextras) {
390: $tokenextras = '&';
391: }
392: $tokenextras .= '&symb='.&escape($env{'form.symb'});
393: }
394: if ($env{'form.iptoken'}) {
395: if (!$tokenextras) {
396: $tokenextras = '&&';
397: }
398: $tokenextras .= '&iptoken='.&escape($env{'form.iptoken'});
399: }
400: if ($env{'form.ltoken'}) {
401: my %info = &Apache::lonnet::tmpget($env{'form.ltoken'});
402: &Apache::lonnet::tmpdel($env{'form.ltoken'});
403: delete($env{'form.ltoken'});
404: if ($info{'linkprot'}) {
405: if (!$tokenextras) {
406: $tokenextras = '&&&';
407: }
408: $tokenextras .= '&linkprot='.&escape($info{'linkprot'});
409: }
410: } elsif ($env{'form.linkkey'}) {
411: if (!$tokenextras) {
412: $tokenextras = '&&&';
413: }
414: $tokenextras .= '&linkkey='.&escape($env{'form.linkkey'});
415: }
416: my $logtoken=Apache::lonnet::reply(
417: 'tmpput:'.$ukey.$lkey.'&'.$firsturl.$tokenextras,
418: $lonhost);
419:
420: # -- If we cannot talk to ourselves, or hostID does not map to a hostname
421: # we are in serious trouble
422:
423: if (($logtoken eq 'con_lost') || ($logtoken eq 'no_such_host')) {
424: if ($logtoken eq 'no_such_host') {
425: &Apache::lonnet::logthis('No valid logtoken for log-in page -- unable to determine hostname for hostID: '.$lonhost.'. Check entry in hosts.tab');
426: }
427: my $spares='';
428: my $last;
429: foreach my $hostid (sort
430: {
431: &Apache::lonnet::hostname($a) cmp
432: &Apache::lonnet::hostname($b);
433: }
434: keys(%Apache::lonnet::spareid)) {
435: next if ($hostid eq $lonhost);
436: my $hostname = &Apache::lonnet::hostname($hostid);
437: next if (($last eq $hostname) || ($hostname eq ''));
438: $spares.='<br /><font size="+1"><a href="http://'.
439: $hostname.
440: '/adm/login?domain='.$authdomain.'">'.
441: $hostname.'</a>'.
442: ' '.&mt('(preferred)').'</font>'.$/;
443: $last=$hostname;
444: }
445: if ($spares) {
446: $spares.= '<br />';
447: }
448: my %all_hostnames = &Apache::lonnet::all_hostnames();
449: foreach my $hostid (sort
450: {
451: &Apache::lonnet::hostname($a) cmp
452: &Apache::lonnet::hostname($b);
453: }
454: keys(%all_hostnames)) {
455: next if ($hostid eq $lonhost || $Apache::lonnet::spareid{$hostid});
456: my $hostname = &Apache::lonnet::hostname($hostid);
457: next if (($last eq $hostname) || ($hostname eq ''));
458: $spares.='<br /><a href="http://'.
459: $hostname.
460: '/adm/login?domain='.$authdomain.'">'.
461: $hostname.'</a>';
462: $last=$hostname;
463: }
464: $r->print(
465: '<html>'
466: .'<head><title>'
467: .&mt('The LearningOnline Network with CAPA')
468: .'</title></head>'
469: .'<body bgcolor="#FFFFFF">'
470: .'<h1>'.&mt('The LearningOnline Network with CAPA').'</h1>'
471: .'<img src="/adm/lonKaputt/lonlogo_broken.gif" align="right" />'
472: .'<h3>'.&mt('This LON-CAPA server is temporarily not available for login.').'</h3>');
473: if ($spares) {
474: $r->print('<p>'.&mt('Please attempt to login to one of the following servers:')
475: .'</p>'
476: .$spares);
477: }
478: $r->print('</body>'
479: .'</html>'
480: );
481: return OK;
482: }
483:
484: # ----------------------------------------------- Apparently we are in business
485: $servadm=~s/\,/\<br \/\>/g;
486:
487: # ----------------------------------------------------------- Front page design
488: my $pgbg=&Apache::loncommon::designparm('login.pgbg',$domain);
489: my $font=&Apache::loncommon::designparm('login.font',$domain);
490: my $link=&Apache::loncommon::designparm('login.link',$domain);
491: my $vlink=&Apache::loncommon::designparm('login.vlink',$domain);
492: my $alink=&Apache::loncommon::designparm('login.alink',$domain);
493: my $mainbg=&Apache::loncommon::designparm('login.mainbg',$domain);
494: my $loginbox_bg=&Apache::loncommon::designparm('login.sidebg',$domain);
495: my $loginbox_header_bgcol=&Apache::loncommon::designparm('login.bgcol',$domain);
496: my $loginbox_header_textcol=&Apache::loncommon::designparm('login.textcol',$domain);
497: my $logo=&Apache::loncommon::designparm('login.logo',$domain);
498: my $img=&Apache::loncommon::designparm('login.img',$domain);
499: my $domainlogo=&Apache::loncommon::domainlogo($domain);
500: my $showbanner = 1;
501: my $showmainlogo = 1;
502: if (defined(&Apache::loncommon::designparm('login.showlogo_img',$domain))) {
503: $showbanner = &Apache::loncommon::designparm('login.showlogo_img',$domain);
504: }
505: if (defined(&Apache::loncommon::designparm('login.showlogo_logo',$domain))) {
506: $showmainlogo = &Apache::loncommon::designparm('login.showlogo_logo',$domain);
507: }
508: my $showadminmail;
509: my @possdoms = &Apache::lonnet::current_machine_domains();
510: if (grep(/^\Q$domain\E$/,@possdoms)) {
511: $showadminmail=&Apache::loncommon::designparm('login.adminmail',$domain);
512: }
513: my $showcoursecat =
514: &Apache::loncommon::designparm('login.coursecatalog',$domain);
515: my $shownewuserlink =
516: &Apache::loncommon::designparm('login.newuser',$domain);
517: my $showhelpdesk =
518: &Apache::loncommon::designparm('login.helpdesk',$domain);
519: my $now=time;
520: my $js = (<<ENDSCRIPT);
521:
522: <script type="text/javascript" language="JavaScript">
523: // <![CDATA[
524: function send()
525: {
526: this.document.server.elements.uname.value
527: =this.document.client.elements.uname.value;
528:
529: this.document.server.elements.udom.value
530: =this.document.client.elements.udom.value;
531:
532: uextkey=this.document.client.elements.uextkey.value;
533: lextkey=this.document.client.elements.lextkey.value;
534: initkeys();
535:
536: if(this.document.server.action.substr(0,5) === 'http:'){
537: this.document.server.elements.upass0.value
538: =getCrypted(this.document.client.elements.upass$now.value);
539: } else {
540: this.document.server.elements.upass0.value
541: =this.document.client.elements.upass$now.value;
542: }
543:
544: this.document.client.elements.uname.value='';
545: this.document.client.elements.upass$now.value='';
546:
547: this.document.server.submit();
548: return false;
549: }
550:
551: function enableInput() {
552: this.document.client.elements.upass$now.removeAttribute("readOnly");
553: this.document.client.elements.uname.removeAttribute("readOnly");
554: this.document.client.elements.udom.removeAttribute("readOnly");
555: return;
556: }
557:
558: // ]]>
559: </script>
560:
561: ENDSCRIPT
562:
563: # --------------------------------------------------- Print login screen header
564:
565: my %add_entries = (
566: bgcolor => "$mainbg",
567: text => "$font",
568: link => "$link",
569: vlink => "$vlink",
570: alink => "$alink",
571: onload => 'javascript:enableInput();',);
572:
573: my ($lonhost_in_use,$headextra,$headextra_exempt,@hosts,%defaultdomconf);
574: @hosts = &Apache::lonnet::current_machine_ids();
575: $lonhost_in_use = $lonhost;
576: if (@hosts > 1) {
577: foreach my $hostid (@hosts) {
578: if (&Apache::lonnet::host_domain($hostid) eq $defdom) {
579: $lonhost_in_use = $hostid;
580: last;
581: }
582: }
583: }
584: %defaultdomconf = &Apache::loncommon::get_domainconf($defdom);
585: $headextra = $defaultdomconf{$defdom.'.login.headtag_'.$lonhost_in_use};
586: $headextra_exempt = $defaultdomconf{$domain.'.login.headtag_exempt_'.$lonhost_in_use};
587: if ($headextra) {
588: my $omitextra;
589: if ($headextra_exempt ne '') {
590: my @exempt = split(',',$headextra_exempt);
591: my $ip = $ENV{'REMOTE_ADDR'};
592: if (grep(/^\Q$ip\E$/,@exempt)) {
593: $omitextra = 1;
594: }
595: }
596: unless ($omitextra) {
597: my $confname = $defdom.'-domainconfig';
598: if ($headextra =~ m{^\Q/res/$defdom/$confname/login/headtag/$lonhost_in_use/\E}) {
599: my $extra = &Apache::lonnet::getfile(&Apache::lonnet::filelocation("",$headextra));
600: unless ($extra eq '-1') {
601: $js .= "\n".$extra."\n";
602: }
603: }
604: }
605: }
606:
607: $r->print(&Apache::loncommon::start_page('The LearningOnline Network with CAPA Login',$js,
608: { 'redirect' => [$expire,'/adm/roles'],
609: 'add_entries' => \%add_entries,
610: 'only_body' => 1,}));
611:
612: # ----------------------------------------------------------------------- Texts
613:
614: my %lt=&Apache::lonlocal::texthash(
615: 'un' => 'Username',
616: 'pw' => 'Password',
617: 'dom' => 'Domain',
618: 'perc' => 'percent',
619: 'load' => 'Server Load',
620: 'userload' => 'User Load',
621: 'catalog' => 'Course/Community Catalog',
622: 'log' => 'Log in',
623: 'help' => 'Log-in Help',
624: 'serv' => 'Server',
625: 'servadm' => 'Server Administration',
626: 'helpdesk' => 'Contact Helpdesk',
627: 'forgotpw' => 'Forgot password?',
628: 'newuser' => 'New User?',
629: );
630: # -------------------------------------------------- Change password field name
631:
632: my $forgotpw = &forgotpwdisplay(%lt);
633: $forgotpw .= '<br />' if $forgotpw;
634: my $loginhelp = &Apache::lonauth::loginhelpdisplay($authdomain);
635: if ($loginhelp) {
636: $loginhelp = '<a href="'.$loginhelp.'">'.$lt{'help'}.'</a><br />';
637: }
638:
639: # ---------------------------------------------------- Serve out DES JavaScript
640: {
641: my $jsh=Apache::File->new($include."/londes.js");
642: $r->print(<$jsh>);
643: }
644: # ---------------------------------------------------------- Serve rest of page
645:
646: $r->print(
647: '<div class="LC_Box"'
648: .' style="margin:0 auto; padding:10px; width:90%; height: auto; background-color:#FFFFFF;">'
649: );
650:
651: $r->print(<<ENDSERVERFORM);
652: <form name="server" action="/adm/authenticate" method="post" target="_top">
653: <input type="hidden" name="logtoken" value="$logtoken" />
654: <input type="hidden" name="serverid" value="$lonhost" />
655: <input type="hidden" name="uname" value="" />
656: <input type="hidden" name="upass0" value="" />
657: <input type="hidden" name="udom" value="" />
658: <input type="hidden" name="localpath" value="$env{'form.localpath'}" />
659: <input type="hidden" name="localres" value="$env{'form.localres'}" />
660: </form>
661: ENDSERVERFORM
662: my $coursecatalog;
663: if (($showcoursecat eq '') || ($showcoursecat)) {
664: $coursecatalog = &coursecatalog_link($lt{'catalog'}).'<br />';
665: }
666: my $newuserlink;
667: if ($shownewuserlink) {
668: $newuserlink = &newuser_link($lt{'newuser'}).'<br />';
669: }
670: my $logintitle =
671: '<h2 class="LC_hcell"'
672: .' style="background:'.$loginbox_header_bgcol.';'
673: .' color:'.$loginbox_header_textcol.'">'
674: .$lt{'log'}
675: .'</h2>';
676:
677: my $noscript_warning='<noscript><span class="LC_warning"><b>'
678: .&mt('Use of LON-CAPA requires Javascript to be enabled in your web browser.')
679: .'</b></span></noscript>';
680: my $helpdeskscript;
681: my $contactblock = &contactdisplay(\%lt,$servadm,$showadminmail,
682: $authdomain,\$helpdeskscript,
683: $showhelpdesk,\@possdoms);
684:
685: my $mobileargs;
686: if ($clientmobile) {
687: $mobileargs = 'autocapitalize="off" autocorrect="off"';
688: }
689: my $loginform=(<<LFORM);
690: <form name="client" action="" onsubmit="return(send())">
691: <input type="hidden" name="lextkey" value="$lextkey" />
692: <input type="hidden" name="uextkey" value="$uextkey" />
693: <b><label for="uname">$lt{'un'}</label>:</b><br />
694: <input type="text" name="uname" id="uname" size="15" value="$authusername" readonly="readonly" $mobileargs /><br />
695: <b><label for="upass$now">$lt{'pw'}</label>:</b><br />
696: <input type="password" name="upass$now" id="upass$now" size="15" readonly="readonly" /><br />
697: <b><label for="udom">$lt{'dom'}</label>:</b><br />
698: <input type="text" name="udom" id="udom" size="15" value="$authdomain" readonly="readonly" $mobileargs /><br />
699: <input type="submit" value="$lt{'log'}" />
700: </form>
701: LFORM
702:
703: if ($showbanner) {
704: $r->print(<<HEADER);
705: <!-- The LON-CAPA Header -->
706: <div style="background:$pgbg;margin:0;width:100%;">
707: <img src="$img" border="0" alt="The Learning Online Network with CAPA" class="LC_maxwidth" />
708: </div>
709: HEADER
710: }
711: $r->print(<<ENDTOP);
712: <div style="float:left;margin-top:0;">
713: <div class="LC_Box" style="background:$loginbox_bg;">
714: $logintitle
715: $loginform
716: $noscript_warning
717: </div>
718:
719: <div class="LC_Box" style="padding-top: 10px;">
720: $loginhelp
721: $forgotpw
722: $contactblock
723: $newuserlink
724: $coursecatalog
725: </div>
726: </div>
727:
728: <div>
729: ENDTOP
730: if ($showmainlogo) {
731: $r->print(' <img src="'.$logo.'" alt="" class="LC_maxwidth" />'."\n");
732: }
733: $r->print(<<ENDTOP);
734: $announcements
735: </div>
736: <hr style="clear:both;" />
737: ENDTOP
738: my ($domainrow,$serverrow,$loadrow,$userloadrow,$versionrow);
739: $domainrow = <<"END";
740: <tr>
741: <td align="left" valign="top">
742: <small><b>$lt{'dom'}: </b></small>
743: </td>
744: <td align="left" valign="top">
745: <small><tt> $domain</tt></small>
746: </td>
747: </tr>
748: END
749: $serverrow = <<"END";
750: <tr>
751: <td align="left" valign="top">
752: <small><b>$lt{'serv'}: </b></small>
753: </td>
754: <td align="left" valign="top">
755: <small><tt> $lonhost ($role)</tt></small>
756: </td>
757: </tr>
758: END
759: if ($loadlim) {
760: $loadrow = <<"END";
761: <tr>
762: <td align="left" valign="top">
763: <small><b>$lt{'load'}: </b></small>
764: </td>
765: <td align="left" valign="top">
766: <small><tt> $loadpercent $lt{'perc'}</tt></small>
767: </td>
768: </tr>
769: END
770: }
771: if ($uloadlim) {
772: $userloadrow = <<"END";
773: <tr>
774: <td align="left" valign="top">
775: <small><b>$lt{'userload'}: </b></small>
776: </td>
777: <td align="left" valign="top">
778: <small><tt> $userloadpercent $lt{'perc'}</tt></small>
779: </td>
780: </tr>
781: END
782: }
783: if (($version ne '') && ($version ne '<!-- VERSION -->')) {
784: $versionrow = <<"END";
785: <tr>
786: <td colspan="2" align="left">
787: <small>$version</small>
788: </td>
789: </tr>
790: END
791: }
792:
793: $r->print(<<ENDDOCUMENT);
794: <div style="float: left;">
795: <table border="0" cellspacing="0" cellpadding="0">
796: $domainrow
797: $serverrow
798: $loadrow
799: $userloadrow
800: $versionrow
801: </table>
802: </div>
803: <div style="float: right;">
804: $domainlogo
805: </div>
806: <br style="clear:both;" />
807: </div>
808:
809: <script type="text/javascript">
810: // <![CDATA[
811: // the if prevents the script error if the browser can not handle this
812: if ( document.client.uname ) { document.client.uname.focus(); }
813: // ]]>
814: </script>
815: $helpdeskscript
816:
817: ENDDOCUMENT
818: my %endargs = ( 'noredirectlink' => 1, );
819: $r->print(&Apache::loncommon::end_page(\%endargs));
820: return OK;
821: }
822:
823: sub check_loginvia {
824: my ($domain,$lonhost,$lonidsdir,$balcookie,$linkprot) = @_;
825: if ($domain eq '' || $lonhost eq '' || $lonidsdir eq '') {
826: return;
827: }
828: my %domconfhash = &Apache::loncommon::get_domainconf($domain);
829: my $loginvia = $domconfhash{$domain.'.login.loginvia_'.$lonhost};
830: my $loginvia_exempt = $domconfhash{$domain.'.login.loginvia_exempt_'.$lonhost};
831: my $output;
832: if ($loginvia ne '') {
833: my $noredirect;
834: my $ip = $ENV{'REMOTE_ADDR'};
835: if ($ip eq '127.0.0.1') {
836: $noredirect = 1;
837: } else {
838: if ($loginvia_exempt ne '') {
839: my @exempt = split(',',$loginvia_exempt);
840: if (grep(/^\Q$ip\E$/,@exempt)) {
841: $noredirect = 1;
842: }
843: }
844: }
845: unless ($noredirect) {
846: my ($newhost,$path);
847: if ($loginvia =~ /:/) {
848: ($newhost,$path) = split(':',$loginvia);
849: } else {
850: $newhost = $loginvia;
851: }
852: if ($newhost ne $lonhost) {
853: if (&Apache::lonnet::hostname($newhost) ne '') {
854: if ($balcookie) {
855: my ($balancer,$cookie) = split(/:/,$balcookie);
856: if ($cookie =~ /^($match_domain)_($match_username)_([a-f0-9]+)$/) {
857: my ($udom,$uname,$cookieid) = ($1,$2,$3);
858: unless (&Apache::lonnet::delbalcookie($cookie,$balancer) eq 'ok') {
859: if ((-d $lonidsdir) && (opendir(my $dh,$lonidsdir))) {
860: while (my $filename=readdir($dh)) {
861: if ($filename=~/^(\Q$uname\E_\d+_\Q$udom\E_$match_lonid)\.id$/) {
862: my $handle = $1;
863: my %hash =
864: &Apache::lonnet::get_sessionfile_vars($handle,$lonidsdir,
865: ['request.balancercookie',
866: 'user.linkedenv']);
867: if ($hash{'request.balancercookie'} eq "$balancer:$cookieid") {
868: if (unlink("$lonidsdir/$filename")) {
869: if (($hash{'user.linkedenv'} =~ /^[a-f0-9]+_linked$/) &&
870: (-l "$lonidsdir/$hash{'user.linkedenv'}.id") &&
871: (readlink("$lonidsdir/$hash{'user.linkedenv'}.id") eq "$lonidsdir/$filename")) {
872: unlink("$lonidsdir/$hash{'user.linkedenv'}.id");
873: }
874: }
875: }
876: last;
877: }
878: }
879: closedir($dh);
880: }
881: }
882: }
883: }
884: $output = &redirect_page($newhost,$path,$linkprot);
885: }
886: }
887: }
888: }
889: return $output;
890: }
891:
892: sub redirect_page {
893: my ($desthost,$path,$linkprot) = @_;
894: my $hostname = &Apache::lonnet::hostname($desthost);
895: my $protocol = $Apache::lonnet::protocol{$desthost};
896: $protocol = 'http' if ($protocol ne 'https');
897: unless ($path =~ m{^/}) {
898: $path = '/'.$path;
899: }
900: my $url = $protocol.'://'.$hostname.$path;
901: if ($env{'form.firsturl'} ne '') {
902: $url .='?firsturl='.$env{'form.firsturl'};
903: }
904: if ($linkprot) {
905: my $ltoken = &Apache::lonnet::tmpput({linkprot => $linkprot},$desthost);
906: if ($ltoken) {
907: $url .= (($url =~ /\?/) ? '&' : '?').'ltoken='.$ltoken;
908: }
909: }
910: my $start_page = &Apache::loncommon::start_page('Switching Server ...',undef,
911: {'redirect' => [0,$url],});
912: my $end_page = &Apache::loncommon::end_page();
913: return $start_page.$end_page;
914: }
915:
916: sub contactdisplay {
917: my ($lt,$servadm,$showadminmail,$authdomain,$helpdeskscript,$showhelpdesk,
918: $possdoms) = @_;
919: my $contactblock;
920: my $origmail;
921: if (ref($possdoms) eq 'ARRAY') {
922: if (grep(/^\Q$authdomain\E$/,@{$possdoms})) {
923: $origmail = $Apache::lonnet::perlvar{'lonSupportEMail'};
924: }
925: }
926: my $requestmail =
927: &Apache::loncommon::build_recipient_list(undef,'helpdeskmail',
928: $authdomain,$origmail);
929: unless ($showhelpdesk eq '0') {
930: if ($requestmail =~ m/[^\@]+\@[^\@]+/) {
931: $showhelpdesk = 1;
932: } else {
933: $showhelpdesk = 0;
934: }
935: }
936: if ($servadm && $showadminmail) {
937: $contactblock .= $$lt{'servadm'}.':<br />'.
938: '<tt>'.$servadm.'</tt><br />';
939: }
940: if ($showhelpdesk) {
941: $contactblock .= '<a href="javascript:helpdesk()">'.$lt->{'helpdesk'}.'</a><br />';
942: my $thisurl = &escape('/adm/login');
943: $$helpdeskscript = <<"ENDSCRIPT";
944: <script type="text/javascript">
945: // <![CDATA[
946: function helpdesk() {
947: var possdom = document.client.udom.value;
948: var codedom = possdom.replace( new RegExp("[^A-Za-z0-9.\\-]","g"),'');
949: if (codedom == '') {
950: codedom = "$authdomain";
951: }
952: var querystr = "origurl=$thisurl&codedom="+codedom;
953: document.location.href = "/adm/helpdesk?"+querystr;
954: return;
955: }
956: // ]]>
957: </script>
958: ENDSCRIPT
959: }
960: return $contactblock;
961: }
962:
963: sub forgotpwdisplay {
964: my (%lt) = @_;
965: my $prompt_for_resetpw = 1;
966: if ($prompt_for_resetpw) {
967: return '<a href="/adm/resetpw">'.$lt{'forgotpw'}.'</a>';
968: }
969: return;
970: }
971:
972: sub coursecatalog_link {
973: my ($linkname) = @_;
974: return <<"END";
975: <a href="/adm/coursecatalog">$linkname</a>
976: END
977: }
978:
979: sub newuser_link {
980: my ($linkname) = @_;
981: return '<a href="/adm/createaccount">'.$linkname.'</a>';
982: }
983:
984: 1;
985: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>