more syncs from 3.0
[Samba.git] / examples / LDAP / smbldap-tools / smbldap-useradd.pl
blob99c9525e82430d17d572c8868385cb035d610782
1 #!/usr/bin/perl
3 # This code was developped by IDEALX (http://IDEALX.org/) and
4 # contributors (their names can be found in the CONTRIBUTORS file).
6 # Copyright (C) 2002 IDEALX
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License
10 # as published by the Free Software Foundation; either version 2
11 # of the License, or (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 # USA.
23 # Purpose of smbldap-useradd : user (posix,shadow,samba) add
25 use strict;
26 use smbldap_tools;
27 use smbldap_conf;
29 #####################
31 use Getopt::Std;
32 my %Options;
34 my $ok = getopts('axnmwPG:u:g:d:s:c:k:A:B:C:D:E:F:H:?', \%Options);
36 if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
37 print "Usage: $0 [-awmugdsckGPABCDEFH?] username\n";
38 print " -a is a Windows User (otherwise, Posix stuff only)\n";
39 print " -w is a Windows Workstation (otherwise, Posix stuff only)\n";
40 print " -x creates rid and primaryGroupID in hex instead of decimal\n";
41 print " -u uid\n";
42 print " -g gid\n";
43 print " -G supplementary comma-separated groups\n";
44 print " -n do not create a group\n";
45 print " -d home\n";
46 print " -s shell\n";
47 print " -c gecos\n";
48 print " -m creates home directory and copies /etc/skel\n";
49 print " -k skeleton dir (with -m)\n";
50 print " -P ends by invoking smbldap-passwd.pl\n";
51 print " -A can change password ? 0 if no, 1 if yes\n";
52 print " -B must change password ? 0 if no, 1 if yes\n";
53 print " -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')\n";
54 print " -D sambaHomeDrive (letter associated with home share, like 'H:')\n";
55 print " -E sambaLogonScript (DOS script to execute on login)\n";
56 print " -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')\n";
57 print " -H sambaAcctFlags (samba account control bits like '[NDHTUMWSLKI]')\n";
58 print " -? show this help message\n";
59 exit (1);
62 # cause problems when dealing with getpwuid because of the
63 # negative ttl and ldap modification
64 my $nscd_status = system "/etc/init.d/nscd status >/dev/null 2>&1";
66 if ($nscd_status == 0) {
67 system "/etc/init.d/nscd stop > /dev/null 2>&1";
70 # Read options
71 my $userUidNumber = $Options{'u'};
72 if (!defined($userUidNumber)) {
73 # find first unused uid starting from $UID_START
74 while (defined(getpwuid($UID_START))) {
75 $UID_START++;
77 $userUidNumber = $UID_START;
78 } elsif (getpwuid($userUidNumber)) { die "Uid already exists.\n"; }
80 if ($nscd_status == 0) {
81 system "/etc/init.d/nscd start > /dev/null 2>&1";
85 # as rid we use 2 * uid + 1000
86 my $userRid = 2 * $userUidNumber + 1000;
87 if (defined($Options{'x'})) {
88 $userRid= sprint("%x", $userRid);
91 my $createGroup = 0;
92 my $userGidNumber = $Options{'g'};
93 # gid not specified ?
94 if (!defined($userGidNumber)) {
95 # windows machine => $_defaultComputerGid
96 if (defined($Options{'w'})) {
97 $userGidNumber = $_defaultComputerGid;
98 # } elsif (!defined($Options{'n'})) {
99 # create new group (redhat style)
100 # find first unused gid starting from $GID_START
101 # while (defined(getgrgid($GID_START))) {
102 # $GID_START++;
104 # $userGidNumber = $GID_START;
106 # $createGroup = 1;
108 } else {
109 # user will have gid = $_defaultUserGid
110 $userGidNumber = $_defaultUserGid;
112 } else {
113 my $gid;
114 if (($gid = parse_group($userGidNumber)) < 0) {
115 print "$0: unknown group $userGidNumber\n";
116 exit (6);
118 $userGidNumber = $gid;
121 # as grouprid we use 2 * gid + 1001
122 my $userGroupRid = 2 * $userGidNumber + 1001;
123 if (defined($Options{'x'})) {
124 $userGroupRid = sprint("%x", $userGroupRid);
126 # Read only first @ARGV
127 my $userName = $ARGV[0];
129 # user must not exist in LDAP (should it be nss-wide ?)
130 my ($rc, $dn) = get_user_dn2($userName);
131 if ($rc and defined($dn)) {
132 print "$0: user $userName exists\n";
133 exit (9);
134 } elsif (!$rc) {
135 print "$0: error in get_user_dn2\n";
136 exit(10);
139 my $userHomeDirectory;
140 my $tmp;
141 if (!defined($userHomeDirectory = $Options{'d'}))
143 $userHomeDirectory = $_userHomePrefix."/".$userName;
145 $_userLoginShell = $tmp if (defined($tmp = $Options{'s'}));
146 $_userGecos = $tmp if (defined($tmp = $Options{'c'}));
147 $_skeletonDir = $tmp if (defined($tmp = $Options{'k'}));
149 ########################
151 # MACHINE ACCOUNT
152 if (defined($tmp = $Options{'w'})) {
154 # add a trailing dollar if missing
155 if ($userName =~ /[^\$]$/s) {
156 $userName .= "\$";
159 #print "About to create machine $userName:\n";
161 if (!add_posix_machine ($userName, $userUidNumber, $userGidNumber)) {
162 die "$0: error while adding posix account\n";
165 if (!$with_smbpasswd) {
166 if (!add_samba_machine_mkntpwd($userName, $userUidNumber)) {
167 die "$0: error while adding samba account\n";
169 } else {
170 if (!add_samba_machine($userName)) {
171 die "$0: error while adding samba account\n";
174 my $tmpldif =
175 "dn: uid=$userName,$computersdn
176 changetype: modify
177 sambaAcctFlags: [W ]
180 die "$0: error while modifying accountflags of $userName\n"
181 unless (do_ldapmodify($tmpldif) == 0);
182 undef $tmpldif;
185 exit 0;
188 #######################
190 # USER ACCOUNT
192 # add posix account first
194 my $tmpldif =
195 "dn: uid=$userName,$usersdn
196 objectclass: inetOrgPerson
197 objectclass: posixAccount
198 cn: $userName
199 sn: $userName
200 uid: $userName
201 uidNumber: $userUidNumber
202 gidNumber: $userGidNumber
203 homeDirectory: $userHomeDirectory
204 loginShell: $_userLoginShell
205 gecos: $_userGecos
206 description: $_userGecos
207 userPassword: {crypt}x
211 die "$0: error while adding posix user $userName\n"
212 unless (do_ldapadd($tmpldif) == 0);
214 undef $tmpldif;
216 #if ($createGroup) {
217 # group_add($userName, $userGidNumber);
220 group_add_user($userGidNumber, $userName);
222 my $grouplist;
223 # adds to supplementary groups
224 if (defined($grouplist = $Options{'G'})) {
225 add_grouplist_user($grouplist, $userName);
228 # If user was created successfully then we should create his/her home dir
229 if (defined($tmp = $Options{'m'})) {
230 unless ( $userName =~ /\$$/ ) {
231 if ( !(-e $userHomeDirectory) ) {
232 system "mkdir $userHomeDirectory 2>/dev/null";
233 system "cp -a $_skeletonDir/.[a-z,A-Z]* $_skeletonDir/* $userHomeDirectory 2>/dev/null";
234 system "chown -R $userUidNumber:$userGidNumber $userHomeDirectory 2>/dev/null";
235 system "chmod 700 $userHomeDirectory 2>/dev/null";
241 # Add Samba user infos
242 if (defined($Options{'a'})) {
243 if (!$with_smbpasswd) {
245 my $winmagic = 2147483647;
246 my $valpwdcanchange = 0;
247 my $valpwdmustchange = $winmagic;
248 my $valacctflags = "[UX]";
250 if (defined($tmp = $Options{'A'})) {
251 if ($tmp != 0) {
252 $valpwdcanchange = "0";
253 } else {
254 $valpwdcanchange = "$winmagic";
258 if (defined($tmp = $Options{'B'})) {
259 if ($tmp != 0) {
260 $valpwdmustchange = "0";
261 } else {
262 $valpwdmustchange = "$winmagic";
266 if (defined($tmp = $Options{'H'})) {
267 $valacctflags = "$tmp";
270 my $tmpldif =
271 "dn: uid=$userName,$usersdn
272 changetype: modify
273 objectClass: inetOrgPerson
274 objectclass: posixAccount
275 objectClass: sambaSAMAccount
276 sambaPwdLastSet: 0
277 sambaLogonTime: 0
278 sambaLogoffTime: 2147483647
279 sambaKickoffTime: 2147483647
280 sambaPwdCanChange: $valpwdcanchange
281 sambaPwdMustChange: $valpwdmustchange
282 displayName: $_userGecos
283 sambaAcctFlags: $valacctflags
284 sambaSID: $smbldap_conf::SID-$userRid
288 die "$0: error while adding samba account to posix user $userName\n"
289 unless (do_ldapmodify($tmpldif) == 0);
291 undef $tmpldif;
292 } else {
293 my $FILE="|smbpasswd -s -a $userName >/dev/null" ;
294 open (FILE, $FILE) || die "$!\n";
295 print FILE <<EOF;
300 close FILE;
301 if ($?) {
302 print "$0: error adding samba account\n";
303 exit (10);
305 } # with_smbpasswd
307 my $valscriptpath = "$userName.cmd";
308 my $valprofilepath = "$_userProfile$userName";
309 my $valsmbhome = "$_userSmbHome";
310 my $valhomedrive = "$_userHomeDrive";
312 if (defined($tmp = $Options{'C'})) {
313 $valsmbhome = "$tmp";
316 if (defined($tmp = $Options{'D'})) {
317 $tmp = $tmp.":" unless ($tmp =~ /:/);
318 $valhomedrive = "$tmp";
321 if (defined($tmp = $Options{'E'})) {
322 $valscriptpath = "$tmp";
325 if (defined($tmp = $Options{'F'})) {
326 $valprofilepath = "$tmp";
329 my $tmpldif =
330 "dn: uid=$userName,$usersdn
331 changetype: modify
332 sambaSID: $smbldap_conf::SID-$userRid
333 sambaPrimaryGroupSID: $smbldap_conf::SID-$userGroupRid
334 sambaHomeDrive: $valhomedrive
335 sambaHomePath: $valsmbhome
336 sambaProfilePath: $valprofilepath
337 sambaLogonScript: $valscriptpath
338 sambaLMPassword: XXX
339 sambaNTPassword: XXX
343 die "$0: error while modifying samba account of user $userName\n"
344 unless (do_ldapmodify($tmpldif) == 0);
345 undef $tmpldif;
348 if (defined($Options{'P'})) {
349 exec "/usr/local/sbin/smbldap-passwd.pl $userName"
352 exit 0;
354 ########################################
356 =head1 NAME
358 smbldap-useradd.pl - Create a new user or update default new
359 user information
361 =head1 SYNOPSIS
363 smbldap-useradd.pl [-c comment] [-d home_dir]
364 [-g initial_group] [-G group[,...]]
365 [-m [-k skeleton_dir]]
366 [-s shell] [-u uid [ -o]] [-P]
367 [-A canchange] [-B mustchange] [-C smbhome]
368 [-D homedrive] [-E scriptpath] [-F profilepath]
369 [-H acctflags] login
371 =head1 DESCRIPTION
373 Creating New Users
374 The smbldap-useradd.pl command creates a new user account using
375 the values specified on the command line and the default
376 values from the system.
377 The new user account will be entered into the system
378 files as needed, the home directory will be created, and
379 initial files copied, depending on the command line options.
381 You have to use smbldap-passwd to set the user password.
382 For Samba users, rid is 2*uidNumber+1000, and primaryGroupID
383 is 2*gidNumber+1001. Thus you may want to use
384 smbldap-useradd.pl -a -g "Domain Admins" -u 500 Administrator
385 to create a sambaDomainName administrator (admin rid is 0x1F4 = 500 and
386 grouprid is 0x200 = 512)
388 Without any option, the account created will be an Unix (Posix)
389 account. The following options may be used to add information:
391 -a The user will have a Samba account (and Unix).
393 -w Creates an account for a Samba machine (Workstation), so that
394 it can join a sambaDomainName.
396 -x Creates rid and primaryGroupID in hex (for Samba 2.2.2 bug). Else
397 decimal (2.2.2 patched from cvs or 2.2.x, x > 2)
399 -c comment
400 The new user's comment field (gecos).
402 -d home_dir
403 The new user will be created using home_dir as the value for the
404 user's login directory. The default is to append the login name
405 to default_home and use that as the login directory name.
407 -g initial_group
408 The group name or number of the user's initial login group. The
409 group name must exist. A group number must refer to an already
410 existing group. The default group number is 1.
412 -G group,[...]
413 A list of supplementary groups which the user is also a member
414 of. Each group is separated from the next by a comma, with no
415 intervening whitespace. The groups are subject to the same
416 restrictions as the group given with the -g option. The default
417 is for the user to belong only to the initial group.
419 -m The user's home directory will be created if it does not exist.
420 The files contained in skeleton_dir will be copied to the home
421 directory if the -k option is used, otherwise the files conĀ­
422 tained in /etc/skel will be used instead. Any directories conĀ­
423 tained in skeleton_dir or /etc/skel will be created in the
424 user's home directory as well. The -k option is only valid in
425 conjunction with the -m option. The default is to not create
426 the directory and to not copy any files.
428 -s shell
429 The name of the user's login shell. The default is to leave
430 this field blank, which causes the system to select the default
431 login shell.
433 -u uid The numerical value of the user's ID. This value must be
434 unique, unless the -o option is used. The value must be non-
435 negative. The default is to use the smallest ID value greater
436 than 1000 and greater than every other user.
438 -P ends by invoking smbldap-passwd.pl
440 -A can change password ? 0 if no, 1 if yes
442 -B must change password ? 0 if no, 1 if yes
444 -C sambaHomePath (SMB home share, like '\\\\PDC-SRV\\homes')
446 -D sambaHomeDrive (letter associated with home share, like 'H:')
448 -E sambaLogonScript, relative to the [netlogon] share (DOS script to execute on login, like 'foo.bat')
450 -F sambaProfilePath (profile directory, like '\\\\PDC-SRV\\profiles\\foo')
452 -H sambaAcctFlags, spaces and trailing bracket are ignored (samba account control bits like '[NDHTUMWSLKI]')
454 =head1 SEE ALSO
456 useradd(1)
458 =cut