Samba-LDAP
view release on metacpan or search on metacpan
scripts/smbldap-useradd view on Meta::CPAN
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
# USA.
# Purpose of smbldap-useradd : user (posix,shadow,samba) add
use strict;
use FindBin;
use FindBin qw($RealBin);
use lib "$RealBin/";
use smbldap_tools;
use Crypt::SmbHash;
#####################
use Getopt::Std;
my %Options;
my $ok = getopts('o:abnmwiPG:u:g:d:s:c:k:t:A:B:C:D:E:F:H:M:N:S:T:?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
print_banner;
print "Usage: $0 [-awmugdsckABCDEFGHMNPST?] username\n";
print " -o add the user in the organizational unit (relative to the user suffix)\n";
print " -a is a Windows User (otherwise, Posix stuff only)\n";
print " -b is a AIX User\n";
print " -w is a Windows Workstation (otherwise, Posix stuff only)\n";
print " -i is a trust account (Windows Workstation)\n";
print " -u uid\n";
print " -g gid\n";
print " -G supplementary comma-separated groups\n";
print " -n do not create a group\n";
print " -d home\n";
print " -s shell\n";
print " -c gecos\n";
print " -m creates home directory and copies /etc/skel\n";
print " -k skeleton dir (with -m)\n";
print " -t time. Wait 'time' seconds before exiting (when adding Windows Workstation)\n";
print " -P ends by invoking smbldap-passwd\n";
print " -A can change password ? 0 if no, 1 if yes\n";
print " -B must change password ? 0 if no, 1 if yes\n";
print " -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n";
print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n";
print " -E sambaLogonScript (DOS script to execute on login)\n";
print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
print " -N surname\n";
print " -S family name\n";
print " -M local mailAddress (comma seperated)\n";
print " -T mailToAddress (forward address) (comma seperated)\n";
print " -? show this help message\n";
exit (1);
}
my $ldap_master=connect_ldap_master();
# cause problems when dealing with getpwuid because of the
# negative ttl and ldap modification
my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
if ($nscd_status == 0) {
system "/etc/init.d/nscd stop > /dev/null 2>&1";
}
# Read only first @ARGV
my $userName = $ARGV[0];
# For computers account, add a trailing dollar if missing
if (defined($Options{'w'})) {
if ($userName =~ /[^\$]$/s) {
$userName .= "\$";
}
}
# untaint $userName (can finish with one or two $)
if ($userName =~ /^([\w -.]+\$?)$/) {
$userName = $1;
} else {
print "$0: illegal username\n";
exit (1);
}
# user must not exist in LDAP (should it be nss-wide ?)
my ($rc, $dn) = get_user_dn2($userName);
if ($rc and defined($dn)) {
print "$0: user $userName exists\n";
exit (9);
} elsif (!$rc) {
print "$0: error in get_user_dn2\n";
exit(10);
}
# Read options
# we create the user in the specified ou (relative to the users suffix)
my $user_ou=$Options{'o'};
my $node;
if (defined $user_ou) {
if (!($user_ou =~ m/^ou=(.*)/)) {
$node=$user_ou;
$user_ou="ou=$user_ou";
} else {
($node)=($user_ou=~m/ou=(.*)/);
}
# $config{usersdn}="$user_ou,$config{usersdn}";
# if the ou does not exist, we create it
my $mesg = $ldap_master->search ( base => "$config{usersdn}",
scope => "one",
filter => "(&(objectClass=organizationalUnit)(ou=$node))"
);
$mesg->code && die $mesg->error;
if ($mesg->count eq 0) {
print "creating $user_ou first (as $user_ou,$config{usersdn})\n";
# add organizational unit
my $add = $ldap_master->add ("ou=$node,$config{usersdn}",
attr => [
'objectclass' => ['top','organizationalUnit'],
'ou' => "$node"
]
);
$add->code && die "failed to add entry: ", $add->error ;
}
$config{usersdn}="$user_ou,$config{usersdn}";
}
my $userUidNumber = $Options{'u'};
if (!defined($userUidNumber)) {
$userUidNumber=get_next_id($config{usersdn},"uidNumber");
} elsif (getpwuid($userUidNumber)) {
die "Uid already exists.\n";
}
if ($nscd_status == 0) {
system "/etc/init.d/nscd start > /dev/null 2>&1";
}
my $createGroup = 0;
my $userGidNumber = $Options{'g'};
# gid not specified ?
if (!defined($userGidNumber)) {
# windows machine => $config{defaultComputerGid}
if (defined($Options{'w'})) {
$userGidNumber = $config{defaultComputerGid};
# } elsif (!defined($Options{'n'})) {
# create new group (redhat style)
# find first unused gid starting from $config{GID_START}
# while (defined(getgrgid($config{GID_START}))) {
# $config{GID_START}++;
# }
# $userGidNumber = $config{GID_START};
# $createGroup = 1;
} else {
# user will have gid = $config{defaultUserGid}
$userGidNumber = $config{defaultUserGid};
}
} else {
my $gid;
if (($gid = parse_group($userGidNumber)) < 0) {
print "$0: unknown group $userGidNumber\n";
exit (6);
}
$userGidNumber = $gid;
}
my $group_entry;
my $userGroupSID;
my $userRid;
my $user_sid;
if (defined $Options{'a'} or defined $Options{'i'}) {
# as grouprid we use the value of the sambaSID attribute for
# group of gidNumber=$userGidNumber
$group_entry = read_group_entry_gid($userGidNumber);
$userGroupSID = $group_entry->get_value('sambaSID');
unless ($userGroupSID) {
print "Error: SID not set for unix group $userGidNumber\n";
print "check if your unix group is mapped to an NT group\n";
exit (7);
}
# as rid we use 2 * uid + 1000
$userRid = 2 * $userUidNumber + 1000;
# let's test if this SID already exist
$user_sid="$config{SID}-$userRid";
my $test_exist_sid=does_sid_exist($user_sid,$config{usersdn});
if ($test_exist_sid->count == 1) {
print "User SID already owned by\n";
# there should not exist more than one entry, but ...
( run in 0.813 second using v1.01-cache-2.11-cpan-f56aa216473 )