Using the XLDAP Prototype
From a basic install of CentOS 7,
From a basic install of CentOS 7,
Required RPMS
yum install nss-pam-ldapd pam_krb5
#!/usr/bin/perl
use warnings ;
use strict ;
## /n/n paragraph break
## =:: Title page title
## === Header1 h1 header
## ==== Header2 h2 header
## ===== Header3 h3 header
## ====== Header4 h4 header
## =<url url link
## =<url> text url link w/ text
## =<<<file include boxed verbatim file
## =<<<file> tag include boxed verbatim file w/ tag
## =--- begin boxed verbatim (end w/ =---)
## =--- title begin boxed verbatim (end w/ =---) w/ title
## =-- begin white verbatim (end w/ =--)
## =-- title begin white verbatim (end w/ =--) w/ title
## =AUTOINDEX insert directory autoindex (needs .htaccess support)
use POSIX ;
use IO::Handle ;
use File::stat ;
use CGI qw[ escapeHTML ] ;
# --- CGI Framework ---
my $cgi ;
BEGIN # Emit header immediately & redirect STDERR to catch errors...
{
$cgi = CGI->new ;
print $cgi->header ;
STDOUT->autoflush(1) ;
STDERR->autoflush(1) ;
open STDERR, '>&', STDOUT or die ;
}
# --- Load Template and StyleSheet from <DATA> ---
my @stylesheet ;
my @template ;
while (<DATA>)
{
chomp ;
## last if /^__END__/ ;
push @template, $_ if /^__TEMPLATE__/.../^__/ and !/^__/ ;
push @stylesheet, $_ if /^__STYLESHEET__/.../^__/ and !/^__/ ;
}
# --- Stat & Open SFML File ---
my $sfml_file = $ENV{'PATH_TRANSLATED'}
|| $ARGV[0] or die "No input specified...\n" ;
my $sfml_stat = stat $sfml_file or die "Cannot stat $sfml_file: $!\n" ;
my $sfml_date = strftime "%F", localtime $sfml_stat->mtime ;
open SFML, '<', $sfml_file or die "Cannot open $sfml_file: $!\n" ;
# --- Breadcrumb Links ---
my @breadcrumbs ;
my $req = $ENV{'REQUEST_URI'} ;
$req =~ s|/+|/|g ; $req =~ s|^/|| ;
my $link = "" ;
foreach (split '/', $req)
{
$link .= "/$_" ;
push @breadcrumbs, "<a href=$link>$_</a>" ;
}
$breadcrumbs[0] = "<a href=/somsky>WRSomsky</a>" ;
# --- Process SFML File ---
my $title ;
my @content ;
sub cont { push @content, @_ ; }
my $par = 0 ;
sub par { cont "<p>" unless $par ; $par = 1 ; } # begin paragraph
sub rap { cont "</p>\n" if $par ; $par = 0 ; } # end paragraph
my $verb = 0 ;
sub verb
{
cont "<p class=tag>@{[shift]}</p>" if defined $_[0] ;
cont "<pre>" ;
$verb = 1 ;
}
sub verbw
{
cont "<p class=tag>@{[shift]}</p>" if defined $_[0] ;
cont "<pre class=w>" ;
$verb = 1 ;
}
sub brev
{
cont "</pre>" ;
$verb = 0 ;
}
sub verbfile {
my $file = shift ;
my $tag = shift ;
$tag ||= $file ;
my $path = $ENV{'PATH_TRANSLATED'} ;
$path =~ s|[^/]*$|| ; $path .= $file ;
verb "<a href=$file>$tag</a>:" ;
if (open FILE, $path) {
while (<FILE>) { cont escapeHTML $_ ; }
}
else {
cont "<span style='color:#cc0000'>" ;
cont " --- Cannot open '$file' for display --- \n" ;
cont " Path: $path " ;
cont "</span>\n" ;
}
close FILE ;
brev ;
}
sub autoindex
{
use LWP::Simple ;
my $request = $ENV{'REQUEST_URI'} ;
$request =~ s|/[^/]*$|?AUTOINDEX| ;
foreach (split /\n/, get "http://".$ENV{'SERVER_NAME'}."//".$request)
{
cont "$_\n" if m|<pre>|..m|</pre>| and not m|</pre>| ;
}
cont "</pre>" ; # do it this way to drop trailing <hr>
}
while (<SFML>)
{
chomp ;
if (0) {}
elsif ($verb and /^=---?/) { brev ; }
elsif ($verb) { cont escapeHTML "$_\n" ; }
elsif (/^=---\s*(.*)/) { rap ; verb $1 ; }
elsif (/^=--\s*(.*)/) { rap ; verbw $1 ; }
elsif (/^=AUTOINDEX/) { autoindex ; }
elsif (/^=<<<\s*([^>]*)>(.*)/) { verbfile ($1,$2) ; }
elsif (/^=<<<\s*(.*)/) { verbfile ($1) ; }
elsif (/^=<\s*([^>]*)>(.*)/) { cont "<a href=$1>$2</a>\n" ; }
elsif (/^=<\s*(.*)/) { cont "<a href=$1>$1</a>\n" ; }
elsif (/^======\s*(.*)/) { rap ; cont "<h4>$1</h4>\n" ; }
elsif (/^=====\s*(.*)/) { rap ; cont "<h3>$1</h3>\n" ; }
elsif (/^====\s*(.*)/) { rap ; cont "<h2>$1</h2>\n" ; }
elsif (/^===\s*(.*)/) { rap ; cont "<h1>$1</h1>\n" ; }
elsif (/^=::\s*(.*)/) { $title = $1 if not defined $title ; }
elsif (/^\s*$/) { rap ; }
else { par ; cont "$_\n" ; }
}
rap ; # close terminal paragraph, if any
# --- Output HTML Page ---
print $cgi->start_html (
-title => $title,
-style => { -code => join "\n", @stylesheet },
) ;
foreach (@template)
{
s/%%LASTMOD%%/$sfml_date/ ;
s/%%BREADCRUMBS%%/join "::", @breadcrumbs/e ;
s/%%CONTENT%%/join '', @content/e ;
print "$_\n" ;
}
print $cgi->end_html ;
__DATA__ # ====================================================================
__TEMPLATE__ # ----------------------------------------------------------------
<div id=sheet>
<div id="masthead">
<table>
<tr class=banner1><td colspan=2>WRSomsky</td></tr>
<tr class=banner2><td colspan=2>UW Physics & Astronomy Linux Guru</td></tr>
<tr class=nav>
<td class=crumbs>%%BREADCRUMBS%%</td>
<td class=mtime>%%LASTMOD%%</td>
</tr>
</table>
</div>
<div id="content">
%%CONTENT%%
</div>
__STYLESHEET__ # --------------------------------------------------------------
html { font-family: "Open Sans",Helvetica,Arial,sans-serif ; }
body { background: #dd9933 ; margin: 0 ; padding: 1em; }
div#sheet { margin: 0px auto 0px auto ; padding: 1.5em ; }
div#sheet { box-shadow: 0.5em 0.5em 0.25em #573a0f ; }
div#sheet { background: #faebd7 ; }
div#sheet { max-width: 860px ; }
div#masthead { margin-bottom: 2.5em ; }
div#masthead table { width: 100% ; }
div#masthead table { border: 0 ; border-collapse: collapse ; }
div#masthead tr { background: #aaaaaa ; }
div#masthead tr.nav { background: #555555 ; }
div#masthead tr.nav { color: #cccccc ; }
div#masthead a { text-decoration: none ; }
div#masthead a:link { color: #cccccc ; }
div#masthead a:visited { color: #cccccc ; }
div#masthead a:hover { color: #90ff90 ; text-decoration: underline ; }
div#masthead a:active { color: #ffff00 ; text-decoration: underline ; }
div#masthead td.crumbs { width: 100% ; }
div#masthead tr.banner1 { font-size: 200% ; font-weight: bold ; }
div#masthead tr.banner2 { font-size: 120% ; font-weight: normal ; }
div#masthead tr.banner1 { line-height: 1 ; }
div#masthead tr.banner2 { line-height: 1 ; }
div#masthead tr.banner1 td { margin: 0px ; padding: 10px 10px 0px 10px ; }
div#masthead tr.banner2 td { margin: 0px ; padding: 2px 10px 8px 10px ; }
div#masthead tr.nav td { margin: 0px ; padding: 2px 10px 2px 10px ; }
div#content p.tag { margin-bottom: 0.1em ; font-size: 86% ; }
div#content p.tag + pre { margin-top: 0em ; }
div#content pre {
background: #dddddd ;
font-family: monospace ;
border: thin solid #777777 ;
padding: 0.25em 0.50em ;
white-space: pre ;
}
div#content pre.w {
background: #faebd7 ;
padding: 0em 0em ;
border: none ;
}
__END__ # =====================================================================
__END__ # =====================================================================
__END__ # =====================================================================
Verbatim:
This is some < verbatim text
indented & stuff
Verbatim-w:
This is some < verbatim text
indented & stuff
Tagged:
tag
Some verbatim w/ a tag... & stuff
Tagged:
tag
Ditto white Some verbatim w/ a tag... & stuff
Include a file verbatim, w/ altname
uri ldaps://xldap.phys.washington.edu:636 base ou=u_somsky,dc=XLDAP TLS_REQCERT allow
Include a file verbatim, w/ altname
passwd: files ldap shadow: files ldap group: files ldap netgroup: files ldap #-- hosts: files dns #-- aliases: files automount: files bootparams: files ethers: files netmasks: files networks: files protocols: files publickey: files rpc: files services: files
A link: http://cnn.com with text after
A link w/ text Donnie calls this FAKE! with text after
uri ldaps://xldap.phys.washington.edu:636 base ou=u_somsky,dc=XLDAP TLS_REQCERT allow
uid nslcd
gid ldap
tls_reqcert allow
uri ldaps://xldap.phys.washington.edu:636
binddn cn=reader,ou=bindDNs,ou=u_somsky,dc=XLDAP
bindpw reader
bind_timelimit 30
timelimit 30
idle_timelimit 3600
filter group (objectClass=posixGroup)
base group ou=xldapGroup,ou=u_somsky,dc=XLDAP
filter passwd (objectClass=xldapPosixAccount)
base passwd ou=xldapAccount,ou=u_somsky,dc=XLDAP
map passwd uidNumber uwUidNumber
map passwd gidNumber uwGidNumber
map passwd gecos uwDisplayName
## map passwd gecos unitDisplayName
## map passwd homeDirectory uwHomeDirectory
## map passwd homeDirectory unitHomeDirectory
map passwd homeDirectory "/local/users/$uid"
## map passwd loginShell uwLoginShell
## map passwd loginShell unitLoginShell
map passwd loginShell "${uwLoginShell:-/bin/tcsh}"
## ---------------------------------------------------------
## See nslcd.conf(5) for info on maps and map expressions...
## ---------------------------------------------------------
[logging] kdc = FILE:/var/log/krb5kdc.log default = FILE:/var/log/krb5libs.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = NETID.WASHINGTON.EDU [realms] [domain_realm] [appdefaults]
#%PAM-1.0 # required = [default=bad success=ok new_authtok_reqd=ok ignore=ignore] # requisite = [default=die success=ok new_authtok_reqd=ok ignore=ignore] # optional = [default=ignore success=ok new_authtok_reqd=ok ] # sufficient = [default=ignore success=done new_authtok_reqd=done] auth required pam_env.so auth sufficient pam_unix.so try_first_pass auth requisite pam_succeed_if.so uid >= 1000 auth sufficient pam_krb5.so use_first_pass auth required pam_deny.so password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok password requisite pam_succeed_if.so uid >= 1000 password sufficient pam_krb5.so use_authtok password required pam_deny.so account required pam_unix.so broken_shadow account sufficient pam_succeed_if.so uid < 1000 quiet account required pam_ldap.so account optional pam_krb5.so account required pam_permit.so session optional pam_keyinit.so revoke session required pam_limits.so session optional pam_systemd.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so session optional pam_ldap.so session optional pam_krb5.so