This chapter describes the programming interfaces that read entries in the user and profile databases. Entries are stored in these databases when the system administrator sets up users and profiles using the Solaris Management Console (SMC) graphical user interfaces.
In the Solaris and the Trusted Solaris environment, user information is held in four databases:
user_attr(4) - The /etc/user_attr file contains extended user attributes, using a keyword=value format.
auth_attr(4) - The /etc/security/auth_attr file contains the definitions of authorizations, which can be included in rights profiles.
prof_attr(4) - The /etc/security/prof_attr file contains the name, description, authorizations, subordinate rights profiles, and help files for rights profiles.
The following figure shows how the user databases work together and with policy.conf(4) and label_encodings(4) to provide user attributes.
The user_attr database contains the attributes shown, including a comma-separated list of profile names. The contents of the profiles are split between the prof_attr database, which contains profile identification information, authorizations assigned to the profile, and subordinate profiles, and the exec_attr database, which contains commands and actions with their associated security attributes. The auth_attr file supplies available authorizations to the prof_attr database and the policy.conf database. (Note that although it is possible to assign authorizations directly to users through user_attr, this practice is discouraged.) The policy.conf file supplies default attributes to be applied to all users on the machine. The label_encodings file supplies label defaults if they are not otherwise specified.
The exec_attr entries within a profile are searched only in the scope in which that profile is found. The scope ( files, NIS, or NIS+), is specified in the nsswitch.conf file.
The programming interfaces for manipulating user data require the following header files:
#include <user_attr.h> #include <prof_attr.h> #include <exec_attr.h> #include <auth_attr.h> |
The examples in this chapter compile with the following libraries:
-lsecdb -lnsl -lcmd -DTSOL |
The main interface for accessing user information is the getuserattr(3SECDB) family of interfaces. The getuserattr function enumerates the user_attr entries. The getusernam function searches for a user_attr entry with a given name. In similar fashion, the getuseruid function searches for a user_attr entry with a given UID. Successive calls to these functions return successive user_attr entries or NULL.
The rights profile data is spread between two databases: prof_attr(4) and exec_attr(4). There are two corresponding interface families for accessing rights profiles data: getprofattr(3SECDB) and getexecattr(3SECDB).
The getprofattr function enumerates the prof_attr entries. The getprofnam function searches for a prof_attr entry with a given name. The getproflist function searches for supplementary profiles.
An example program using the getprofattr function follows.
#include <stdio.h> #include <prof_attr.h> main(int argc, char *argv[]) { profattr_t *profp = NULL; int i; char *kv_str = NULL; char *attr[] = { PROFATTR_AUTHS_KW, PROFATTR_PROFS_KW, "help", NULL }; if (argc != 2) { printf("\tUsage: %s \"profile name\"\n", argv[0]); printf("\t\tPut multi-word profile names in quotes\n"); exit(1); } if ((profp = getprofnam(argv[1])) == NULL) { printf("\tNo prof_attr entry found for %s\n", argv[1]); exit(0); } if (profp->name) printf("\t%s: %s\n", PROFATTR_COL0_KW, profp->name); if (profp->res1) printf("\t%s: %s\n", PROFATTR_COL1_KW, profp->res1); if (profp->res2) printf("\t%s: %s\n", PROFATTR_COL2_KW, profp->res2); if (profp->desc) printf("\t%s: %s\n", PROFATTR_COL3_KW, profp->desc); if (profp->attr) { for (i = 0; attr[i] != NULL; i++) { if (kv_str = kva_match(profp->attr, attr[i])) printf("\t%s: %s\n", attr[i], kv_str); } } free_profattr(profp); }
This program gets the six fields in the argument's prof_attr record and dumps them to a display as follows:
% getprof ``Media Backup'' name: Media Backup res1: res2: desc: Backup files and file systems auths: solaris.device.allocate help: RtMediaBkup.html |
The rights profile data is spread between two databases: prof_attr(4) and exec_attr(4). The getexecattr(3SECDB).
This example program uses the getexecattr() routine to find the first exec_attr entry of type cmd in profile supplied.
#include <stdio.h> #include <exec_attr.h> main(int argc, char *argv[]) { execattr_t *execp = NULL; int i; int search_flag = GET_ONE; char *type = KV_COMMAND; char *id = NULL; char *kv_str = NULL; char *attr[] = { EXECATTR_EUID_KW, EXECATTR_EGID_KW, EXECATTR_UID_KW, EXECATTR_GID_KW, EXECATTR_PRIV_KW, EXECATTR_LABEL_KW, EXECATTR_CLEAR_KW, NULL }; if (argc != 2) { printf("\tUsage: %s \"profile name\"\n", argv[0]); printf("\t\tPut multi-word profile name in quotes.\n"); exit(1); } if ((execp = getexecprof(argv[1], type, id, search_flag)) == NULL) { printf("\tNo exec_attr entry found for id %s of type %s" " in profile %s\n", ((id == NULL) ? "NULL" : id), type, argv[1]); exit(0); } if (execp->name) printf("\t%s: %s\n", EXECATTR_COL0_KW, execp->name); if (execp->policy) printf("\t%s: %s\n", EXECATTR_COL1_KW, execp->policy); if (execp->type) printf("\t%s: %s\n", EXECATTR_COL2_KW, execp->type); if (execp->res1) printf("\t%s: %s\n", EXECATTR_COL3_KW, execp->res1); if (execp->res2) printf("\t%s: %s\n", EXECATTR_COL4_KW, execp->res2); if (execp->id) printf("\t%s: %s\n", EXECATTR_COL5_KW, execp->id); if (execp->attr) { for (i = 0; attr[i] != NULL; i++) { if (kv_str = kva_match(execp->attr, attr[i])) printf("\t%s: %s\n", attr[i], kv_str); } } free_execattr(execp); }
Here is a typical result.
% getexecprof ``Media Backup'' name: Media Backup policy: tsol type: cmd res1: res2: id: /usr/lib/fs/ufs/ufsdump egid: 3 privs: 1,4,5,8,10,11,12,19,71 |
The next example program uses the getexecattr() routine to find the first exec_attr entry of type cmd in the first profile for the supplied user.
#include <stdio.h> #include <exec_attr.h> main(int argc, char *argv[]) { execattr_t *execp = NULL; int i; int search_flag = GET_ONE; char *type = KV_COMMAND; char *id = NULL; char *kv_str = NULL; char *attr[] = { EXECATTR_EUID_KW, EXECATTR_EGID_KW, EXECATTR_UID_KW, EXECATTR_GID_KW, EXECATTR_PRIV_KW, EXECATTR_LABEL_KW, EXECATTR_CLEAR_KW, NULL }; if (argc != 2) { printf("\tUsage: %s \"login name\"\n", argv[0]); exit(1); } if ((execp = getexecuser(argv[1], type, id, search_flag)) == NULL) { printf("\tNo exec_attr entry found for id %s of type %s" " for user %s\n", ((id == NULL) ? "NULL" : id), type, argv[1]); exit(0); } if (execp->name) printf("\t%s: %s\n", EXECATTR_COL0_KW, execp->name); if (execp->policy) printf("\t%s: %s\n", EXECATTR_COL1_KW, execp->policy); if (execp->type) printf("\t%s: %s\n", EXECATTR_COL2_KW, execp->type); if (execp->res1) printf("\t%s: %s\n", EXECATTR_COL3_KW, execp->res1); if (execp->res2) printf("\t%s: %s\n", EXECATTR_COL4_KW, execp->res2); if (execp->id) printf("\t%s: %s\n", EXECATTR_COL5_KW, execp->id); if (execp->attr) { for (i = 0; attr[i] != NULL; i++) { if (kv_str = kva_match(execp->attr, attr[i])) printf("\t%s: %s\n", attr[i], kv_str); } } free_execattr(execp); }
Here is a typical result.
% getexecuser janez name: Media Backup policy: tsol type: cmd res1: res2: id: /usr/lib/fs/ufs/ufsdump egid: 3 privs: 1,4,5,8,10,11,12,19,71 |