Novell Home

Creating Home Directories, Rights, and Quotas with ICE

Novell Cool Solutions: Feature
By Bo Bonnevie

Digg This - Slashdot This

Posted: 25 Oct 2006
 

Problem

I wanted to create user home directories, home directory rights, and quotas when creating users with ICE. I needed a single solution that runs entirely on a Netware 6.5 server as a background process.

Solution

I used TRUSTEE.NLM and TOOLBOX to do this. A Perl script reads the new user data from a file, then creates an LDIF file and a TRUSTEE input file. The users, home directories, and home directory properties are created with system calls to ICE, mkdir (TOOLBOX), and TRUSTEE.

I have put a sample perl script here (http://www.ru.ac.za/~ccbb/) and included it below.

Note: This solution was tested with Netware 6.5, TOOLBOX.NLM, ICE.NLM, and TRUSTEE.NLM.

Example

#!perl

# Author: Bo Bonnevie, October 2006
#         Take argv[0] as input file
#         User home directories are in sys:home\ {followed by context}

use Net::LDAP;
use Net::LDAP::LDIF;
use File::Path qw(rmtree);
use File::Basename qw(basename);
use Net::SMTP;

$PORT = 389;
$SSL_PORT = 636;
$ADMIN = 'cn=admin,o=YOUR-TREE-NAME';
$PASSWD = 'adminpwd';

$mailserver = 'mailserver';
$emailaddr = 'email-address';  # Who you send the log to
$dir  = 'sys:etc/cron';
$dir1 = 'sys:home/reg-user';  # user data input directory
$file1 = $ARGV[0];            # user data input file
        # format: ou; cn; first names; surname; email; password; group
($file, $ext) = split('\.', $file1);
print "$file1 $file\n";
$file2 = $file . '-new.ldif';
$file3 = $file . '-pwd.ldif';
$file4 = $file . '-pwd.ncf';
$file5 = $file . '-new.ncf';
$file6 = $file . '-pwdice.log';
$file7 = $file . '-pwderr.log';
$file9 = $file . '-newice.log';
$file10 = $file . '-newerr.log';
$file11 = $file . '-trustee.dat';
$file12 = 'sys:trustee.log';

system("del $file12");  # better clear these log files out first
system("del $dir/$file6");
system("del $dir/$file7");
system("del $dir/$file9");
system("del $dir/$file10");

if (-e "$dir1/$file1") {

  # Get name of local host
  open(hostfile, "sys:etc/hostname") or die "Can't open hostfile: $!\n";
  while ($line = ) {
     ($hostip, $hostfullname) = split(" ", $line);
     ($hostname, $S1) = split('\.', $hostfullname);
  }
  close(hostfile);

  # write .ncf scripts to run ICE
  open(NCF, ">$dir/$file4") or die "Can't open $file4: $!\n";
    print NCF "# This file was generated by $0\n";
    print NCF "# " . localtime() . "\n";
    print NCF "ice -b -l $dir/$file6 -o -e $dir/$file7 -S LDIF -f $dir1/$file3 -D LDAP -s $hostfullname -p 389 -d $ADMIN -w $PASSWD\n";
  close(NCF);

  open(NCF, ">$dir/$file5") or die "Can't open $file5: $!\n";
    print NCF "# This file was generated by $0\n";
    print NCF "# " . localtime() . "\n";
    print NCF "ice -b -l $dir/$file9 -o -e $dir/$file10 -S LDIF -f $dir1/$file2 -D LDAP -s $hostfullname -p 389 -d $ADMIN -w $PASSWD\n";
  close(NCF);


  #connect to the server
  until($ldap = Net::LDAP->new($hostip, port => $PORT)) {
    die "Can not connect to ldap://$hostip:$PORT/" if ++$count > 10;
    sleep 1;
  }

  $r = $ldap->bind($ADMIN, password => $PASSWD, version=>3);
  die $r->error if $r->code;

  open(SREG, "$dir1/$file1") or die "Can't open $file1: $!\n";
  open(NEWREG, ">$dir1/$file2") or die "Can't open $file2: $!\n";
  open(TRUSTEE, ">$dir1/$file11") or die "Can't open $file11: $!\n";
  open(SETPASS, ">$dir1/$file3") or die "Can't open $file3: $!\n";
  print NEWREG "# This LDIF file was generated by $0\n";
  print NEWREG "# " . localtime() . "\n";
  print NEWREG "version: 1\n\n";
  print SETPASS "# This LDIF file was generated by $0\n";
  print SETPASS "# " . localtime() . "\n";
  print SETPASS "version: 1\n\n";
  print TRUSTEE "TRUSTEE.NLM v1.10\n";
  while ($line = ) {
    ($ou, $cn, $fn, $ln, $em, $pw, $group) = split(";", $line);
    @email = split(" ", $em); # get rid of white spaces
    @passw = split(" ", $pw);
    @sn = split(" ", $ln);
    @firstnames = split(" ", $fn);

# Depending on your setup you need to set these appropiately.
# You may want to include them in the data input file, for example.
# NB For TRUSTEE to work it has to run on the server with the relevant
# file system
    $quota = "40000";
    $mserver = "NetwareServerName";

    $BASEDN = "ou=$ou,o=ru";
    $searchstring="(&(objectclass=user)(cn=$cn))";
    $attnames=["dn","cn","surname","mail","groupmembership"];
    print "$co $cn @firstnames @sn\n";
    $r = $ldap->search(base => $BASEDN,
scope=> 'sub',
filter => $searchstring,
attrs=> $attnames);
    if ($r->entries) { # user exists, so change password
       print SETPASS "dn: cn=$cn, ou=$ou, o=ru\n";
       print SETPASS "changetype: modify\n";
       print SETPASS "replace: userpassword\n";
       print SETPASS "userpassword: @passw\n\n";

    }
    else { # user does not exist, so new registration
       print NEWREG "dn: cn=$cn, ou=$ou, o=ru\n";
       print NEWREG "changetype: add\n";
       print NEWREG "objectclass: top\n";
       print NEWREG "objectclass: person\n";
       print NEWREG "objectClass: organizationalPerson\n";
       print NEWREG "objectClass: iNetOrgPerson\n";
       print NEWREG "objectClass: ndsLoginProperties\n";
       print NEWREG "sn: @sn\n";
       print NEWREG "givenName: @firstnames[0]\n";
       print NEWREG "displayname: @firstnames[0] @sn\n";
       print NEWREG "Language: ENGLISH\n";
       print NEWREG "messageServer: cn=$mserver,o=RU\n";
       print NEWREG "allowUnlimitedCredit: FALSE\n";
       print NEWREG "accountBalance: 0\n";
       print NEWREG "minimumAccountBalance: 0\n";
       print NEWREG "passwordRequired: TRUE\n";
       print NEWREG "passwordMinimumLength: 6\n";
       print NEWREG "passwordAllowChange: TRUE\n";
       print NEWREG "mail: @email\n";
       print NEWREG "ndsHomeDirectory: cn=$mserver\_SYS,o=RU#0#/home/$ou/$cn\n";
       if ($group1 ne '') {
         print NEWREG "groupMembership: $group1\n";
       }
       print NEWREG "userpassword: @passw\n\n";
       system("mkdir $mserver/sys:home/$ou/$cn");
       print TRUSTEE "\"ATTR\",\"sys:home/$ou/$cn\",\"LONG\",\"A\",\"\"\n";
       print TRUSTEE "\"OWNER\",\"sys:home/$ou/$cn\",\"LONG\",\"admin.RU\",\"\"\n";
       print TRUSTEE "\"TRUSTEE\",\"sys:home/$ou/$cn\",\"LONG\",\"$cn.$ou.RU\",\"RWCEMF\"\n";
       print TRUSTEE "\"USERQUOTA\",\"sys:\",\"LONG\",\"$cn.$ou.RU\",\"$quota\"\n";
    }
  }
  close(SREG);
  close(NEWREG);
  close(SETPASS);
  close(TRUSTEE);

  $ldap->unbind;

# Run new registration
# Set home directory rights and quota using TRUSTEE.NLM
# Mail the results
    system("sys:etc\\cron\\$file5");
    sleep(1);
    system("sys:system\\trustee restore $dir1\\$file11");

    $smtp = Net::SMTP->new($mailserver) or die "$@\n";
    $smtp->mail($ENV{USER});
    $smtp->to($emailaddr);
    $smtp->data();
    $smtp->datasend("To: $emailaddr\n");
    $smtp->datasend("From: cron\@$hostfullname\n");
        $subject = "$hostname: User registration from $file1";
        $smtp->datasend("Subject: $subject\n\n");
        if (-r "$dir1/$file2") {
           open(NEWREG,"$dir1/$file2") or die "Can't open $file2: $!\n";
           while ($line = ) {
                  $smtp->datasend("$line");
           }
           close(NEWREG);
        }
        else {
          $smtp->datasend("Can not open $file3 for reading\n");
        }
        if (-r "$dir/$file9") {
           open(ICE,"$dir/$file9") or die "Can't open $file9: $!\n";
           while ($line = ) {
                  $smtp->datasend("$line");
           }
           close(ICE);
        }
        else {
          $smtp->datasend("Can not open $file9 for reading\n");
        }
        if (-r "$dir/$file10") {
           open(ICEERR,"$dir/$file10") or die "Can't open $file10: $!\n";
           while ($line = ) {
                  $smtp->datasend("$line");
           }
           close(ICEERR);
        }
        else {
          $smtp->datasend("Can not open $file10 for reading\n");
        }
        if (-r "$file12") {
           open(TRUSTEES,"$file12") or die "Can't open $file12: $!\n";
           while ($line = ) {
                  $smtp->datasend("$line");
           }
           close(TRUSTEES);
        }
        else {
          $smtp->datasend("Can not open $file12 for reading\n");
        }
    $smtp->dataend();
    $smtp->quit;

#  Change passwords and mail the results
    system("sys:etc\\cron\\$file4");
    sleep(2);
    $smtp = Net::SMTP->new($mailserver) or die "$@\n";
    $smtp->mail($ENV{USER});
    $smtp->to($emailaddr);
    $smtp->data();
    $smtp->datasend("To: $emailaddr\n");
    $smtp->datasend("From: cron\@$hostfullname\n");
        $subject = "$hostname: Password changes from $file1";
        $smtp->datasend("Subject: $subject\n\n");
        if (-r "$dir1/$file3") {
           open(SETPASS,"$dir1/$file3") or die "Can't open $file3: $!\n";
           while ($line = ) {
                  $smtp->datasend("$line");
           }
           close(SETPASS);
        }
        else {
          $smtp->datasend("Can not open $file3 for reading\n");
        }
        if (-r "$dir/$file6") {
           open(ICE,"$dir/$file6") or die "Can't open $file6: $!\n";
           while ($line = ) {
                  $smtp->datasend("$line");
           }
           close(ICE);
        }
        else {
          $smtp->datasend("Can not open $file6 for reading\n");
        }
        if (-r "$dir/$file7") {
           open(ICEERR,"$dir/$file7") or die "Can't open $file7: $!\n";
           while ($line = ) {
                  $smtp->datasend("$line");
           }
           close(ICEERR);
        }
        else {
          $smtp->datasend("Can not open $file7 for reading\n");
        }
    $smtp->dataend();
    $smtp->quit;
    sleep(3);

  rename "$dir1/$file1", "$dir1/$file.bak";
}


Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

© 2014 Novell