Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Convert 10.3x LDAP database to UNIX passwd file OS X Server
I have just completed my first really challenging (for me) UNIX shell script and I'm quite proud of myself. I run the Mac section of a very cross-platform lab at an art school in New York. We have all the Macs using network home accounts authenticating on a Mac OS X Server and mounting on an NFS mount point run from a Linux box (it's a long story). Sometimes, it's really convenient for me to have a standard flat BSD passwd file to give to the UNIX SysAdmin so we can sync up the user data between Mac and UNIX. The flat file is also very handy to have around if anything goes wrong with your user database. It can be used to very easily rebuild that database in the event of a catasrophe. Or if you just want to rebuild your server for fun without re-entering all the users and their passwords by hand.

Back in the NetInfo days this was no problem -- use nidump to generate just such a file directly from the NetInfo DB. As of Panther, however, Mac OS X Server uses LDAP exclusively for network home accounts. But I still need that flat file. Apple provides a command-line command called dscl, which will output certain data from the LDAP database, but it will not simply create a flat file like nidump would. So, I've written a script that uses dscl, foreach and (of all things) awk to create a passwd file from the LDAP database. I realize it's very sloppy (I'm sorry, but awk is INSANE) but hey, it works. And like I said I'm proud. Maybe someone else can use it. Or perhaps it's possible that I'm the only person in the world who needs to do this.

To use the script, view the source, then copy and paste all of it into a plain text file. Save it somewhere handy. Make it executable (chmod 755 /Path/To/File). Then just drag it into a Terminal window, hit return and type your password. If you have a large LDAP database, it will take a few minutes ... but when it's done, there will be a file on your Desktop called UserList-FINAL.txt. That's your passwd file!
    •    
  • Currently 1.88 / 5
  You rated: 3 / 5 (8 votes cast)
 
[15,531 views]  

Convert 10.3x LDAP database to UNIX passwd file | 7 comments | Create New Account
Click here to return to the 'Convert 10.3x LDAP database to UNIX passwd file' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Convert 10.3x LDAP database to UNIX passwd file
Authored by: Mortimer.CA on Aug 02, '04 12:26:14PM

If you want to always have a flat file backup, most LDAP servers allow for dumping to an LDIF file (see RFC 2849). Since OS X Server's LDAP server is based on OpenLDAP, I'm guessing (!) the slapcat utility should be around somewhere to accomplish this.



[ Reply to This | # ]
Convert 10.3x LDAP database to UNIX passwd file
Authored by: arg on Aug 02, '04 01:16:19PM

Yes. Thank you. I actually did use slapcat to generate an LDIF file. But I still needed (well, wanted, really) a way to convert that info to a UNIX style passwd file. And now I have it through the wonders of shell scripting, which I'm just discovering (in case you can't tell). Anyway, thanks again for the comment.



[ Reply to This | # ]
Using Net:LDAP
Authored by: redjar on Aug 02, '04 03:07:15PM
We use OpenLDAP in a Linux environment, but I suspect that the Perl-LDAP modules will work just fine under Mac OS X. Using the modules makes manipulating LDAP data very easy. For example, here is a simple script I wrote to create a flat passwd file:
#!/usr/bin/perl

use Net::LDAP;

$ldap = Net::LDAP->new("localhost");

$ldap->bind("cn=admin,dc=domain,dc=com", password=>"secret");

$mesg = $ldap->search(filter=>"(objectclass=posixAccount)", base=>"ou=people,dc=domain,dc=com");

@entries = $mesg->entries;

foreach $entry (@entries) {
        $username = $entry->get_value(uid);
        $uidnumber = $entry->get_value(uidNumber); 
        $gidnumber = $entry->get_value(gidNumber);
        $gecos = $entry->get_value(gecos);
        $homedir = $entry->get_value(homeDirectory);
        $shell = $entry->get_value(loginShell);

	print "$username:x:$uidnumber:$gidnumber:$gecos:$homedir:$shell\n";
}


[ Reply to This | # ]
escape char got snarfed
Authored by: redjar on Aug 02, '04 03:09:51PM

an escape character got snarfed, the print statement at the end should have a backslash before the n. Hopefully it won't get stripped again:

print "$username:x:$uidnumber:$gidnumber:$gecos:$homedir:$shell\n";



[ Reply to This | # ]
Convert 10.3x LDAP database to UNIX passwd file
Authored by: mbartosh on Aug 03, '04 12:20:09AM

A perhaps easier solution would be to use nss_ldap and pam_krb5 to allow your unix hosts to access the identification and authentication data housed in your open directory master. This is certainly easier to maintain in the long run. These concepts are covered briefly in Apple's Directory Services class.

---
4am Media, Inc. Mac OS X Training and Consulting



[ Reply to This | # ]
Convert 10.3x LDAP database to UNIX passwd file
Authored by: kholburn on Aug 03, '04 03:24:55AM
Here's a script I have used to dump a linux LDAP database to an /etc/password format. You have to have authorisation to access the data:

more ldapusers.sh
#!/bin/sh

#ldapsearch -x -v -D "uid=manager,o=mycompany.com" -w -b \
#"o=mycompany.com" '(objectclass=posixaccount)' \
#uid uidnumber gidnumber gecos homedirectory loginshell |\
#

ldapsearch -x -v \
  '(uidnumber=*)' \
  uid uidnumber gidnumber gecos homedirectory loginshell |\
  perl -e '
    $line = 0;
    while () {
      chomp;
      if (/^#/) { next; }
      if (/^$/) { $state=2; }
      elsif (/^uid/ && /,ou=People,/) { $state+=1; }
      else {
        if (/^uid: /i) { s/^uid: //i; $entry[0]=$_; }
        elsif (/^uidnumber: /i) { s/^uidnumber: //i; $entry[2]=$_; }
        elsif (/^gidnumber: /i) { s/^gidnumber: //i; $entry[3]=$_; }
        elsif (/^gecos: /i) { s/^gecos: //i; $entry[4]=$_; }
        elsif (/^homedirectory: /i) 
          { s/^homedirectory: //i; $entry[5]=$_; }
        elsif (/^loginshell: /i) { s/^loginshell: //i; $entry[6]=$_; }
      } 
      if ($state>1) {
        if (scalar @entry) {
          $entry[1]="x"; print join (":", @entry), "\n"; @entry=();
        }
        $state=0;
      }
    }
    if (scalar @entry) {
      $entry[1]="x"; print join (":", @entry), "\n"; @entry=();
    }
  '


[ Reply to This | # ]
Convert 10.3x LDAP database to UNIX passwd file
Authored by: kps on Aug 03, '04 02:54:18PM

#!/bin/sh

HN=localhost
DB=/NetInfo
FS='RecordName Password UniqueID PrimaryGroupID RealName NFSHomeDirectory UserShell'

{ dscl $HN -list "$DB/Users" | sed "s,.*,read $DB/Users/& $FS,"; echo quit; } |
	dscl -q $HN |
	sed -e '/^read/d' -e '/^quit/d' -e 's/^[^:]*: //' |
	rs -e -C: 0 7 |
	sed -e 's/:$//'
The dscl author(s) need to be beaten half to death with a copy of Software Tools for (a) not recognizing the end of input, and (b) echoing the commands.

[ Reply to This | # ]