You are on page 1of 12

System Data Files and Information

Introduction A UNIX system requires numerous data files for normal operation: the password file /etc/passwd and the group file /etc/group are two files that are frequently used by various programs. For example, the password file is used every time a user logs in to a UNIX system. Password File The UNIX System's password file, called the user database by POSIX.1, contains the fields shown in Figure 1.1. These fields are contained in a passwd structure that is defined in <pwd.h>. Figure 1.1. Fields in /etc/passwd file Description user name encrypted password numerical user ID numerical group ID comment field initial working directory initial shell (user program) struct passwd member char *pw_name char *pw_passwd uid_t pw_uid gid_t pw_gid char *pw_gecos char *pw_dir char *pw_shell POSIX.1 FreeBSD 5.2.1 Linux 2.4.22 Mac OS X 10.3 Solaris 9

Generally, passwd file entry looks as follows

1.Username: It is used when user logs in. It should be between 1 and 32 characters in length. 2.Password: An x character indicates that encrypted password is stored in /etc/shadow file. 3.User ID (UID): Each user must be assigned a user ID (UID). UID 0 (zero) is reserved for root and UIDs 1-99 are reserved for other predefined accounts. Further UID 100-999 are reserved by system for administrative and system accounts/groups. 4.Group ID (GID): The primary group ID (stored in /etc/group file) 5.User ID Info: The comment field. It allow you to add extra information about the users such as user's full name, phone number etc. This field use by finger command. 6.Home directory: The absolute path to the directory the user will be in when they log in. If this directory does not exists then users directory becomes / 7.Command/shell: The absolute path of a command or shell (/bin/bash). Typically, this is a shell. Please note that it does not have to be a shell. POSIX.1 defines only two functions to fetch entries from the password file. These functions allow us to look up an entry given a user's login name or numerical user ID.

#include <pwd.h> struct passwd *getpwuid(uid_t uid); struct passwd *getpwnam(const char *name); Both return: pointer if OK, NULL on error The getpwuid() routine searches the user database for an entry with a matching user ID. If found, it returns a pointer to a structure with information about that user. Getting an Entry for the Root User The following example gets the user database entry for the user with user ID 0 (root). #include <sys/types.h> #include <pwd.h> #include <stdio.h> int main(){ uid_t id = 0; struct passwd *pwd; if ((pwd = getpwuid(id)) != NULL) { printf("The user id is: %d\n", pwd->pw_uid); printf("The group id is: %d\n", pwd->pw_gid); } else printf("error"); return 0; }

Getting an Entry for the User Name


The getpwnam() routine searches the user database for an entry with a matching name. If found, it returns a pointer to a structure with information about that user #include <sys/types.h> #include <pwd.h> #include <stdio.h> int main() { struct passwd *pd; if ((pd = getpwnam("root"))!= NULL) { printf("The user name is: %s\n", pd->pw_name); printf("The initial directory is: %s\n", pd->pw_dir); printf("The initial user program is: %s\n", pd->pw_shell); } else printf("error."); return 0; }

These two POSIX.1 functions are fine if we want to look up either a login name or a user ID, but some programs need to go through the entire password file. The following function can be used for this. #include <pwd.h> struct passwd *getpwent(void); Returns: pointer if OK, NULL on error or end of file void setpwent(void); void endpwent(void); We call getpwent to return the next entry in the password file. As with the two POSIX.1 functions, getpwent returns a pointer to a structure that it has filled in. This structure is normally overwritten each time we call this function. If this is the first call to this function, it opens whatever files it uses. There is no order implied when we use this function; the entries can be in any order, because some systems use a hashed version of the file /etc/passwd. #include<stdio.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h> #include<dirent.h>#include<pwd.h> int main (int argc, char *filename[]){ struct stat buf; struct passwd *p; p = getpwuid(buf.st_uid); while((p = getpwent())!= NULL){ printf("%s\n",p->pw_name);printf("%s\n",p->pw_passwd);printf("%d\n",p->pw_uid); printf("%d\n",p->pw_gid);printf("%s\n",p->pw_gecos);printf("%s\n",p->pw_dir); printf("%s\n",p->pw_shell);} return 0;} shadow password file: /etc/shadow file stores actual password in encrypted format for user's account with additional properties related to user password i.e. it stores secure user account information. All fields are separated by a colon (:) symbol. It contains one entry per line for each user listed in /etc/passwd file Generally, shadow file entry looks as follows: /etc/shadow file fields

