Tuesday, 10 June 2008

Samba and LDAP: a Wind-up

I had to revisit this because I thought I must have missed something: must have got something wrong. But I really don't think I have. The developerWorks document I quoted in an earlier post was written before the release of Samba 3. It says that "There are two things a Samba/LDAP installation cannot do 'out of the box' ". The first is "Retrieve user account information from an Windows 2000 Active Directory server"; the second is "Alleviate the need for /etc/passwd." Both these issues, the document confidently expects "will be resolved with the release of Samba 3.0." But it didn't happen. Instead, the Samba documentation states that "The second item [removing the need for /etc/passwd] can be accomplished by using LDAP NSS and PAM modules." Except that these modules are already installed on Fedora. Checking the /etc/nsswitch.conf file for the necessary entries:

passwd: files ldap
group: files ldap

shows that these entries are in place.

Everything I've read implies that I should be able to achieve what I want to do with Samba and LDAP: create groups and user accounts in LDAP and have them access file and print resources on the Samba server. And yet I've not been able to achieve that in the time I've had available. I'm disappointed. My feeling is that unless you really need to use the features of LDAP you are probably better off using Samba's tdbsam backend instead.

CLDAP

I couldn't of course just leave things as they were, so I did some digging. Everything I've read indicates that openldap, and by extension FDS, does not support UDP. As a result, an openldap server cannot respond to CLDAP queries such as those made by a Windows client. That doesn't always seem to have been the case. Earlier versions of openldap seem to have had a complile time option --enable-cldap. This option appears to have been dropped. I found a reference here to the to option no longer being available in version 2.1.22. Certainly in the configure script of the current 2.4.10 source code there is no mention of --enable-cldap.

I couldn't find any formal announcement, but perhaps the reason CLDAP support was dropped from openldap was because the protocol has been buried as an Internet standard. It's epitaph is recorded in RFC 3352.

From a practical point of view, all this means is that you have to treat a Samba server - even one with an LDAP backend - as a NT 4.0 server and connect to it via NetBIOS. If you specify a DNS name, Windows thinks you are connecting to Active Directory. This is made clear by the subtly different error message you get on Vista:


Don't think this is the end of CLDAP, however. It is obviously still being used by Active Directory, and if it is still being used by Active Directory, it will have to be supported by Samba 4.0.

Monday, 9 June 2008

Joining a Samba Domain

Joining a Windows workstation to a Samba domain is quite instructive: it tells you an awful lot about how a Windows workstation joins a Windows domain...

Here's what I got the first time I tried to join a Windows XP machine to my RIVERSIDE Samba domain:


The error message goes on: "The query was for the SRV record for _ldap._tcp.dc._msdcs.RIVERSIDE"

What's happened here is that Windows has first tried to look up the NetBIOS name "RIVERSIDE" assuming - correctly - that it is not a DNS name. When the NetBIOS name look up failed, Windows then queried DNS. Most of this error message relates to the DNS look up, and as such is quite misleading.

The standard solution you will find on all the Samba discussion forums is to add the Samba server to workstation's list of available WINS servers. One simple way of doing this is to get your DHCP server to pass on the address of the Samba server. If your DHCP server is Linux you just need to add a line like the following to your /etc/dhcp3/dhcpd.conf:

option netbios-name-servers 192.168.2.8;

When the workstation next gets an IP address from the DHCP server it will know about your Samba server (running WINS) and will be able to resolve the domain NetBIOS name. This works. And maybe, if you're sensible, you should stop there. However, aren't you a bit curious about the " SRV record " stuff?

If, instead of supplying a NetBIOS domain name, we supply a DNS domain name, like riverside.forensit.com, Windows will attempt to look up - not the DNS domain name itself - but a service location (SRV) resource record for a Domain Controller for the domain. In other words, it queries DNS for something like:

SRV _ldap._tcp.dc._msdcs.RIVERSIDE.FORENSIT.COM

In order for your DNS server to answer this query you need to add some lines to your DNS config files:

_ldap._tcp IN 1H SRV 0 100 389 medway
_ldap._tcp.riverside.forensit.com-site._sites IN 1H SRV 0 100 389 medway_ldap._tcp.riverside.forensit.com_site._sites.dc_msdcs IN 1H SRV 0 100 389 medway
_ldap._tcp.gc._msdcs IN 1H SRV 0 100 389 medway_ldap._tcp.dc._msdcs IN 1H SRV 0 100 389 medway
_ldap._tcp.dc._msdcs.riverside.forensit.com IN 1H SRV 0 100 389 medway_ldap._tcp.gc._msdcs.riverside.forensit.com IN 1H SRV 0 100 389 medway
_gc._tcp IN 1H SRV 0 100 3268 medway_gc._tcp.riverside.forensit.com-site._sites IN 1H SRV 0 100 3268 medway

