#ident "@(#)issues 1.17 07/03/14 SAC" Issues for inception Unified POSIX and Windows Credentials for Solaris 14 Feb, 2007 Submitter: Mike Shapiro Owner: Gary Winiger nw-0 High-level view: move Solaris from using POSIX IDs to using SIDs (and/or GUIDs) instead. And all that that implies: - new SID-oriented versions of syscalls that deal in UIDs/GIDs - new SID-oriented versions of getXbyYs that deal in UIDs/GIDs - storing SIDs (and/or GUIDs) instead of/in addition to POSIX IDs in filesystems and archive/backup file formats/protocols - having backwards compatible mapping of SIDs to POSIX IDs - relaxing user/group name length limits The proposal does indeed propose most of the above, with the one exception that we don't propose wholesale introduction of SID-oriented system calls. Instead, ephemeral mappings are used so POSIX APIs with uid_t/gid_t can remain in use for some time until we feel that the 32-bit space is too small. Subsequent cases such as Winchester and others will cover the details of name-service level API changes. nw-1 If getXbyYs are supposed to fail for "negative UIDs/GIDs" then how are Windows user/group names/SIDs to be resolved? Will there be new getXbyYs using SIDs instead of POSIX IDs? (Note: I believe we currently agree offline that getXbyYs shouldn't fail/map to 'nobody' any "negative UIDs/GIDs," they should function as usual.) getXbyY's should only fail for ephemeral mappings when those identifiers are present in a FUID-aware filesystem (and thus the ephemeral ID is visible) but no Winchester/Reno name service can resolve that SID to a name. This is identical to the existing behavior that a filesystem can store uid 123, and if I stat the file after the user is removed from NIS or LDAP or passwd(4), I still see the uid but getpwuid() fails. nw-2 Assuming there's a way to resolve Windows user/group names/SIDs, there will be a need to support user/group names qualified with domain names. The Solaris ABI user/group name length limit of 8 characters (or is it bytes?) surely will cause problems. What is the possible impact from breaking this part of the ABI? (Note: This breakage could be limited to Solaris systems joined to AD domains.) How will Windows user/group names be represented in Solaris (name@domain, name@REALM, upn@domain, ...)? This case is intended to function as an umbrella covering the central design question of representation of foreign identities as discussed at inception. Given the decision to change uid_t a logical and useful extension of that decision is breaking the user name/group name length limits as well, and deciding the question above. This should be covered by a follow-on case that examines all of the APIs / ABIs for name length limits, just as this case covers the uid_t/gid_t issues. nw-3 It seems we have a requirement for being able to use AD and Unix name services simultaneously. Probably unqualified user/group names being resolved in Unix name services and qualified ones being resolved in AD. We should make this requirement explicit. Agree, but I think this issue is better resolved in a case specific to name services (Reno, Winchester, or a follow-on). nw-4 Will Windows domain users be able login to Solaris systems? The case materials indicate that setuid(2) and friends will accept "negative" IDs, which implies "yes." (Note: We agree offline that the answer is ultimately "yes.") If not, why not? If yes, how will /var/adm/lastlog work? Will it be replaced? Similarly for utmpx; utmpx has a 32-byte length limit on usernames. Will tmpfs/devfs support SIDs instead of/in addition to POSIX IDs? For tmpfs, there is no pressing need for conversion, as described in paragraph 4 of Section 15. This can be done at any time, and is orthogonal to the immediate CIFS / ZFS goals. For devfs, there is no need for direct conversion as devfs is purely an in-kernel filesystem that relies on a backing filesystem (ufs or zfs) for its attribute caching. As such it will inherit the SID conversion of ZFS or non-conversion of UFS and interact using uid_t's passed through the VOP layer. nw-5 Making use of the heretofore negative range of UIDs and GIDs will clearly break ABI. What will be the impact? What applications are known to break? (Note: This breakage could be limited to Solaris systems joined to AD domains.) Section 10 discusses this issue in detail. nw-6 Are there no applications that persistently store POSIX IDs besides archive/backup tools? If so, ephemeral negative IDs will only be safe if the same apps all also reject or map to 'nobody' any negative IDs. Otherwise identity aliasing problems (i.e., security problems) crop up. Known Solaris data format issues are described in Section 16. Other applications (e.g. ISVs) must be addressed through developer documentation and Sun's MDE program. nw-7 With regard to ephemeral ID mappings, if a [long-term?] goal is to move Solaris away from POSIX IDs and towards using SIDs (and/or GUIDs) then is the reliability of the persistent ID mapping facility a long-term issue? The long-term goal articulated by this case is to provide unique identifiers as the underlying model. A consequence of that goal is that an id mapping service becomes a central facility in Sun's operating system. nw-8 This one is for the ARC. This case makes every Solaris system have its own UID/GID namespaces distinct from all others. The lower half of these are to be reserved for identity mapping with "legacy" Unix environments, the upper half are reserved for dynamic mapping for Windows SIDs. UIDs/GIDs in the "positive" range need no mapping when talking NFSv3 or NFSv4 w/ AUTH_SYS with "legacy" Unix peers. UIDs/GIDs in the "negative" range are mapped to "nobody" on the wire in the NFSv3 or NFSv4 w/ AUTH_SYS, even when talking to non-legacy peers. We agree that there is an alternative that to using negative IDs that otherwise has equal configuration complexity characteristics to the actual proposal, but more design complexity. A choice of one or the other alternative is a trade-off between: - one more bit of UID/GID namespace + simpler design, but breaks compatibility or otherwise requires complex compatibility/security analysis (OTOH, this makes ephemeral mappings remotely feasible, which can be a way to address any concerns about persistent ID mapping reliability) vs. - somewhat more complex design and just the same old 31 bits of UID/GID namespace, but no risk to backwards compatibility issues with negative IDs (ephemeral mappings are also not possible, so any persistent ID mapping reliability concerns must be addressed) The ARC may help set the parameters for making this choice. This issue was discussed at inception review and the concensus was to proceed with the design direction of the case as described in the inception materials and move to commitment. nw-9 Apple, apparently, is moving towards storing GUIDs in their filesystems instead of POSIX IDs. Given Apple's apparent intent to port/use ZFS, shouldn't this mean that we should agree on an on-disk format that supports GUIDs, not just "LUIDs" or "FUIDs" (compressed SIDs)? (Note: Disk space is cheap; kernel memory isn't, but often many files have the same ACLs, so it seems possible to use hash tables to store a single copy of any ACL in kernel memory, and ZFS could help by storing an ACL hash/ rolling CRC in the dnode bonus instead of the first six ACL entries [ACEs].) GUID representation is described in paragraph 4 of section 7, and thus GUIDs are in fact supported by the proposed encoding. Apple's current implementation uses UNIX id's for owner and group, but GUID identifiers generated by OpenDirectory in ACLs. At the same time, Microsoft has also extended their ACLs to include SIDs as before but also GUIDs of AD objects. Therefore Apple's needs would be addressed by the ZFS work to extend ACLs to support these additional forms, which will be submitted in a separate case. In any case I strongly concur that ACL hash is a good idea as we see large-size similar ACLs on many znodes. nw-10 Name-based ID mapping could be configured after files are created that reference the same user/group in AD and Unix. This could be bad, but then, this could be addressed by adding a secondary user IDs (SIDs, GUIDs or UIDs) to cred_t. Please consider doing so. Besides, it will play well with AD's notion of "historical SIDs" :) I don't believe introducing a core notion of secondary IDs is the correct approach given the amount of complexity it adds to a very large number of code paths, APIs, and data structures. Edge cases that require secondary IDs can be better addressed architecturally by having a group identifier that contains solely the primary and secondary ID and then using the composed identifier in an ACL. nw-11 Switching from POSIX IDs to new forms of internal identifiers implies new syscalls to replace setuid(2) and friends. Should we keep the same real/effective/saved user and primary group ID scheme? Or is it time to consider something else? The explicit design of this project is not to introduce new system calls, using the ephemeral mapping to the POSIX space to delay our need to do so. In terms of the POSIX ID scheme I don't wish to debate its merits here, only to show that we can achieve our long-term goals without breaking compatibility. gw-0 What is or is there a relationship between FUIDs and ephemeral UIDs? Beyond 0 touch, where do you see ephemeral UIDs being used? E.g., extending an AD authenticated login to a Solaris login (via ssh/kerberos or friends)? FUIDs are a filesystem-local encoding of an SID. Within a given system or zone for a given execution of that system an SID is then mapped to an ephemeral ID. Ephemeral IDs would also be used whenever SID-based login service is provided. gw-0a What does the project team believe should be in an opinion for this case? Approval of a strategy? Approval of specific uid_t, gid_t as unsigned? ... a little more specifics on 18 a-e. [ Note: Section 18 from inception is now Section 19 ] This case is intended a key strategy decision/umbrella which will guide successful design, integration, and implementation of CIFS, extensions to ZFS, Winchester, and several other cases. The ARC opinion should reflect that Section 19 (a-e) represent a set of design decisions for the operating system, and agree to evaluate the design and integration of CIFS, ZFS, and Winchester along these lines. The ARC should further agree that the set of further cases 19 a-d (second set) can be brought separately to the ARC for review to implement the pieces of work described by this case. Finally, the ARC should agree that the first set of implementation work would comprise changing uid_t and gid_t to unsigned and implementing 19 item (a): Interface changes and additions for cred_t and ucred_t, including functions to establish, retrieve, and validate SID values associated with credentials and appropriate observability (proc(4) ucred file, pcred(1), DTrace). An ARC fast-track covering these items at the .h file and API level would be brought subsequent to this case to show such details, and meantime the Winchester, ZFS, and CIFS work can proceed. gw-1 6.b -- what are the thoughts about the SID format in cred_t/ ucred_t? FUIDs/SIDs respectively? For SIDs in cred_t and ucred_t we should store SIDs in string representation so as to avoid reliance on the binary encoding of Microsoft's current format, and permit us to extend the SID schema to arbitrary forms. FUIDs only appear within filesystem below the VOP layer, and thus are never exposed in [u]cred_t. gw-2 8. Is the SID/FUID mapping expected to be kept persistent by Winchester? Or is there some other scheme? No: FUIDs only exist in the filesystem below the VOP layer. Winchester maintains the SID<->ephemeral ID mapping in memory and tmpfs, and not across reboots. gw-3 How might the Sparc ABI issues of uid_t/gid_t apparently being signed be mitigated? This case does constitute an ABI change, but not an incompatible one, as the ARC agreed during inception. Documentation will aid developers with the changes. gw-4 What is foreseen relative to get_x_by_y with SIDs or AD style names. Perhaps better for Reno/Winchester phase 2. These APIs are not immediately needed, and their exact form should be discussed by Reno/Winchester phase 2. gw-5 7 "and defining our own P-* space." IMO, we, Sun, really shouldn't go this alone, we should work with POSIX/IEEE to have a defined standard that even S-* names will find acceptable. Agree. This case should include a TCA for Sun to begin work on industry-wide definition of SIDs and extensions. gw-6 8. "extended attribute mechanism." Are there any packaging and install issues to be considered here? Would packages want to associate P-* or S-* values as owners/groups? Currently packaging tools use names rather than explicit POSIX identifiers to assign ownership and groups. Therefore extension to support S-* values directly seems unnecessary. gw-7 For the /proc//ucred case, ensure appropriate privilege for access of the audit fields. Agree. This will be viewed as a TCR on the ucred ARC case. gw-8 While not explicit at the system call interface, the Audit Project uses -1, -2, -3 for internal values in various id fields in the cred and audits internal userland structures. I believe -2 is also used other places in Solaris. Suggest reserving [-1, -100] or something like that. As described in Section 16, Solaris auditing will need to be modified to support SIDs such that ephemeral identifiers are not used in audit records. Therefore, auditing use of uid_t's will either be entirely replaced, in which case the above will not be an issue, or it will continue to support reading and/or writing of extant records with uid/gid values in addition to new SID records. If the latter, then those legacy records can continue to use -1 -2 -3 as their own reserved values. These details should be clarified as part of the auditing case. gw-9 9. "This design implies that .... uid_t/gid_t values can be returned." This implies to me that no ephemeral IDs are stored in inodes or FUIDs. Is that correct? I'm not sure how that relates to chown can be used with ephemeral values and will have correct semantics. Correct: no ephemeral IDs are ever stored in a filesystem. A filesystem either stores legacy IDs (e.g. ufs) in which case it converts any ephemeral ID into *ID_NOBODY, or it stores FUIDs, in which case it takes an ephemeral ID, gets the true SID from the cred, and then converts that SID to a FUID. Upon a chown (VOP_SETATTR), a FUID-aware filesystem will take the new identifier, upcall the mapping service to obtain the SID (or hit in the kernel cache), compute the FUID for that SID, and modify the on-disk znode to reflect the FUID. gw-10 10. "Therefore, we define ephemeral .... client with appropriate privilege". Would that just be the map requests comes from the kernel door? Is something else implied here? If so, what? The CIFS service must have some means to introduce a new SID into the system, i.e. establish an ephemeral mapping. This is therefore some door call to the id mapping service, and that type of call must require appropriate privileges. If it did not, unprivileged processes could deny service to the system by requesting millions of spurious SID mappings. gw-99 Less architectural than business, the Audit project team is not staffed to include SIDs in audit records. Should there be "logins" or auditable processes that are attributable to SIDs or ephemeral IDs, some one is going to have to ensure proper staffing. Additionally, if SIDs or ephemeral IDs are going to be part of the Solaris evaluations, the Solaris Evaluations project will also need appropriate staffing. Agree. In particular this point should be revisited when nss_ad is introduced to permit AD-based logins, and in the ARC fast-track covering the auditing changes for this project. dwc-0 spec.txt section 10 (POSIX ID Partition and Mapping) The fact that the POSIX standards and Single UNIX Specifications (API standards) allow uid_t and gid_t to be either signed or unsigned does not relieve this project from also meeting to the System V ABI and Sparc Compliance Definition (ABI standards) requirements that both of these be signed types. Changing uid_t and gid_t to unsigned types will break ABI conforming applications that compare an object of type uid_t or gid_t with -1 (which you correctly describe as a sentinel value). Changing these types from signed to unsigned will require a major release binding! This point was discussed at the ARC inception review and withdrawn at the request of the submitter. The ARC agreed that while we are changing in effect the ABI document this change can be done compatibly to existing binaries according to ISO C. (In particular, refer to the language of ISO C 6.3.1.2.) wes-0 in my experience the term "legacy" bears little technical content but carries a significant negative connotation. Can we avoid using it in the spec and discussion? Suggested non-negative alternatives: - omit entirely - "traditional" - "standard" - "historic" I've corrected this everywhere except for /var/adm/pacct, which deserves to be spoken of with negative connotation. wes-0a How fundamental is the signedness change? could you use negative values less than -1 to represent ephemeral ids? This issue was discussed at inception and the ARC agreed to proceed with the change to unsigned. The fundamental issue is that a negative value violates the POSIX language, and also other UNIX OSes Linux and BSD are now using unsigned. wes-1 It seems that there's an opportunity here to use the compound SID/ ZID/FUID to solve other problems -- for instance, there is no requirement that two zones on the same system share the same uid_t space, which complicates sharing filesystems between zones. Agree. Also see new Section 18 for discussion of Zones. wes-2 Please add PF_KEY to the list of kernel interfaces which pass uid_t's around. I've looked at sadb_msg etc. and I'm not seeing uid_t: can you provide a more specific pointer here? [e-mail me] wes-3 The expansion in ucred_t size forced by passing SIDs is likely to strain/break the current mechanism for passing ucred_t's through sendmsg()/recvmsg() ancillary data; this already needs a revisit.. The details here will be covered in the ucred_t case, one of the cases proposed by Section 19. wes-4 section 10: "we propose that getpwuid(3C), getpwuid_r(3C), getgrgid(3C), and getgrgid_r(3C), all return failure with "not found" semantics when passed an ephemeral uid or gid." Am I reading correctly that this is an interim measure until nss_ad/reno shows up? can you clarify this in the spec? Correct. I've clarified the language in Section 10. wes-5 11 (c): why wouldn't you say "must not be cached persistently" ? Agree: I've simplified the language there. wes-6 Should there be a separate id mapping service per zone, or should it be global? would it need to persist across zone reboots? See new Section 18 for discussion of Zones. Short answer: separate mapping service per zone. wes-90 [nit] section 1.x: "no restrictions on values" isn't quite correct as (uid_t)-1 and (gid_t)-1 mean "don't change" for the chown/fchown syscalls. This is discussed elsewhere: I wasn't intended to go into all of the details at this point in the document. wes-91 [historic trivia] in 1987, several of us at MIT/Athena deployed a uid mapping scheme for NFS, mentioned in an appendix to the 1988 USENIX paper "Kerberos: An Authentication Service for Open Network Systems" (Steiner, Neuman, and Schiller) Noted. wes-92 [nit/historic trivia] UUID has a very specific meaning: a 128-bit "universally unique identifier" which traces its roots to the Multics timestamp-based "unique id" as extended by apollo through the addition of a hardware node id. The currently used uuid format originated in the apollo NCS RPC framework as a portable version of the apollo "unique id" and was subsequently extended by OSF DCE and adopted by microsoft, linux and solaris. Noted. Issues for commitment Unified POSIX and Windows Credentials for Solaris 14 Mar, 2007 Submitter: Mike Shapiro Owner: Gary Winiger jdc-1 ucred_geteuid and related functions are documented to return -1 on error; does this conflict with the signedness change? No: because of the existing use of -1 as a reserved value for the chown(2) system call, my proposal is that we reserve the one single value -1 as an invalid uid_t and gid_t. This is necessary to make chown work, but also addresses the issue of any other calls like ucred_geteuid() that wish to return failure, as well as code any developer might write where one wants to return a uid_t or gid_t or an error indication. jdc-2 Do you know of C++ libraries that might be flag-day'd by this change? (I think two good places to go looking for victims would be in Cluster-land and GNOME.) The C++ issue in general is described in Section 10 (f). As discussed there, the issue arises when a native C++ interface (i.e. not extern "C") exported by a C++ library is recompiled on one side of the library boundary but not the other. As a general rule, WOS consolidations re-deliver fully compiled new bits to the WOS each build, so this would typically address any consolidation-internal code. Sun could experience an issue if a C++ library is used across a consolidation boundary. This would handled as with any other cross-consolidation flag day, by notifying the C-teams beforehand. The project team will also perform such a search to locate such issues prior to integration of these changes. gw-11 gw-8 [0x80000000, 0xfffffffd] See above for my reply to gw-8. gw-100 jdc-2 isn't JVM C++ as well? See above for my reply to jdc-2. wes-7 [wes-2 answer] it's buried in sadb_ident_t; its sadb_ident_id field can potentially carry a uid. wes-93 [nitpick/wes-5 cleanup followup] ... ITYM "anything that persists across reboot" instead of "on disk". ("on disk" would have false positives and false negatives -- flash-based filesystems, suspend-to-disk/virtual-machine checkpoints instead of reboot).