1. User name : It is your login name 2. Password: It your encrypted password 3. Minimum: The minimum number of days required between password changes i.e. the number of days left before the user is allowed to change his/her password 4. Maximum: The maximum number of days the password is valid (after that user is forced to change his/her password) 5. Warn : The number of days before password is to expire that user is warned that his/her password must be changed 6. Inactive : The number of days after password expires that account is disabled Expire : days since Jan 1, 1970 that account is disabled i.e. an absolute date specifying when the login may no longer be used

Understanding Group File. etc/group is a text file which defines the groups to which users belong under Linux and UNIX operating system. Under Unix / Linux multiple users can be categorized into groups. Unix file system permissions are organized into three classes, user, group, and others. The use of groups allows additional abilities to be delegated in an organized fashion, such as access to disks, printers, and other peripherals. This method, amongst others, also enables the Superuser to delegate some administrative tasks to normal users. /etc/group file It stores group information or defines the user groups i.e. it defines the groups to which users belong. There is one entry per line, and each line has the following format (all fields are separated by a colon (:) e.g:

The fields are as follows: i. group_name the name of the group. ii. password the (encrypted) group password. If this field is empty, no password is needed. iii. GID the numeric group ID. iv. user_list a list of the usernames that are members of this group, separated by commas. Why do we Need Groups in Linux? Users on Linux and UNIX systems are assigned to one or more groups for the following reasons: y To share files or other resource with a small number of users y Ease of user management y Ease of user monitoring y Group membership is perfect solution for large Linux (UNIX) installation. y Group membership gives you or your user special access to files and directories or devices which are permitted to that group

User tom is part of both 'Web developers' and 'Sales' group. So tom can access files belongs to both groups. To look up group name and ID We can look up either a group name or a numerical group ID with the following two functions, which are defined by POSIX.1. #include <grp.h> struct group *getgrgid(gid_t gid); struct group *getgrnam(const char *name); Both return: pointer if OK, NULL on error As with the password file functions, both of these functions normally return pointers to a static variable, which is overwritten on each call.If we want to search the entire group file, we need some additional functions. The following function is like their counterparts for the password file. #include <grp.h> struct group *getgrent(void); Returns: pointer if OK, NULL on error or end of file
Example to show groups name #include<stdio.h>#include<unistd.h>#include<sys/types.h>#include<sys/stat.h> #include<dirent.h>#include<grp.h>#include<pwd.h> int main (int argc, char *filename[]){ struct group *g; struct passwd *p; /* --- users*/ while ( (p = getpwent()) != NULL){ printf("%s\n",p->pw_name); } while ((g = getgrent())){ printf("%s\n",g->gr_name); } return 0; }

Example to get grouplist of user #include <stdio.h>#include <stdlib.h>#include <grp.h>#include <pwd.h> int main(int argc, char *argv[]){ int j, ngroups; gid_t *groups; struct passwd *pw; struct group *gr; ngroups = atoi(argv[2]); groups = malloc(ngroups * sizeof (gid_t)); pw = getpwnam(argv[1]); if (pw == NULL) { perror("getpwnam"); exit(EXIT_SUCCESS);} if (getgrouplist(argv[1], pw->pw_gid, groups, &ngroups) ==-1) {

fprintf(stderr,"getgrouplist() returned -1; ngroups = %d\n",ngroups); exit(EXIT_FAILURE); } fprintf(stderr, "ngroups = %d\n", ngroups); for (j = 0; j < ngroups; j++) { printf("%d", groups[j]); gr = getgrgid(groups[j]); if (gr != NULL) printf(" (%s)", gr->gr_name); printf("\n"); } exit(EXIT_SUCCESS); } Sample out put for above example

Description The getgrouplist() function scans the group database to obtain the list of groups that user belongs to. Up to *ngroups of these groups are returned in the array groups. If it was not among the groups defined for user in the group database, then group is included in the list of groups returned by getgrouplist(); typically this argument is specified as the group ID from the password record for user. The ngroups argument is a value-result argument: on return it always contains the number of groups found for user, including group; this value may be greater than the number of groups stored in groups. RETURN VALUE If the number of groups of which user is a member is less than or equal to *ngroups, then the value *ngroups is returned. If the user is a member of more than *ngroups groups, then getgrouplist() returns -1. In this case the value returned in *ngroups can be used to resize the buffer passed to a further call getgrouplist().