On Fedora, these get added to the /var/named/*.db file. You can add these entries using system-config-bind, although (rightly) it does complain.

After restarting named on the DNS server, the Windows workstation should be about to get a response to its SRV query. On my riverside.forensit.com domain it can... But - and throughout this whole long exercise there has always been a but - that doesn't get me much further. Windows returns the error "A domain controller for the domain RIVERSIDE.FORENSIT.COM could not be contacted." The details are:

DNS was successfully queried for the service location (SRV) resource record used to locate a domain controller for domain RIVERSIDE.FORENSIT.COM:

The query was for the SRV record for _ldap._tcp.dc._msdcs.RIVERSIDE.FORENSIT.COM

The following domain controllers were identified by the query:

medway.riverside.forensit.com

Which is all absolutely correct. I can ping medway.riverside.forensit.com (the DC.) I can look it up using nslookup. So what's going on now?

I resorted to Wireshark. Having successfully queried for the DC name, the XP workstation sent a search request for the "ROOT" base object of the LDAP directory over CLDAP (Connectionless LDAP.) It was this request that failed: the server returning "Destination unreachable (Port unreachable)" over ICMP. However, the LDAP error log on my server just reports " - slapd started. Listening on All Interfaces port 389 for LDAP requests." It's almost like a firewall problem, except Firestarter reports no blocked connections.

So that's as far as I've got. I hate leaving unanswered questions, but I've already spent far too long on Samba: the questions will have to wait. It maybe that what I'm attempting here can't be done. I've come across some posts by glauco.b on the Ubuntu Forums saying that openldap does not support UDP - which is what the CLDAP query goes over.

Friday, 6 June 2008

Roaming Profile Error Logging On To Samba

When I attempted to log on to my Samba domain from an XP workstation I got this:


Followed by this:


Except I'm not using roaming profiles.

The solution was to explicitly set the "logon path" and "logon home" parameters to nothing in the /etc/samba/smb.conf file:

logon path =
logon home =

I seem to remember a customer complaining about this in the past. Now I know.

Samba A101

RULE ONE: Before you can add a user to the smbpasswd password file, that user must have an UNIX/Linux account (typically stored in /etc/passwd) on the system hosting the Samba service.

And that's what I was missing. You can't add a Samba user unless the posix user account exists first. This applies to Samba implementations with a LDAP "back end" just as much as it applies to traditional Samba implementations. It never occurred to me that this would be the case. On a Windows Active Directory server, you don't have to create a local user account as well as creating a user account in AD, the LDAP database. On NT 4.0 Servers - which Samba was originally developed to imitate - things are different, of course. But in February 2000 Windows moved on: Samba has still to catch up eight years later.

Suddenly the scales have been lifted from my eyes. Fedora Directory Services, and indeed other Linux LDAP implementations, are at best "bolt ons" for Samba. LDAP does not fundamentally change the way Samba operates, and emphatically Samba + LDAP does not equal AD.

Crucially, Samba cannot integrate LDAP with the Linux file system. On a Windows server, you can create a group in AD and then give that group access to a folder. Samba 4 will have its own LDAP directory that will allow it to be an LDAP server for AD clients. However, there will still be no integration with the file system. As a recent article in Linux Magazine puts it:

On a more somber note, Samba4 lacks great integration with the POSIX system on which it sits. It cannot map NT ACLs into POSIX ACLs, it requires users and groups to be added to Linux as well as to its internal ldb database.

So why bother implementing Samba (3) with LDAP at all? For the moment I can't think of a single good reason. Apparently a LDAP back end provides better scalability and performance. But any organization needing scalability and performance isn't going to be looking at hacking around with Samba and LDAP anyway. They are going to look to Active Directory, and the product that Active Directory set out to destroy - Novell Netware. I'm suddenly very interested in how OES integrates with the Linux file system - if indeed it does.

My illusions shattered, I got Samba and LDAP working quite quickly. It was just a case of creating the accounts I needed using useradd or system-config-users. This included creating the "Administrator" account (which then allowed me to use pdbedit to set the SID) and my Windows workstation accounts:

/usr/sbin/useradd -n -c "Workstation FDSPC" -M -d /nohome -s /bin/false FDSPC$

I then called "smbpasswd -D 10 -a Administrator" as I did before. This time, however, I got this:

smbldap_search_ext: base => [dc=riverside,dc=forensit,dc=com], filter => [(&(uid=Administrator)(objectclass=sambaSamAccount))], scope => [2]
ldapsam_getsampwnam: Unable to locate user [Administrator] count=0
pdb_set_username: setting username Administrator, was
pdb_set_full_name: setting full name Administrator, was
pdb_set_domain: setting domain RIVERSIDE, was
...etc...

which makes sense: Samba checks LDAP to see if the accounts exists and creates it if it doesn't. I used smbpasswd again to create the workstation accounts:

/usr/bin/smbpasswd -a -m FDSPC$

This done, I was finally able to add my Windows workstation to my Samba LDAP domain.

Thursday, 5 June 2008

Getting More Information From smbpasswd

smbpasswd has 10 debug levels specified by the -D switch. Level 10 is not recommended: the man page says "Levels above 3 are designed for use only by developers and generate HUGE amounts of log data, most of which is extremely cryptic." Really?

smbpasswd -D 10 -a testuser

gives us this:

smbldap_search_domain_info: Searching for:[(&(objectClass=sambaDomain)(sambaDomainName=RIVERSIDE))]
smbldap_search_ext: base => [dc=riverside,dc=forensit,dc=com], filter => [(&(objectClass=sambaDomain)(sambaDomainName=RIVERSIDE))], scope => [2]
The connection to the LDAP server was closed
smb_ldap_setup_connection: ldap://riverside.forensit.com
smbldap_open_connection: connection opened
ldap_connect_system: Binding to ldap server ldap://riverside.forensit.com as "cn=Directory Manager"
ldap_connect_system: successful connection to the LDAP server
ldap_connect_system: LDAP server does not support paged results
The LDAP server is successfully connected
pdb backend ldapsam:ldap://riverside.forensit.com has a valid init
smbldap_search_ext: base => [dc=riverside,dc=forensit,dc=com], filter => [(&(uid=testuser)(objectclass=sambaSamAccount))], scope => [2]
ldapsam_getsampwnam: Unable to locate user [testuser] count=0

testuser can't be found. Of course it can't be found - we're trying to create it!

More Samba Problems

I am getting to grips with how a Windows client discovers the Samba Domain Controller on the network. I will cover this in a later post. Unfortunately, there is still something profoundly wrong with my installation of Samba which I need to resolve before going any further.


It started when I was following the FDS instructions for setting up Samba. Having religiously followed every step, I got to the bit about setting up the Administrator account:

# smbpasswd -a Administrator -w ldap-admin-password

This returned:

Setting stored password for "cn=Directory Manager" in secrets.tdb

Was that right? I suspect not. What I've discovered is that if I replace "Administrator" here with any account name - including no name at all - I get the same result!

The next step was where it really went wrong. This is supposed to modify the Samba Administrator account to use the correct SID (one ending in a RID of 500):

# pdbedit -U $( net getlocalsid sed 's/SID for domain RIVERSIDE is: //' )-500 -u Administrator -r

All I get is:

Username not found!

The final step in the instructions is to test creating a new user:

# smbpasswd -a testuser

Which just returns:

Failed to modify password entry for user testuser

I've done a lot of googling on this. There are plenty of reports of this sort of error, but precious few answers.

Tuesday, 3 June 2008

Connecting to Samba... or not...

I have managed to get over most of my connection issues. These were down to a combination of DNS configuration problems, and firewall issues.

The DNS problems stemmed from the fact that there were "allow-query" and "listen-on" entries in the /etc/named.conf file that effectively restricted queries to the localhost. So, for example, dig @localhost riverside.forensit.com would work, but using the IP address dig @192.168.2.8 riverside.forensit.com would fail. My guess is that these entries were written to the file when I was messing around with system-config-bind, although I don't recall changing anything.

After fixing the DNS problems, I installed Firestarter. I might have been able to get away with Fedora's own system-config-firewall, but I'm familiar with Firestarter - and it logs blocked connections so you can easily see what is going on. Once I'd opened up the Samba, DNS, LDAP and HTTP ports - not forgetting the Fedora Management Console port, I was starting to get somewhere. I was still unable to see my "Riverside" domain on the network, however. I couldn't see it from a Windows machine, and I couldn't even see it from "Network" on the server itself.

Being able to browse for the domain on the network is dependent on the Samba nmbd daemon (that's service for the Windows-minded.) nmbd is controlled by the line

wins support = yes

in the /etc/samba/smb.conf file. You would think then, that when you started Samba, nmbd would automatically be started too. Well I did. It wasn't. I manually started "nmb" via system-config-services and "Riverside" appeared under "Microsoft Windows Network" on my XP machine.

Almost there? Unfortunately there is still something missing. Although I can "see" the domain, I cannot get a Windows machine to join the domain. There's still more work to do.