Users, Groups, and Security


The UNIX and Windows security models are quite different. Interix, as a subsystem of Windows, uses the underlying Windows security model. At the same time, Interix attempts to present the Windows security model in a way that is consistent with UNIX security.

This results in some key differences between the way in which Interix security works and the way in which standard UNIX security works. (For a discussion of someof these differences, see Comparison of Windows and UNIX Architectures in Chapter 2, Windows and UNIX Compared.) This section covers the differencesin the security model and describes how to modify code to operate under Interix.

The key areas that are addressed here are:

  • User names in Interix

  • UNIX UIDs and GIDs versus Windows SIDs

  • The passwd file structure

  • User and group operation functions

  • Running programs as other users or groups

  • User accounting database functions

User Names in Interix

User names are handled differently in UNIX and Interix. In UNIX, they are lowercase text stored in the passwd file. In Interix, the user names are taken from the account database and can contain information about the domain the accountis in as well as its user name .

It s important to note that Windows places user and group names in the same namespace, while UNIX places them in separate namespaces. What this means is that a UNIX environment might have a user named tools and a group named tools, while a Windows environment would forbid that and require, for example, that the group be named tools_group. Applications should be written in such a waythat user and group names aren t hard-coded; obviously, any code that expects identical user and group names will need to be changed.

From a programming standpoint, functions that use the user or group name in UNIX, such as getpwnam() and getgrnam() , accept a DomainName + UserName pair in Interix. The DomainName part is explained in more detail in the following paragraphs. Any application code that assumes that a user or group name cannot contain a plus sign must be changed. Similarly, applications should be prepared to accept user or group names that are considerably longer than the norm on UNIX systems. (Traditional UNIX systems limit user and group names to eight characters each.)

Interix User Names and Windows Domains

A domain is a collection of networked Windows-based computers that use a common security database. Most Windows-based computers have access to at least two domains: the network domain, which has a centralized security database; and a local domain, which uses the security database on the local computer. On domain controllers, the network and local domains are the same.

Windows user and group names use the format DomainName + UserName . The pw_name and gr_name members in the Interix passwd and group structuresuse the same format. They can also be passed in the form + UserName or UserName .

Table 10.10 on the next page describes how domain and user names are interpreted.

Table 10.10: Domain and User Names in Interix

Name

Description

DomainName + UserName

The group or user name belonging to the specified domain.

+ UserName

When passed to an Interix function, finds the closest matchingname in the same search order used by Windows. Usually, this is used with well-known names such as +SYSTEM or +Administrator,and the function will find the matching name on the local computer. However, if the name is not found on the local computer, the function will search the primary domain and other trusted domains for that name, returning the first match.When this format is returned from an Interix function, it indicatesa name from the local computer domain.

UserName

The group or user name in the same domain as the calling process.

The Interix principal domain is normally the domain to which the system itself belongs. This can be overridden by changing a registry setting (HKEY_LOCAL_MACHINE\Software\Microsoft\Services For Unix\PrincipalDomain). Applications can determine the system s principaldomain through the getpdomain() function.

UNIX UIDs and GIDs vs. Windows SIDs

UNIX systems translate user and group names to integers, UID and GID, respectively. These values are typically 32-bit numbers and are assigned arbitrarily by an administrator. It is possible to reuse UID and GID values, and it is possible for multiple user or group names to correspond to a particular UID or GID. The UID and GID values are taken from distinct spaces ” that is, it is possible for user joes to have UID 556 and group joeteam to have GID 556. There is no guarantee of uniqueness for UID or GID values between separate systems. Two UNIX systems can have different human users each with the same UID of 556.

Windows systems translate user and group names to SIDs, which are large (typically 112-bit) structured values. SIDs are automatically assigned by Windows when users or groups are created. SIDs are guaranteed to be globally unique and can never be reused. There is a one-to-one relationship between a SID and a user or group.SIDs for users and groups come from the same space.