In terminal In terminal to find out about the group list of a user run the following commands  Id -G {user name}  eg: id G root This will show the groups IDs against the use root .  Id Gn {user name}

Other Data Files

We've discussed only two of the system's data files so far: the password file and the group file. Numerous other files are used by UNIX systems in normal day-to-day operation Routines for accessing system data files Description Data file Passwords Groups Shadow Hosts Networks Protocols Services /etc/passwd /etc/group /etc/shadow /etc/hosts Header <pwd.h> <grp.h> Structure Additional keyed lookup functions passwd group getpwnam, getpwuid getgrnam, getgrgid getspnam gethostbyname, gethostbyaddr getnetbyname, getnetbyaddr getprotobyname, getprotobynumber getservbyname, getservbyport

<shadow.h> spwd <netdb.h> hostent netent protoent servent

/etc/networks <netdb.h> /etc/protocols <netdb.h> /etc/services <netdb.h>

Login Accounting Two data files that have been provided with most UNIX systems are the utmp file, which keeps track of all the users currently logged in, and the wtmp file, which keeps track of all logins and logouts. With Version 7, one type of record was written to both files, a binary record consisting of the following structure: struct utmp { char ut_line[8]; /* tty line: "ttyh0", "ttyd0", "ttyp0", ... */ char ut_name[8]; /* login name */ long ut_time; /* seconds since Epoch */};

On login, one of these structures was filled in and written to the utmp file by the login program, and the same structure was appended to the wtmp file. On logout, the entry in the utmp file was erasedfilled with null bytesby the init process, and a new entry was appended to the wtmp file. This logout entry in the wtmp file had the ut_name field zeroed out. Special entries were appended to the wtmp file to indicate when the system was rebooted and right before and after the system's time and date was changed. The who(1) program read the utmp file and printed its contents in a readable form. Later versions of the UNIX System provided the last(1) command, which read through the wtmp file and printed selected entries.

Most versions of the UNIX System still provide the utmp and wtmp files, but as expected, the amount of information in these files has grown. The 20-byte structure that was written by Version 7 grew to 36 bytes with SVR2, and the extended utmp structure with SVR4 takes over 350 bytes! The detailed format of these records in Solaris is given in the utmpx(4) manual page. With Solaris 9, both files are in the /var/adm directory. Solaris provides numerous functions described in getutx(3) to read and write these two files. On FreeBSD 5.2.1, Linux 2.4.22, and Mac OS X 10.3, the utmp(5) manual page gives the format of their versions of these login records. The pathnames of these two files are /var/run/utmp and /var/log/wtmp. System Identification : System identification we have a function known as uname Uname return the information on the current host and the operating system #include <sys/utsname.h> int uname(struct utsname *name); Returns: non-negative value if OK, 1 on error struct utsname { char sysname[]; char nodename[]; char release[]; char version[]; /* name of the node /* current release of OS /* current version of this release */

char machine[];

/* name of hardware type */ };

Example of utsname :#include <sys/utsname.h> #include <stdio.h> void dump_uname(void) { struct utsname uts; uname( &uts ); printf( "Init: uts.sysname: %s\n", uts.sysname ); printf( "Init: uts.nodename: %s\n", uts.nodename );

printf( "Init: uts.release: %s\n", uts.release ); printf( "Init: uts.version: %s\n", uts.version ); printf( "Init: uts.machine: %s\n", uts.machine ); puts(""); } Output of the example :sysname is always RTEMS nodename is always 1 in a single CPU system release is of the form rtems-VERSION machine is of the form: CPU/CPU Model CPU is the CPU family CPU Model will usually reflect the multilib variant

Get host name: Each string is null-terminated. The maximum name lengths supported by the different platforms #include <unistd.h> int gethostname(char *name, int namelen); The namelen argument specifies the size of the name buffer.

Example :char hostname[128];

gethostname(hostname, sizeof hostname); printf("My hostname: %s\n", hostname);

Your system has a name. They all do. This is a slightly more Unixy thing than the rest of the networky stuff we've been talking about, but it still has its uses. For instance, you can get your host name, and then call gethostbyname() to find out your IP address. The parameter name should point to a buffer that will hold the host name, and len is the size of that buffer in bytes. gethostname() won't overwrite the end of the buffer (it might return an error, or it might just stop writing), and it will NUL-terminate the string if there's room for it in the buffer.

You might also like