Saturday, November 29, 2008

Intregrating SAMBA\WINBIND on AIX 4.3.3 with Microsoft Active Directory

Overview: This document is a road map on how you can integrate SAMBA with your Active Directory environment. This configuration will allow your Samba server to appear as a member of Active Directory. It will also allow your telnet sessions to use Active Directory for authentication.

AIX Setup:
Verify your system has all the BOS sub packages from the AIX install CD's.

Install rpm package manager (rpm.rte) with installp:

installp -qacXgd rpm.rte rpm.rte

Install the following rpms (http://www-1.ibm.com/servers/aix/products/aixos/linux/download.html)
If they are all in the same directory, you can do this by doing the following:

rpm -ivh --nodeps *.rpm

Packages Required:

autoconf-2.53-1.aix4.3.noarch.rpm
automake-1.5-1.aix4.3.noarch.rpm
bash-2.05a-1.aix4.3.ppc.rpm
bison-1.34-2.aix4.3.ppc.rpm
db-3.3.11-3.aix4.3.ppc.rpm
flex-2.5.4a-6.aix4.3.ppc.rpm
gawk-3.1.0-2.aix4.3.ppc.rpm
gettext-0.10.39-2.aix4.3.ppc.rpm
glib-1.2.10-2.aix4.3.ppc.rpm
glib-devel-1.2.10-2.aix4.3.ppc.rpm
glib2-2.2.1-3.aix4.3.ppc.rpm
glib2-devel-2.2.1-3.aix4.3.ppc.rpm
gzip-1.2.4a-7.aix4.3.ppc.rpm
libtool-1.4.2-1.aix4.3.ppc.rpm
m4-1.4-14.aix4.3.ppc.rpm
make-3.79.1-3.aix4.3.ppc.rpm
openldap-2.0.21-4.aix4.3.ppc.rpm
openldap-devel-2.0.21-4.aix4.3.ppc.rpm
pkgconfig-0.15.0-1.aix4.3.ppc.rpm
rpm-3.0.5-30.aix4.3.ppc.rpm
sed-3.02-8.aix4.3.ppc.rpm
tar-1.13-4.aix4.3.ppc.rpm

Update PATH and LD_LIBRARY_PATH:

PATH=/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/samba/bin:/usr/local/samba/sbin
LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/lib

Download binutils and gcc binaries:

binutils.2.9.1.tar.gz (http://sunsite.lanet.lv/ftp/unix/aix-binaries/uclapub/binutils/RISC/4.2/exec/)

gcc.3.3.4.tar.Z (http://aixpdslib.seas.ucla.edu/packages/gcc.html)

Download source code for the following:

krb5-1.3.5.tar.gz (http://web.mit.edu/kerberos/www/dist/)
openldap-2.2.18.tar.gz (http://www.openldap.org/software/download/)
samba-3.0.8pre2.tar.gz (http://www.samba.org)

Install binutils:

gzip -d binutils.2.9.1.tar.gz
cp binutils.2.9.1.tar /
tar -xvf binutils.2.9.1.tar
rm /binutils.2.9.1.tar
**Note** Untar the binutils from the / directory so the files are placed into the proper locations.


Install gcc:

gzip -d gcc.3.3.4.tar.Z
cp gcc.3.3.4.tar /
tar -xvf gcc.3.3.4.tar
rm /gcc.3.3.4.tar
**Note** Untar the binutils from the / directory so the files are placed into the proper locations.


Build and install Kerberos:

gzip -d krb5-1.3.5.tar.gz
tar -xvf krb5-1.3.5.tar
cd krb5-1.3.5
./configure --enable-dns --enable-dns-for-kdc --enable-dns-for-realm
make
make install

Build and install OpenLDAP:

gzip -d openldap-2.2.18.tar.gz
tar -xvf openldap-2.2.18.tar
cd openldap-2.2.18
./configure --disable-slurpd --disable-bdb --disable-slapd --without-threads
make
make install

Build and install Samba:

gzip -d samba-3.0.8pre2.tar.gz
tar -xvf samba-3.0.8pre2.tar
cd samba-3.0.8pre2
./configure --with-winbind --with-ldap --with-ads --with-krb5=/usr/local
make
make install

Configure Kerberos:

Edit /etc/krb5.conf to reflect the following (substitute DOMAIN.COM with your domain):

[logging]
default = FILE:/var/log/krb5/libs.log
kdc = FILE:/var/log/krb5/kdc.log
admin_server = FILE:/var/log/krb5/admin.log

[libdefaults]
ticket_lifetime = 24000
default_realm = DOMAIN.COM
forwardable = true
proxiable = true
dns_lookup_realm = false
dns_lookup_kdc = false

[realms]
DOMAIN.COM = {
default_domain = domain.com
kdc = :88
admin_server = :749
}

[domain_realm]
.domain.com = DOMAIN.COM
domain.com = DOMAIN.COM

[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf

[pam]
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false


Configure Samba:

Edit /usr/local/samba/lib/smb.conf to reflect the following (substitute DOMAIN with your domain):
**Note** That the shares are examples and may be different.

[global]
workgroup = DOMAIN
netbios name = HOSTNAME
server string = HOSTNAME
security = ADS
realm = DOMAIN.COM
password server =
wins server =
client use spnego = yes
client signing = yes
encrypt passwords = yes
printcap name = cups
disable spoolss = Yes
show add printer wizard = No
idmap uid = 15000-20000
idmap gid = 15000-20000
winbind separator = +
winbind use default domain = Yes
winbind enum users = yes
winbind enum groups = yes
template homedir = /home/%U
template shell = /bin/bash
use sendfile = Yes
printing = cups
ldap suffix = "dc=DOMAIN, dc=com"
winbind cache time = 0
#Uncomment to allow these options
#log level = 8
#log file = /var/log/samba.log
#max log size = 5000000
#debug timestamp = yes
browseable = yes
obey pam restrictions = yes
auth methods = winbind

[homes]
comment = User Home
path = /home/%U
force group = %U
read only = No
browseable = No

[alpha]
comment = OSCAR Alpha Code (Read/Write)
path = /apps/oscar/alpha
valid users = @dev, @REDHAT
admin users = @dev, @REDHAT
read only = No
browseable = Yes

[beta]
comment = OSCAR Beta Code (Read Only)
path = /apps/oscar/beta
valid users = @dev, @REDHAT
admin users = @dev, @REDHAT
read only = Yes
browseable = Yes

[scripts]
comment = OSCAR Scripts (Read Only)
path = /apps/oscar/scripts
valid users = @dev, @REDHAT
admin users = @dev, @REDHAT
read only = Yes
browseable = Yes

[logs]
comment = OSCAR Logs (Read Only)
path = /apps/logs
valid users = @dev, @REDHAT
admin users = @dev, @REDHAT
force user = oscar
force group = dev
read only = Yes
browseable = Yes

[archive]
comment = OSCAR Archive (Read Only)
path = /apps/archive
valid users = @dev, @REDHAT
admin users = @dev, @REDHAT
force user = oscar
force group = dev
read only = Yes
browseable = Yes

[apps]
comment = OSCAR
path = /apps
valid users = @dev, @REDHAT
admin users = @dev, @REDHAT
read only = No
browseable = Yes

[public]
comment = test
path = /usr/local/source
read only = No
browseable = Yes

**Note** Do not start Samba yet!

Active Directory Integration:

Obtain a kerberos ticket from your AD server by issuing the command:

kinit Administrator

You will then be asked for a password. Put in the Administrator password for your Domain.

To verify the ticket was issued do the following:

klist

The results should appear as follows:

# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: Administrator@DOMAIN.COM

Valid starting Expires Service principal
11/03/04 14:26:23 11/04/04 00:26:22 krbtgt/DOMAIN.COM@DOMAIN.COM
renew until 11/04/04 14:26:23


Kerberos 4 ticket cache: /tmp/tkt0
klist: You have no tickets cached

Once you have obtained kerberos ticket you can join the computer to the domain:

net ads join

Now start the Samba and Winbind:

/usr/local/samba/sbin/smbd -D
/usr/local/samba/sbin/nmbd -D
/usr/local/samba/sbin/winbindd

Winbind and Active Directory Authentication:

First you will need to copy the WINBIND file from where is was created when you compiled Samba to /usr/lib/security:

cp /path/to/samba-3.0.8pre2/nsswitch/WINBIND /usr/lib/security

Next you will need to add a stanza to the file /usr/lib/security/methods.cfg:

WINBIND:
program = /usr/lib/security/WINBIND
options = authonly

Finally you will need to edit /etc/security/users and make sure under the default stanza that SYSTEM is set to WINBIND:

default:
admin = false
login = true
su = true
daemon = true
rlogin = true
sugroups = ALL
admgroups =
ttys = ALL
auth1 = SYSTEM
auth2 =
tpath = nosak
umask = 022
expires = 0
SYSTEM = "WINBIND"
logintimes =
pwdwarntime = 0
account_locked = false
loginretries = 0
histexpire = 0
histsize = 0
minage = 0
maxage = 0
maxexpired = -1
minalpha = 0
minother = 0
minlen = 0
mindiff = 0
maxrepeats = 8
dictionlist =
pwdchecks =

Test your authentication by issuing a telnet to the aix box and login using your Active Directory credentials.

Friday, August 01, 2008

Netbackup Schedules in 5.x or 6.x

Anyone who has managed Netbackup in a large environment knows how difficult it can be to schedule backup jobs. It is not the creation of the schedule that is the issue, but rather the allocation of resources and knowing when you should schedule a job to run. The issue becomes more cumbersome over time due to new policies being created and older jobs taking longer to run.

I personally faced this challenge myself and found that using the built-in function bpschedreq -predict or nbpemreq -predict was just not adequate. Not only was it cumbersome, I found that some of the time it did not even display jobs that I knew were going to run.

To resolve this issue, I wrote the nbpol script. This script when used will allow you to peer into a specific date and see what schedules will kick off and at what time. It also allows you to print out a histogram summarizing where your volume of jobs run. The syntax is as follows:

Usage: nbpol -y (year) -m (month) -d (day) -t (am|pm|all) (-graph)


Below is the actual perl code:

#!/usr/bin/perl
#########################################################################################
# nbpol: Script to determine which policies will run on a given day when policies #
#  are calendar based.        #
# written: Benjamin Schmaus         #
# date: 070108          #
#########################################################################################
use DateTime;
use Getopt::Long;
use CGI;
use Time::Local;
use POSIX qw(strftime);
$first = "0";$last = "0";
$schd1 = "SCHED ";$schd2 = "SCHED";
$counter = "0";
$hour = "0";$minute = "0";$second = "0";
$arraycount = 0;
@gac = 0;
options();
@policies = `/usr/openv/netbackup/bin/admincmd/bppllist -l`;
datetime2();
printf "%-30s %-20s %-15s %-15s\n","Policy","Schedule","Start Time","Duration";
printf "%-30s %-20s %-15s %-15s\n","------","--------","----------","--------";
foreach $policies (@policies) {
 $counter = 0;
 chomp($policies);
 open DATA, "/usr/openv/netbackup/bin/admincmd/bpplsched $policies -l|";
 while () {
  $line = $_;
  chomp($line);
  if ($line =~ /$schd1/ && $first eq "0") { first(); }
  if ($line =~ /$schd2/ && $first eq "1") { checks(); }
 }
 close DATA;
 for ($out = 0; $out < $counter; $out++) {
  $policies =~ s/\s*$//g;
  if ($schedcaldayoweek[$out] =~ /$datum/) {
   parseit();
   if ($windowl > 0) {
    if (($time eq "am") && ($starttime < 12)) {
     printf "%-30s %-20s %-15s %-15s\n",$policies,$schedule2,$starttime,$windowl;
     $gac[int($starttime)] = $gac[int($starttime)] + 1;
    } elsif (($time eq "pm") && ($starttime > 11.99)) {
     printf "%-30s %-20s %-15s %-15s\n",$policies,$schedule2,$starttime,$windowl;
     $gac[int($starttime)] = $gac[int($starttime)] + 1;
    } elsif ($time eq "all") {
     printf "%-30s %-20s %-15s %-15s\n",$policies,$schedule2,$starttime,$windowl;
     $gac[int($starttime)] = $gac[int($starttime)] + 1;
    }
   }
  }
 }
}
if ($graph = "1") {
 graphit();
}
exit; 

sub graphit {
 print "\n\n";
 print "Hr\tNumber of Jobs\n";
 print "--\t---------------\n";
 for ($loop = 0; $loop < 24; $loop++) {
  print "$loop\t";
  for ($loop2 = 0; $loop2 < $gac[$loop]; $loop2++) {
   print "*";
  }
  print "\n";
 }
}

sub options {
 $help="";$year="" ;$month="";$day="";$time="";$graph="";
 GetOptions ('h|help'=>\$help,'y|year=s'=>\$year,'m|month=s'=>\$month,'d|day=s'=>\$day,'t|time=s'=>\$time,'graph'=>\$graph);
 if ($help) {
  print "Usage: nbpol -y  -m  -d  -t  [ -graph ]\n";
  exit;
 }
 if (($year eq "") || ($month eq "") || ($day eq "") || ($time eq "")) {
  print "Usage: nbpol -y  -m  -d  -t  [ -graph ]\n";
  exit;
 }
}

sub parseit {
 $field2 = ($dow*2);
 $field1 = ($dow*2)-1;
 @schedtmp = split(/[ \t]+/,$schedule[$out]);
 $schedule2 = $schedtmp[1];
 @schedwintmp = split(/[ \t]+/,$schedwin[$out]);
 $starttime = ($schedwintmp[$field1]/(60*60));
 $starttime =~ s/(^\d{1,}\.\d{2})(.*$)/$1/;
 $windowl = ($schedwintmp[$field2]/(60*60)); 
 $windowl =~s/(^\d{1,}\.\d{2})(.*$)/$1/;
}

sub datetime2 {
 $dt = DateTime->new(year=>$year, month=>$month,day=>$day,hour=>$hour,minute=>$minute,second=>$second,nanosecond=>00,time_zone=>'America/Chicago',);
 print "$dt\n";
 $dow = $dt->day_of_week;      ##### 1-7 (Monday is 1) - also dow, wday
 $wod = $dt->weekday_of_month();  ##### 1-5 weeks
 if ($dow eq "7") { $dow = "1"; } else { $dow = $dow +1; }
 $datum = "$dow,$wod";
 chomp($datum);
}


sub first {
 $first = "1";
 $schedule[$counter] = "$line";
}

sub checks {
 if ($line =~ /SCHEDCALENDAR/) {
  $schedcalendar[$counter] = "SCHEDCALENDAR enabled";
 }
        if ($line =~ /SCHEDCALDAYOWEEK/) {
                $schedcaldayoweek[$counter] = "$line";
        }
        if ($line =~ /SCHEDWIN/) {
                $schedwin[$counter] = "$line";
        }
        if ($line =~ /SCHEDRES/) {
                $schedres[$counter] = "$line";
        }
        if ($line =~ /SCHEDPOOL/) {
                $schedpool[$counter] = "$line";
        }
        if ($line =~ /SCHEDRL/) {
                $schedrl[$counter] = "$line";
        }
        if ($line =~ /SCHEDFOE/) {
                $schedfoe[$counter] = "$line";
  $first = "0";
  $counter = $counter+1;
        }
}

Wednesday, May 14, 2008

How to get tomorrow's date in BASH shell

Sometimes when you write a script, you need to get tomorrow's date. This can come in handy if you want to see if it is the first day of the next month, and therefore execute a monthly job that should always run at the end of the month.

TOMDATE=$(TZ=CDT-24 /bin/date +%d)

What Perl modules are installed?


Sometimes the package manager of our favorite Linux distribution does not have the Perl modules we need for a development project we are working on.   In that case we have to resort to using CPAN which is analogous to Pip for Python modules.

perl -MCPAN -e shell
cpan> install package-name

Now that process works very well and even prepends dependent modules. However this leads to one pesky problem. How do you know what modules have already been installed and their version?

Well a friend of mine pointed out this gem which is not readily documented on Google:

perl -MCPAN -e 'print CPAN::Shell->r '

This command will tell you what modules and version is installed on the system it is run on.

The other option of course, and I did this at the University of Minnesota, is to download the source Perl modules and make RPM packages. However I find using the CPAN shell to be more convenient.