The UNIX APIs expose user and group identities as integers of type UID_t and GID_t, respectively. Interix conforms to this requirement by mapping Windows SIDs to UID and GID values. All systems belonging to the same domain will perform this mapping in the same way. Under normal circumstances, there will be no collisions among mapped UID and GID values ” that is, no two Windows SIDs will be converted to the same UID_t or GID_t.

Because mapped UID and GID values may differ between systems joined to different domains, applications that need to preserve identity information should store user or group names rather than UID or GID values.

The passwd File Structure

The files /etc/passwd and /etc/groups do not exist on an Interix system; therefore, some of the information contained in the structure struct passwd is obtainedin a nonstandard way, such as the following:

  • pw_gecos

    The user information member contains the text from the Description fieldin the Windows user account information.

  • pw_shell

    The user s shell member is always /bin/sh .

Because other applications in both the Interix subsystem and the Win32 subsystem can use the information in the pw_gecos and pw_shell fields, the contents of the pw_gecos member will not necessarily continue to be taken from the Description field found in a Windows user account.

Interix also returns two additional parameters not available on UNIX systems:

  • The pw_change parameter returns the time until the password must be changed.

  • The pw_expire parameter returns the time when the user s account expires .

User and Group Operation Functions

Because the Interix security model is integrated with the Windows security subsystem, Interix does not support all of the user and group functions that manipulate or obtain information from the /etc/passwd , /etc/group , /etc/shadow , or /etc/gshadow files. Table 10.11 summarizes the calls that Interix does not support and recommended replacements .

Table 10.11: User and Group Calls Not Supported by Interix

Function Name

Description

Suggested Interix Replacement

endspent

Indicates that the caller expects to do no further shadow password retrieval operations.

Endpwent()

fgetgrent,
fgetgrent_r

Gets the group file entry.

struct group * getgrent ()

fgetpwent,
fgetpwent_r

Gets the password file entry.

struct passwd *getpwent()

fgetspent,
fgetspent_r

Reads from a shadow file stream.

struct passwd *getpwent()
Note: Interix does not support a concept of a shadow password file.

getgrent_r,
getgrgid_r,
getgrnam_r

Gets the group file entry.

struct group * getgrent (void)
struct group * getgrgid (GID_t GID)
struct group * getgrnam (const char *groupname)

getpw

Gets the password file entry from UID.

getpwuid(UID) or getpwnam(*login)
Note: This conversion should be performed before the port to Interix on all supported UNIX platforms.

getpwent_r,
getpwnam_r,
getpwuid_r

Gets the password file entry.

getpwent, getpwnam, getpwuid
Note: The re-entrant routines are not required on Interix at this time because it is not multithreaded.

getspent,
getspent_r

Gets the shadow password file entry.

struct passwd *getpwent()
Note: Interix does not support a concept of a shadow password file, and the re-entrant routines are not required on Interix at this time because it is not multithreaded.

getspnam,
getspnam_r

Gets the shadow logon name file entry.

getpwnam(*login)
Note: Interix does not support a concept of a shadow password file, and the re-entrant routines are not required on Interix at this time because it is not multithreaded.

initgroups
(*name, GID_t basegid)

Initializes the supplementary group access list.

getgroups (int gidsetsize, GID_t grouplist[ ])
For a usage example, see the sample code in Interix initgroups Example following this table.

lckpwdf,
ulckpwdf

Manipulates the shadow password database lock file.

//lckpwdf
//ulckpwdf

putpwent

Writes a password file entry.

For password change:
chpass(*fq_user, *oldpw, *newpw)

putspent

Writes a shadow password file entry.

For password change:
chpass(*fq_user, *oldpw, *newpw)

setgroups

Sets supplementary group access list Ids.

The list of supplementary groups can be retrieved with getgroups , but it is not possible to build and apply an arbitrary list of supplementary groups.

setresgid,
where
rgid=egid=sgid

