CIFS ... in Solaris (November 2, 2007)
By Dkildahl -Oracle on Jun 16, 2011
CIFS ... in Solaris. That's an interesting concept; one that has evoked a variety of emotions within Sun.
I was first asked about adding an in-kernel CIFS service to Solaris about 4 years ago, "Yes, it's possible but it's probably a lot more intrusive than you think. Are you sure you want to do that?"
We had been working on an independent CIFS implementation for several years, and we would use this as the basis for the Solaris CIFS project, but it would take time for everything necessary to fall into place: there is a big difference between what management at Sun would like to happen and what the engineers at Sun will endorse. It took a while to get the necessary support and it would be another two years before the Solaris CIFS server project became a reality.
Although I didn't know it at the time, this all started about 16 years ago when I was working on multi-OS, distributed, transaction processing systems (I seemed to be forever porting ONC RPC to yet another OS) and I came across something called OSF DCE, which was a distributed computing environment that used DCE RPC for client-server communication, X.500 name services and Kerberos security. We built a prototype using DCE across various different UNIX operating systems but decided to use a different technology to create products. People were talking about using DCE for CORBA (object request broker) servers, and we'd used a DCE based transaction processing monitor, but I didn't think DCE would catch on and I thought I'd never hear about it again - I had no idea.
About 10 years ago, I was asked to help design and implement a new transaction oriented, journalling file system (not ZFS) for a small NAS company. We started working on it but a large OEM deal came along and the file system was put aside to productize what would eventually become the StorageTek 5320 NAS. There were many things to take care of but one of the main problems was the lack of a comprehensive CIFS service. No-one on the team had much experience with Windows or CIFS so I took it on, and it didn't take long to realize that I'd run straight back into DCE. CIFS had evolved: MSRPC is essentially DCE RPC and Active Directory is based on LDAP and Kerberos. Oh Joy!
And 10 years on ...
Many people assumed or desired that the Solaris CIFS server project would be like Samba but what would that achieve? Sure, it would avoid breaking any eggs, i.e. avoid making substantial changes to Solaris, but Samba is available on Solaris today. There is no point in creating another Samba. If you truly want an integrated CIFS implementation, that can really inter-operate with Windows at a fundamental level, the operating system has to support certain core features. Eggs will have to be broken.
Not surprisingly, the most contentious topic seemed to be the possibility that someone might introduce case-insensitivity into a Solaris file system. This was anathema to many, which led to many repetitive discussions, and was an interesting distraction because it wasn't the thing that really concerned me. Case-insensitivity is important for transparent inter- operability with Windows, as is ensuring that file names can be shared by applications and protocols using disparate character encoding schemes, but I could visualize solutions for those things - solutions that would not compromise POSIX conformance. My real concern was how to support integrated file access control within the file system given the mismatch between UNIX and Windows credentials. The idea of non-unique UIDs and GIDs is so pervasive in UNIX that I wasn't sure it would be possible to effect the level of change necessary to achieve true CIFS integration. CIFS access control relies on access tokens (Windows credentials) and security descriptors, in which users and groups are represented by globally unique, variable length security identifiers (SID). NFSv4 and ZFS offer partial compatibility through NFSv4 access control lists (ACL) but those ACLs and Solaris credentials are still founded on UIDs and GIDs, which are fixed size and non-unique across NIS domains.
Afshin, a senior member of the CIFS project team, and I spent a lot of time working on white boards and came to the conclusion that we couldn't get round the credential issue. So, in December 2006 - the same month that I submitted the CIFS Service project proposal (PSARC case 2006/715), Afshin wrote and distributed a white paper titled "CIFS/NFSv4 Unified Authorization", which proposed a unified access control model for CIFS, NFSv4, local users and ZFS, and introduced the concept of the FUID that is now used in ZFS. This generated some good discussion but the mountain remained; how to make such a huge change a reality.
We continued working on other things, there was no shortage of other things, but it was difficult to see a light at the end of the tunnel until February 2007, when a happenstance discussion over coffee with Jeff Bonwick and Mike Shapiro, both Sun Distinguished Engineers who need no introduction here, changed the future of the CIFS project. They asked how things were going and I explained the magnitude of the change I wanted to make. A short discussion and white board session later we had consensus and Mike said, "Let me do some reading this weekend and I'll write something up." That write-up became PSARC case 2007/064 (Unified POSIX and Windows Credentials for Solaris) and we had the way forward for the Solaris CIFS service.
We already had the basic CIFS service building on Solaris but it took another 8 months, 22 more ARC cases, a lot of helping hands and many late nights to deliver the project. On October 25th, 2007, the CIFS service project putback over 800 files, approximately 370,000 lines of code (including 180,000 lines of new code) to the Solaris operating system.
It's a large, complex project (several years in the making, including a very intense final year), which incorporates some fundamental changes to Solaris.
So what is CIFS, why add support to Solaris and what did we change?
The Common Internet File System (CIFS), also known as SMB, is the standard for Windows file sharing services, and one of the primary goals for Solaris is to continue to improve and enhance it as a storage operating system and platform. Adding CIFS, to provide seamless, ubiquitous file sharing for both CIFS (Windows, MacOS etc) clients and NFS clients is a major step towards achieving this goal. Together, with the CIFS client, which is also an OpenSolaris project, the CIFS server helps provide comprehensive, integrated native Windows interoperability on Solaris.
What does this mean for Samba on Solaris? Not a lot really. Samba is a good, multi-platform application service that provides file and print service for Windows and CIFS clients. It is a portable, user space application, and is actively supported on Solaris. The Solaris CIFS service is a native kernel implementation; a first-class citizen of the Solaris operating system that has been integrated with NFS, ZFS and many OS feature enhancements to provide seamless, ubiquitous, cross-protocol file sharing.
There is a common misconception that Windows interoperability is just a case of implementing file transfer using the CIFS protocol. Unfortunately, that doesn't get you very far. Windows interoperability also requires that a server support various Windows services, typically MSRPC services, and it is very sensitive to the way that those services behave: Windows inter- operability requires that a CIFS server convince a Windows client or server that it "is Windows". This is really only possible if the operating system supports those services at a fundamental level.
In addition to the CIFS/SMB and MSRPC protocols and services:
- We added support for SIDs to Solaris credentials. This solved the centralized access control problem: CIFS can specify users in terms of SIDs and ZFS can perform native file system access control using that information.
- There are various VFS updates and enhancements to support new attributes, share reservations and mandatory locking. As with the credential change, this was also a significant effort, which affected the interface to every file system in Solaris.
- ZFS enhancements include:
- Support for DOS attributes (archive, hidden, read-only and system)
- Case-insensitive file name operations.
There are three modes: case-sensitive, case-insensitive and mixed.
- Support for ubiquitous cross-protocol file sharing through an option to ensure UTF8-only name encoding.
- Atomic ACL-on-create semantics.
- Enhanced ACL support for compatibility with Windows.
- sharesmb, which is similar to sharenfs.
- One of our project goals was to minimize the number of new commands being introduced. To this end, sharemgr(1M) and sharectl(1M), which are used to manage NFS shares and NFS configuration, have been enhanced to support CIFS. Sharemgr now supports named shares and directories can be shared multiple times. Sharectl has been enhanced to support CIFS configuration.
- Various file system utilities have been, or are being, updated to support the new attributes and features: chmod, (un)compress, cp, cpio, ls, (un)pack, pax and tar. Most of these file system commands have already been modified to accommodate the changes. The pax and cpio commands have not yet been modified and will simply ignore the new attributes.
- A new privilege, sys_smb, has been introduced to restrict access to the NetBIOS and SMB ports, which is similar to sys_nfs. The sys_smb privilege is required to bind to ports 137, 138, 139 and/or 445. For those running Samba as root, this should make no difference. Otherwise, it may require that the process privilege set be modified, using ppriv, to run the process with sys_smb. The privileges(5) man page is being updated to include PRIV_SYS_SMB.
A preliminary draft of System Administration Guide: Windows Interoperability for the Solaris OS will be available soon on the Solaris CIFS server project page at opensolaris.org. The following man pages are also being prepared.