3 # Populate a LDAP base for Samba-LDAP usage
5 # $Id: smbldap-populate,v 1.26 2005/05/27 14:21:00 jtournier Exp $
7 # This code was developped by IDEALX (http://IDEALX.org/) and
8 # contributors (their names can be found in the CONTRIBUTORS file).
10 # Copyright (C) 2001-2002 IDEALX
12 # This program is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU General Public License
14 # as published by the Free Software Foundation; either version 2
15 # of the License, or (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 # . Create an initial LDAP database suitable for Samba 2.2
29 # . For lazy people, replace ldapadd (with only an ldif parameter)
33 use FindBin qw($RealBin);
41 # objectclass of the suffix
43 "ou" => "organizationalUnit",
44 "o" => "organization",
51 my $ok = getopts('a:b:e:i:k:l:m:u:g:?', \%Options);
52 if ( (!$ok) || ($Options{'?'}) ) {
54 print "Usage: $0 [-abeiklug?] [ldif]\n";
55 print " -u uidNumber first uidNumber to allocate (default: 1000)\n";
56 print " -g gidNumber first uidNumber to allocate (default: 1000)\n";
57 print " -a user administrator login name (default: root)\n";
58 print " -b user guest login name (default: nobody)\n";
59 print " -k uidNumber administrator's uidNumber (default: 0)\n";
60 print " -l uidNumber guest's uidNumber (default: 999)\n";
61 print " -m gidNumber administrator's gidNumber (default: 0)\n";
62 print " -e file export ldif file\n";
63 print " -i file import ldif file\n";
64 print " -? show this help message\n";
70 my $domain = $config{sambaDomain};
71 if (! defined $domain) {
72 print STDERR "error: domain name not found !\n";
73 print STDERR "possible reasons are:\n";
74 print STDERR ". incorrect 'sambaDomain' parameter in smbldap.conf\n";
75 print STDERR ". incorrect 'samba_conf' definition in smbldap_tools.pm\n";
79 #$config{sambaUnixIdPooldn}="sambaDomainName=$domain,$config{suffix}";
81 my $firstuidNumber=$Options{'u'};
82 if (!defined($firstuidNumber)) {
86 my $firstgidNumber=$Options{'g'};
87 if (!defined($firstgidNumber)) {
91 my $tmp_ldif_file=$Options{'e'};
92 if (!defined($tmp_ldif_file)) {
93 $tmp_ldif_file="/tmp/$$.ldif";
96 my $adminName = $Options{'a'};
97 if (!defined($adminName)) {
101 my $guestName = $Options{'b'};
102 if (!defined($guestName)) {
103 $guestName = "nobody";
106 my $adminUidNumber=$Options{'k'};
108 if (!defined($adminUidNumber)) {
109 $adminUidNumber = "0";
112 $adminrid=(2*$adminUidNumber+ 1000)
115 my $guestUidNumber=$Options{'l'};
116 if (!defined($guestUidNumber)) {
117 $guestUidNumber = "999";
120 my $adminGidNumber=$Options{'m'};
121 if (!defined($adminGidNumber)) {
122 $adminGidNumber = "0";
125 my $_ldifName = $Options{'i'};
127 my $exportFile = $Options{'e'};
128 if (!defined($exportFile)) {
129 $exportFile = "base.ldif";
132 print "Populating LDAP directory for domain $domain ($config{SID})\n";
133 if (!defined($_ldifName)) {
138 print "(using builtin directory structure)\n\n";
139 if ($config{suffix} =~ m/([^=]+)=([^,]+)/) {
142 $objcl = $oc{$attr} if (exists $oc{$attr});
143 if (!defined($objcl)) {
144 $objcl = "myhardcodedobjectclass";
147 die "can't extract first attr and value from suffix $config{suffix}";
149 #print "$attr=$val\n";
150 my ($type,$ou_users,$ou_groups,$ou_computers,$ou_idmap,$cnsambaUnixIdPool);
151 ($type,$ou_users)=($config{usersdn}=~/(.*)=(.*),$config{suffix}/);
152 ($type,$ou_groups)=($config{groupsdn}=~/(.*)=(.*),$config{suffix}/);
153 ($type,$ou_computers)=($config{computersdn}=~/(.*)=(.*),$config{suffix}/);
154 if (defined $config{idmapdn}) {
155 ($type,$ou_idmap)=($config{idmapdn}=~/(.*)=(.*),$config{suffix}/);
157 ($type,$cnsambaUnixIdPool)=($config{sambaUnixIdPooldn}=~/(.*)=(.*),$config{suffix}/);
159 my ($organisation,$ext);
160 if ($config{suffix} =~ m/dc=([^=]+),dc=(.*)$/) {
161 ($organisation,$ext) = ($config{suffix} =~ m/dc=([^=]+),dc=(.*)$/);
162 } elsif ($config{suffix} =~ m/dc=(.*)$/) {
166 if ($organisation ne '') {
167 $org = "\nobjectclass: organization\no: $organisation";
171 my $entries="dn: $config{suffix}
172 objectClass: $objcl$org
176 objectClass: organizationalUnit
179 dn: $config{groupsdn}
180 objectClass: organizationalUnit
183 dn: $config{computersdn}
184 objectClass: organizationalUnit
185 ou: $ou_computers\n";
187 if (defined $config{idmapdn}) {
188 $entries.="\ndn: $config{idmapdn}
189 objectClass: organizationalUnit
193 $entries.="\ndn: uid=$adminName,$config{usersdn}
196 objectClass: inetOrgPerson
197 objectClass: sambaSAMAccount
198 objectClass: posixAccount
199 objectClass: shadowAccount
200 gidNumber: $adminGidNumber
202 uidNumber: $adminUidNumber\n";
203 if (defined $config{userHome} and $config{userHome} ne "") {
204 my $userHome=$config{userHome};
205 $userHome=~s/\%U/$adminName/;
206 $entries.="homeDirectory: $userHome\n";
208 $entries.="homeDirectory: /dev/null\n";
210 $entries.="sambaPwdLastSet: 0
212 sambaLogoffTime: 2147483647
213 sambaKickoffTime: 2147483647
215 sambaPwdMustChange: 2147483647\n";
216 if (defined $config{userSmbHome} and $config{userSmbHome} ne "") {
217 my $userSmbHome=$config{userSmbHome};
218 $userSmbHome=~s/\%U/$adminName/;
219 $entries.="sambaHomePath: $userSmbHome\n";
221 if (defined $config{userHomeDrive} and $config{userHomeDrive} ne "") {
222 $entries.="sambaHomeDrive: $config{userHomeDrive}\n";
224 if (defined $config{userProfile} and $config{userProfile} ne "") {
225 my $userProfile=$config{userProfile};
226 $userProfile=~s/\%U/$adminName/;
227 $entries.="sambaProfilePath: $userProfile\n";
229 $entries.="sambaPrimaryGroupSID: $config{SID}-512
233 sambaSID: $config{SID}-$adminrid
234 loginShell: /bin/false
235 gecos: Netbios Domain Administrator
237 dn: uid=$guestName,$config{usersdn}
240 objectClass: inetOrgPerson
241 objectClass: sambaSAMAccount
242 objectClass: posixAccount
243 objectClass: shadowAccount
246 uidNumber: $guestUidNumber
247 homeDirectory: /dev/null
250 sambaLogoffTime: 2147483647
251 sambaKickoffTime: 2147483647
253 sambaPwdMustChange: 2147483647\n";
254 if (defined $config{userSmbHome} and $config{userSmbHome} ne "") {
255 my $userSmbHome=$config{userSmbHome};
256 $userSmbHome=~s/\%U/$guestName/;
257 $entries.="sambaHomePath: $userSmbHome\n";
259 if (defined $config{userHomeDrive} and $config{userHomeDrive} ne "") {
260 $entries.="sambaHomeDrive: $config{userHomeDrive}\n";
262 if (defined $config{userProfile} and $config{userProfile} ne "") {
263 my $userProfile=$config{userProfile};
264 $userProfile=~s/\%U/$guestName/;
265 $entries.="sambaProfilePath: $userProfile\n";
267 $entries.="sambaPrimaryGroupSID: $config{SID}-514
268 sambaLMPassword: NO PASSWORDXXXXXXXXXXXXXXXXXXXXX
269 sambaNTPassword: NO PASSWORDXXXXXXXXXXXXXXXXXXXXX
270 # account disabled by default
271 sambaAcctFlags: [NUD ]
272 sambaSID: $config{SID}-2998
273 loginShell: /bin/false
275 dn: cn=Domain Admins,$config{groupsdn}
276 objectClass: posixGroup
277 objectClass: sambaGroupMapping
280 memberUid: $adminName
281 description: Netbios Domain Administrators
282 sambaSID: $config{SID}-512
284 displayName: Domain Admins
286 dn: cn=Domain Users,$config{groupsdn}
287 objectClass: posixGroup
288 objectClass: sambaGroupMapping
291 description: Netbios Domain Users
292 sambaSID: $config{SID}-513
294 displayName: Domain Users
296 dn: cn=Domain Guests,$config{groupsdn}
297 objectClass: posixGroup
298 objectClass: sambaGroupMapping
301 description: Netbios Domain Guests Users
302 sambaSID: $config{SID}-514
304 displayName: Domain Guests
306 dn: cn=Domain Computers,$config{groupsdn}
307 objectClass: posixGroup
308 objectClass: sambaGroupMapping
311 description: Netbios Domain Computers accounts
312 sambaSID: $config{SID}-515
314 displayName: Domain Computers
316 dn: cn=Administrators,$config{groupsdn}
317 objectClass: posixGroup
318 objectClass: sambaGroupMapping
321 description: Netbios Domain Members can fully administer the computer/sambaDomainName
322 sambaSID: S-1-5-32-544
324 displayName: Administrators
326 #dn: cn=Users,$config{groupsdn}
327 #objectClass: posixGroup
328 #objectClass: sambaGroupMapping
331 #description: Netbios Domain Ordinary users
332 #sambaSID: S-1-5-32-545
336 #dn: cn=Guests,$config{groupsdn}
337 #objectClass: posixGroup
338 #objectClass: sambaGroupMapping
341 #memberUid: $guestName
342 #description: Netbios Domain Users granted guest access to the computer/sambaDomainName
343 #sambaSID: S-1-5-32-546
347 #dn: cn=Power Users,$config{groupsdn}
348 #objectClass: posixGroup
349 #objectClass: sambaGroupMapping
352 #description: Netbios Domain Members can share directories and printers
353 #sambaSID: S-1-5-32-547
355 #displayName: Power Users
357 dn: cn=Account Operators,$config{groupsdn}
358 objectClass: posixGroup
359 objectClass: sambaGroupMapping
361 cn: Account Operators
362 description: Netbios Domain Users to manipulate users accounts
363 sambaSID: S-1-5-32-548
365 displayName: Account Operators
367 #dn: cn=System Operators,$config{groupsdn}
368 #objectClass: posixGroup
369 #objectClass: sambaGroupMapping
371 #cn: System Operators
372 #description: Netbios Domain System Operators
373 #sambaSID: S-1-5-32-549
375 #displayName: System Operators
377 dn: cn=Print Operators,$config{groupsdn}
378 objectClass: posixGroup
379 objectClass: sambaGroupMapping
382 description: Netbios Domain Print Operators
383 sambaSID: S-1-5-32-550
385 displayName: Print Operators
387 dn: cn=Backup Operators,$config{groupsdn}
388 objectClass: posixGroup
389 objectClass: sambaGroupMapping
392 description: Netbios Domain Members can bypass file security to back up files
393 sambaSID: S-1-5-32-551
395 displayName: Backup Operators
397 dn: cn=Replicators,$config{groupsdn}
398 objectClass: posixGroup
399 objectClass: sambaGroupMapping
402 description: Netbios Domain Supports file replication in a sambaDomainName
403 sambaSID: S-1-5-32-552
405 displayName: Replicators
408 if ("sambaDomainName=$domain,$config{suffix}" eq $config{sambaUnixIdPooldn}) {
409 $entries.="dn: sambaDomainName=$domain,$config{suffix}
410 objectClass: sambaDomain
411 objectClass: sambaUnixIdPool
412 sambaDomainName: $domain
413 sambaSID: $config{SID}
414 uidNumber: $firstuidNumber
415 gidNumber: $firstgidNumber";
417 $entries.="dn: $config{sambaUnixIdPooldn}
418 objectClass: inetOrgPerson
419 objectClass: sambaUnixIdPool
420 uidNumber: $firstuidNumber
421 gidNumber: $firstgidNumber
422 cn: $cnsambaUnixIdPool
423 sn: $cnsambaUnixIdPool";
425 open (FILE, ">$tmp_ldif_file") || die "Can't open file $tmp_ldif_file: $!\n";
432 $tmp_ldif_file=$_ldifName;
435 if (!defined $Options{'e'}) {
436 my $ldap_master=connect_ldap_master();
437 my $ldif = Net::LDAP::LDIF->new($tmp_ldif_file, "r", onerror => 'undef' );
438 while ( not $ldif->eof() ) {
439 my $entry = $ldif->read_entry();
440 if ( $ldif->error() ) {
441 print "Error msg: ",$ldif->error(),"\n";
442 print "Error lines:\n",$ldif->error_lines(),"\n";
445 # we first check if the entry exist
446 my $mesg = $ldap_master->search (
449 filter => "objectclass=*"
454 print "entry $dn already exist. ";
455 if ($dn eq $config{sambaUnixIdPooldn}) {
456 print "Updating it...\n";
458 foreach my $attr_tmp ($entry->attributes) {
459 push(@mods,$attr_tmp=>[$entry->get_value("$attr_tmp")]);
461 my $modify = $ldap_master->modify ( "$dn",
462 'replace' => { @mods },
464 $modify->code && warn "failed to modify entry: ", $modify->error ;
469 print "adding new entry: $dn\n";
470 my $result=$ldap_master->add($entry);
471 $result->code && warn "failed to add entry: ", $result->error ;
475 $ldap_master->unbind;
476 if (!defined $Options{'i'}) {
477 system "rm -f $tmp_ldif_file";
480 # secure the admin account
481 print "\nPlease provide a password for the domain $adminName: \n";
482 system("$RealBin/smbldap-passwd $adminName");
487 print "exported ldif file: $tmp_ldif_file\n";
492 ########################################
496 smbldap-populate - Populate your LDAP database
500 smbldap-populate [ldif-file]
504 The smbldap-populate command helps to populate an LDAP server by adding the necessary entries : base suffix (doesn't abort if already there), organizational units for users, groups and computers, builtin users : Administrator and guest, builtin groups (though posixAccount only, no SambaTNG support).
507 Your local administrator login name (default: Administrator)
510 Your local guest login name (default: nobody)
516 import an ldif file (Options -a and -b will be ignored)
520 /etc/opt/IDEALX/smbldap-tools/smbldap.conf : main configuration
521 /etc/opt/IDEALX/smbldap-tools/smbldap_bind.conf : credentials for binding to the directory