Sets real, effective, and saved group ID.

setgid (GID)
For more information about changing UID and GID in Interix, see Changing User ID by Using the Interix setuser () Function later in this chapter.

setresgid,
where
rgid!=egid!=sgid

Sets real, effective, and saved group ID.

setregid (rgid, egid)
For more information about changing UID and GID in Interix, see Changing User ID by Using the Interix setuser() Function later in this chapter.

setresuid,
where
ruid=euid=suid

Sets real, effective, and saved user ID.

setuid (UID) For more information about changing UID and GID in Interix, see Changing User ID by Using the Interix setuser() Function later in this chapter.

setresuid,
where
ruid!=euid!=suid

Sets real, effective, and saved user ID.

setreuid (ruid, euid)
For more information about changing UID and GID in Interix, see Changing User ID by Using the Interix setuser() Function later in this chapter.

setspent

Sets the shadow password entry in the database.

Interix does not support a concept of a shadow password file.

Interix initgroups Example

 <initgroups.c> 
Interix getgroups Conversion Example
 #include <sys/types.h> #include <unistd.h> #include <grp.h> int main() {    struct group *ptr_group;    GID_t grouplist[100];    int num;    num = getgroups (99, grouplist);    printf("group\tID:\n---------------\n");    if (num > 0)       while(num) {          ptr_group = getgrgid(grouplist[num]);          printf("%s\t%d\n", ptr_group->gr_name, grouplist[num]);       }    else       printf("num=%d\n", num);    exit(0); } 

Running Programs as Other Users or Groups

Some programs require access to resources to which the current user has no access. This is solved on UNIX systems by running the program as a specific user or group rather than as the current user or group. UNIX programs can use special permissions on the program s executable file called the setuid and setgid bits.

According to the POSIX standard, a file s permissions include bits to set a UID ( setuid ) and to set a GID ( setgid ). If either or both bits are set on a file and a process executes that file, the process runs with an identity based on the UID or GID of the file, respectively.

When you run a program that has the setuid bit set in the file permissions, it runsas if the file s owner executed it no matter who actually started it. These user and group IDs are called effective user ID and effective group ID .

When an Interix process executes a file that has the setuid or setgid bit set, Interix constructs local security tokens for the process with the privileges assigned to the owner (if setuid is set) and/or group (if setgid is set) of the file. Because these tokens are local, they are not recognized by other computers on the network. Even if the file is owned by a member of the Domain Admins group, the process still does not have trusted access to other computers in the domain by using Windows networking.

For example, a process executes a program file that has its setuid bit set and thatis owned by a member of the Domain Admins group. If that program attempts to change a domain user s password, that attempt fails because the security tokensof the process are local and are not recognized by other systems in the domain.If, however, the program attempts to change a local user s password, the attempt succeeds because the file s owner is a member of the Domain Admins group, which typically belongs to the local computer s Administrators group.

On UNIX systems, the user and/or group owner is often set to root, thereby allowing a nonroot program to run with root privileges. On Interix, the owner should be set to the Local Administrator or to a member of the Domain Admins group.

In summary, UNIX and Interix systems maintain at least two user and group IDs: the effective user ID and effective group ID, and the real user ID and real group ID . Most UNIX systems and Interix also support a saved set user ID and savedset group ID.

Changing Between Real and Effective User ID in SetUID Programs

Often in programs with the setuid bit set, it is desirable to be able to change the real and effective IDs during execution. For example, programmers might wantto do one of the following in setuid programs:

  • Change from the initial effective user/group ID to the real user/group ID.

  • Change from the real user/group ID back to the initial effective user/group ID.

These two actions can be performed by using the UNIX setuid() function. In addition, Interix provides another function named setuser() , which simplifies changing the user ID.

Changing User ID by Using the Interix setuser() Function

