#!/usr/local/bin/perl

# NIS+ マップにユーザーを登録するためのスクリプト
#	Programed by TSUCHIYA Masatoshi <tsuchiya@namazu.org>
#	Thu Apr 22 17:55:35 JST 1999


require 5.000;
use strict;
use vars qw/ $USER $GCOS $UID $GID $HOME $BASE $SHELL $SHADOW $MKDIR $MODE $DEBUG $NISCAT $NISADD /;


### 初期値を指定
$USER   = '';
$GCOS   = '';
$UID    = 0;
$GID    = &getgid( 'user' );
$HOME   = 0;
$BASE   = '/home'; # デフォルトのホームディレクトリを決定するための基準ディレクトリ
$SHELL  = '/bin/tcsh';
$SHADOW = '::::::';
$MKDIR  = 0;
$MODE   = 0755;
$DEBUG  = 0;
$NISCAT = '/usr/bin/niscat';
$NISADD = '/usr/bin/nistbladm';


### コマンドラインオプションを解析
while( $_ = shift @ARGV ){
    if( $_ eq '-c' ){
	$GCOS = shift @ARGV;
    } elsif( $_ eq '-d' ){
	$HOME = shift @ARGV;
    } elsif( $_ eq '-g' ){
	$GID = shift @ARGV;
	$GID = &getgid( $GID ) unless $GID =~ /^[0-9]+$/;
    } elsif( $_ eq '-s' ){
	$SHELL = shift @ARGV;
    } elsif( $_ eq '-u' ){
	$UID = shift @ARGV;
    } elsif( $_ eq '-m' ){
	$MKDIR = 1;
    } elsif( $_ eq '-n' ){
	$DEBUG = 1;
    } elsif( /^[a-z0-9]+$/ & ! $USER ){
	$USER = $_;
    } else {
	&print_usage;
	exit 1;
    }
}


### コマンドを実行
$UID  = &getuid( $GID )+1 unless $UID;
$HOME = '/home/' . $USER unless $HOME;
$GCOS = $USER unless $GCOS;
unless( $USER && $UID && $GID && $GCOS && $HOME && $SHELL && $SHADOW ){
    &print_usage;
    exit 1;
}
my $com = sprintf( "%s -a name='%s' passwd='%s' uid=%d gid=%d gcos='%s' home=%s shell=%s shadow='%s' passwd.org_dir",
		   $NISADD, $USER, crypt($USER,time), $UID, $GID, $GCOS, $HOME, $SHELL, $SHADOW );
if( $DEBUG ){
    print "$com\n";
} else {
    system($com) && die "Can't add user to NIS+ map : return code=$?\n";
    if( $MKDIR ){
	mkdir( $HOME, $MODE ) or die "Can't make directory : $!\n";
	chown( $UID, $GID, $HOME ) or rmdir($HOME), die "Can't change owner : $!\n";
    }
}
exit(0);


# 指定されたグループの GID を調べる関数
sub getgid {
    my( $group ) = @_;
    my( $name, $passwd, $gid, $members ) = getgrnam( $group );
    $gid;
}


# 指定されたグループに属している全てのユーザーの UID を調べ、最大の UID を返す関数
sub getuid {
    my( $group ) = @_;
    my @uid;
    open( PASSWD, "$NISCAT passwd.org_dir |" ) or die;
    while( <PASSWD> ){
	my( $name,$passwd,$uid,$gid,$gcos,$home,$shell,$shadow ) = split( /:/, $_, 8 );
	push( @uid, $uid ) if $gid == $group;
    }
    close PASSWD;
    ( sort { $b <=> $a; } @uid )[$[];
}


# 使い方を表示する関数
sub print_usage {
    my( $program ) = ( $0 =~ m!([^/]+)$! );
    print STDERR <<__USAGE__;
NAME
     $program - administer a new user login on the system

SYNOPSIS
     $program [ -c comment ] [ -d dir ] [ -g group ] [ -G gid ]
          [ -m ] [ -u uid ] [ -s shell ] login

DESCRIPTION
     $program adds a new user entry to the NIS+ map.

OPTIONS
     -c comment  Any  text  string.   It  is  generally  a  short
                 description  of the login, and is currently used
                 as the field for the user's full name.

     -d dir      The home directory of the new user.  It defaults
                 to /home/[login],

     -g group    An existing group's  integer  ID  or  character-
                 string  name.

     -m          Create the new user's home directory if it  does
                 not  already  exist.

     -s shell    Full pathname of the program used as the  user's
                 shell  on  login.  It defaults to an empty field
                 causing the  system  to  use  /bin/tcsh  as  the
                 default.   The value of [shell]  must be a valid
                 executable file.

     -u uid      The UID of the new user.  This  UID  must  be  a
                 non-negative  decimal  integer  below  MAXUID as
                 defined in <sys/param.h>.  The UID  defaults  to
                 the  next  available  (unique)  number above the
                 highest number currently assigned.  For example,
                 if UIDs 100, 105, and 200 are assigned, the next
                 default UID number will be 201.  (UIDs from 0-99
                 are reserved by SunOS for future applications.)
__USAGE__
}