The proprietary Interix setuser() function changes the effective and real UID and GID of the current process to that of the specified user name. All of the security attributes and permissions become those of the specified user name. The current working directory of the process does not change.

o use setuser() to replace the standard UNIX calls

  1. Add the following include statement to the code:

     #include <interix/security.h> 
  2. Rewrite the code to use the setuser() function as defined here:

    int setuser(char *username , char *password , int flags )

    Set the arguments as follows :

    • The username argument is the name of the user. If the user name is not fully qualified with a domain name (that is, domain + name ), it is not changed.On a system configured for workgroups, specify the domain as NULL:that is, use the string +name for username .

    • The password argument is the plaintext password for the specified user name.

    • The flags argument comprises control flags. Possible values for flags are defined in interix/security.h as follows:

      SU_COMPLETE changes the real and effective user and group IDs and all security attributes to the default for the specified user.

      SU_CHECK verifies that the process can perform a setuser() action by using SU_COMPLETE for the specified user name and password. This is a quick way to verify a password for a user. This action is equivalent to the older Interix call, authenticateuser() .

The setuser() function has the advantage of changing both the UID and the GID with only one function call. However, it has the disadvantage that it is only supportedon Interix.

Performance degradation can occur if a process changes identity to a user who does not have permission to be located in the current working directory. The best solution to this is to call chdir() to a directory known to be permitted for the new identity after the call to setuser() .

The Interix exec *_asuser() Functions

Interix provides a set of interfaces used to execute a process as another user. These functions and structures are defined in the header file security.h. They include execl_asuser() , execle_asuser() , execlp_asuser() , execv_asuser() , execve_asuser() , and execvp_asuser() .

All of these functions use a user security structure, struct usersec , to identify another user. The usersec structure is illustrated below:

 struct usersec {    char *   user;    char *   domain;    char *   password;    int      logontype;    int      logonprovider; }; 

The domain , user , and password members of the structure have their normal meanings. The logontype and logonprovider members are provided for future development; leave them at the default values of 0.

The six exec*_asuser() functions correspond to the six exec functions: execl() , execle() , execlp() , execv() , execve () , and execvp() . The arguments after the struct usersec member are identical to their exec counterparts.

User Accounting Database Functions

Interix supports a subset of the routines used to track and manage a user accounting database. Interix does support the following calls: endutxent , getutxent , getutxid , getutxline , pututxline , and setutxent .

Table 10.12 shows user account database functions that are not supported in Interix, and recommended alternatives to them.

Table 10.12: User Account Database Functions Not Supported by Interix

Function Name

Description

Suggested Interix Replacement

acct

Enables or disables process accounting.

No support or equivalent in Interix.

endutent

Closes the currently open database.

endutxent

getutent

Extracts the next entry from a UTMP database.

getutxent

getutid

Searches forward from the current point in the UTMP database.

getutxid

getutline

Searches forward from the current point in the UTMP database.

getutxline

getutmp

Copies the information stored in the members of the UTMPX structure to the corresponding members of the UTMP structure.

No support or equivalent for the UTMP structure in Interix.

getutmpx

Copies the information stored in the members of the UTMP structure to the corresponding members of the UTMPX structure.

No support or equivalent for the UTMP structure in Interix.

logwtmp

Appends an entry to the WTMP file.

pututxline

pututline

Writes the supplied UTMP structure into the UTMP database.

pututxline

setutent

Resets the input stream to the beginning.

setutxent

updwtmp

Appends an entry to the WTMP file.

pututxline

updwtmpx

Writes the contents of the UTMPX structure pointed to by UTMPX to the database.

pututxline

utmpname

Changes the name of the database file examined to another file.

 

utmpxname

Changes the name of the database file examined from /var/adm/utmpx to any other file, typically /var/adm/wtmpx .

 



UNIX Application Migration Guide
Unix Application Migration Guide (Patterns & Practices)
ISBN: 0735618380
EAN: 2147483647
Year: 2003
Pages: 134

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net