This chapter provides a summary overview of FNS, a brief description of setup and configuration steps, and a programming example. Experienced administrators may find that this quick start chapter is all that they need.
For more detailed information, see the remaining chapters of this part. For more detailed initial FNS setup and configuration information, see Solaris Naming Setup and Configuration Guide.
Federated Naming Service (FNS) provides a method for federating multiple naming services under a single, simple interface for naming and directory operations. Naming services that can be linked with FNS include: NIS+, NIS, files, DNS, and X.500/LDAP.
The programming interface and policies that FNS supports are specified by XFN (X/Open Federated Naming).
FNS is useful for the following reasons:
A single uniform naming and directory interface is provided to clients for accessing naming and directory services. Consequently, the addition of new naming and directory services does not require changes to applications or existing services.
Names can be composed in a uniform way. FNS defines a way to uniformly compose names from different naming systems so that applications can uniformly address objects in these different naming systems.
Coherent naming is encouraged through the use of shared contexts and shared names. Different applications can use these shared names and contexts and need not duplicate the work.
Fundamental to FNS are the notions of composite names and contexts.
A composite name is a name that spans multiple naming systems.
A composite name consists of an ordered list of components. Each component is a name from the namespace of a single naming system. Individual naming systems are responsible for the syntax of each component. FNS defines the syntax for constructing a composite name using names from component naming systems. Composite names are composed left to right using the slash character (/) as the component separator.
For example, the composite name .../doc.com/site/bldg-5.alameda consists of four components: ..., doc.com, site, and bldg-5.alameda.
A context provides operations for:
Associating (binding) names to objects
Resolving names to objects
Removing bindings
Listing names
Renaming
Associating attributes with named objects
Retrieving and updating attributes associated with named objects
Searching for objects using attributes
A context contains a set of name-to-reference bindings. Each reference contains a list of communication end-points or addresses. The federated naming system is formed by contexts from one naming system being bound in the contexts of another naming system. Resolution of a composite name proceeds from contexts within one naming system to those in the next until the name is resolved.
Attributes may be applied to named objects. Attributes are optional. A named object can have no attributes, one attribute, or multiple attributes.
Each attribute has a unique attribute identifier, an attribute syntax, and a set of zero or more distinct attribute values.
XFN defines the base attribute interface for examining and modifying the values of attributes associated with existing named objects. These objects can be contexts or any other types of objects. Associated with a context are syntax attributes that describe how the context parses compound names.
The extended attribute interface contains operations that search for specific attributes and that create objects and their associated attributes.
Enterprise-level naming services are used to name objects within an enterprise. FNS currently supports three enterprise-level naming services:
NIS+ (see "NIS+".).
NIS (see "NIS").
Files (see "Files-Based").
NIS+ is the preferred enterprise-wide information service in the Solaris operating environment environment. FNS organization units correspond to NIS+ domains and subdomains. There is one orgunit context for each domain and subdomain.
Under NIS+, FNS context and attribute data are stored in NIS+ tables. These tables are stored in NIS+ directory objects named ctx_dir. There is a ctx_dir directory object for each NIS+ domain and subdomain, residing at the same level as the domain's groups_dir and org_dir directory objects. Thus, the directory object ctx_dir.sales.doc.com. contains FNS tables which store FNS context and attribute data for the sales.doc.com. domain.
Under NIS+, you use FNS and NIS+ commands to work with the information in FNS tables. Do not edit these tables directly or manipulate them with UNIX commands.
NIS is an enterprise-wide information service in the Solaris environment. Each enterprise is a single NIS domain. There is one FNS organizational unit which corresponds to the single NIS domain.
Under NIS, FNS context and attribute data are stored in NIS maps. These maps are stored in a /var/yp/domainname directory on a NIS server. Under NIS, the super user can use FNS commands to work with the information in FNS maps.
If certain conditions are met, any NIS client (machine, process, or user) can use FNS commands such as fncreate_fs or fncreate_printer to update the client's own contexts. This allows NIS clients to use FNS commands to update applications such as Printer Administrator, CDE Calendar Manager, Admin Tool and others.
For non-super-users to update their own contexts with FNS commands, the following conditions must be met:
Secure Key_management Infrastructure (SKI) must be available on the NIS master server.
The fnsypd daemon must be running on the NIS master server. This daemon must be started by someone with super user privileges.
A client user or machine is only allowed to update its own context.
The client must be authorized to perform the requested update.
SKI does not support 64-bit mode. Thus, NIS clients cannot update contexts in 64-bit mode.
Files refers to the naming files normally found in a machine's /etc directory. These machine-based files contain UNIX user and password information, host information, mail aliases, and so forth. They also support Solaris-specific data such as the automount maps.
Under a files-based naming system, FNS context and attribute data is stored in files. These FNS files are stored in machine's /var/fn directory. (The /var/fn directory does not have to be on each machine, it could be exported from an NFS file server.)
Under a files naming system, you use FNS commands to work with the information in FNS files.
FNS also supports federating NIS+ and NIS with DNS and X.500. This means that you can connect enterprise level namespaces with global namespaces to make the enterprise objects accessible in the global scope.
FNS currently supports the following global naming services:
DNS
X.500 (via DAP or LDAP)
FNS defines naming policies so that users and applications can depend on and use the shared namespace.
Within an enterprise, there are namespaces for organizational units, sites, hosts, users, files and services, referred to by the names orgunit, site, host, user, fs (for file system), and service. These namespaces can also be named by preceding each name with an underscore (_). For example, host and _host are considered identical.
Table 20-1 summarizes the FNS policies for enterprise-level namespaces.
Table 20-1 FNS Policy Summary
Context Type |
Subordinate Contexts |
Parent Contexts |
---|---|---|
orgunit _orgunit |
site user host fs service |
enterprise root |
site _site |
user host fs service |
enterprise root orgunit |
user _user |
service fs |
enterprise root orgunit |
host _host |
service fs |
enterprise root orgunit |
service _service |
Printer and other applications |
enterprise root orgunit site user host |
fs _fs(file system) |
(none) |
enterprise rootorgunit site user host |
The binding of an FNS orgunit is determined by the underlying naming service:
Under NIS+, an organizational unit corresponds to an NIS+ domain or subdomain. For example, assume that the NIS+ root domain is doc.com. and sales is a subdomain of doc.com. Then, the FNS names org/sales.doc.com. and org/sales both refer to the organizational unit corresponding to the NIS+ domain sales.doc.com. (Note the trailing dot in sales.doc.com.which is required for fully qualified NIS+ names.)
Under NIS, an organizational unit is the NIS domain which is always identified by the FNS name org// or org/domainname where domainname is a fully qualified domain name such as doc.com.. Under NIS, there is no hierarchy in organizational unit names.
Under a files-based naming system, the organizational unit is the system which is always identified by the FNS name org//.
The types of objects that may be named relative to an organizational unit name are: user, host, service, fs, and site. For example:
org/sales/site/conference1.bldg-6 names a conference room conference1 located in building #6 of the site associated with the organizational unit sales. In this example, if org/sales corresponds to sales.doc.com., another way to name this object would be: org/sales.doc.com./site/conference1.bldg-6 (note the trailing dot in sales.doc.com.)
org/finance/user/mjones names a user mjones in the organizational unit finance.
org/finance/host/inmail names a machine inmail belonging to the organizational unit finance.
org/accounts.finance/fs/pub/reports/FY92-124 names a file pub/reports/FY92-124 belonging to the organizational unit accounts.finance.
org/accounts.finance/service/calendar names the calendar service of the organizational unit accounts.finance. This might manage the meeting schedules of the organizational unit.
Site names are created as needed. The types of objects that may be named relative to a site name are: user, host, service and fs. For example:
site/alameda/user/mjones names a user mjones at the site alameda.
site/alameda/host/sirius names a machine sirius at the site alameda.
site/alameda/service/printer/Sparc-2 names the printer Sparc-2 at the site alameda.
site/alameda/fs/usr/dist names a file directory usr/dist available in the site alameda.
User names correspond to names in the corresponding passwd table in NIS+, the passwd map in NIS, or the /etc/passwd file under files. A user's file context is obtained from his or her passwd entry.
The types of objects that may be named relative to a user name are: service, and fs. For example:
user/chou/service/fax names the fax service of the user chou.
user/esperanza/fs/projects/conf96.doc names the file conf96.doc in the projects subdirectory of the user esperanza's file system.
Host names correspond to names in the corresponding hosts table in NIS+, the hosts map in NIS, or the /etc/hosts file under files. The host's file context corresponds to the files systems exported by the host.
The types of objects that may be named relative to a host name are: service, and fs. For example:
host/smtp-1/service/mailbox names the mailbox service associated with the machine smtp-1.
host/deneb/fs/etc/.cshrc names the file .cshrc in the /etc directory on the host deneb.
Service names correspond to, and are determined by, service applications. The service context must be named relative to an organization, user, host, or site context. For example:
org//service/printer names the organization's printer service.
host/deneb/service/printer names the printer service associated with the machine deneb.
host/deneb/service/printer/Sparc-2 names the printer associated with the machine deneb.
user/charlie/service/calendar names the user charlie's calendar service.
site/conf_pine.bldg-7.alameda/service/calendar names the calendar service for the conf_pine conference room in Building 7 at the Alameda site.
File system names correspond to file names. For example:
host/altair/fs/etc/.login names the .login file on the machine altair.
user/prasad/fs/projects/96draft.doc names the file 96draft.doc in the user prasad's projects directory.
To begin using FNS with your underlying name service, you run the fncreate command.
The fncreate command recognizes the underlying naming service in which FNS contexts are to be created (such as, NIS+, NIS, or files). To specify a specific naming service, you must run the fnselect command as explained in "Designating a Non-Default Naming Service"..
By default:
If fncreate is executed on a machine that is an NIS+ client or server, the FNS namespace will be set up in NIS+. (See Solaris Naming Setup and Configuration Guide if you want or need to designate some other machine as an FNS NIS+ master server.)
If the machine is an NIS client, the namespace will be set up in NIS.
If the machine is neither, the namespace will be set up in the machine's /var/fn directory. When your underlying naming system is files-based, the common practice is to create /var/fn by running fncreate on each machine. It is possible however to create /var/fn on one machine and export it by NFS to be mounted by other clients.
You can also explicitly specify a non-default target naming service by using the fnselect command. For example the following command selects the target naming service to be NIS.
# fnselect nis |
Once the naming service has been selected either using the default policy or explicitly via fnselect, you can execute the following command to create the FNS namespace:
# fncreate -t org org// |
This creates all the necessary contexts for users and hosts in the corresponding naming service.
When your primary enterprise-level naming service is NIS+, take into account the following points.
The command syntax shown above creates the FNS namespace for the root NIS+ domain. To specify a domain other than the root, add the domain name between the double slashes, as in:
# fncreate -t org org/sales.doc.com./ |
Note the trailing dot after the fully qualified sales.doc.com. domain name.
The fncreate commands creates NIS+ tables and directories in the ctx_dir directory. The ctx_dir directory object resides at the same level as the NIS+ groups_dir and org_dir directory objects of the domain.
With a large domain, the additional space required on the NIS+ server could be substantial and in a large installation performance might be improved by using separate servers for FNS and the standard NIS+ tables. See Solaris Naming Setup and Configuration Guide for information on how to use separate servers for FNS and NIS+.
In a large, or mission-critical domain, FNS service should be replicated. See Solaris Naming Setup and Configuration Guide for information on how to replicate FNS service.
The user who runs fncreate and other FNS commands is expected to have the necessary NIS+ credentials.
The environment variable NIS_GROUP
specifies the group owner for the NIS+ objects created by fncreate. In order to facilitate administration of the NIS+ objects, NIS_GROUP
should be set to the name of the NIS+ group responsible for FNS administration for that domain prior to executing fncreate and other FNS commands.
Changes to NIS+ related properties, including default access control rights, could be effected using NIS+ administration tools and interfaces after the context has been created. The NIS+ object name that corresponds to an FNS composite name can be obtained using fnlookup and fnlist, described later in this document.
The fncreate command must be executed by superuser on the NIS system that will serve as the NIS master server for the FNS maps.
The NIS maps used by FNS are stored in /var/yp/domainname.
Any changes to the FNS information can only be done by the superuser on the FNS NIS master server using FNS commands.
When using fncreate with the -t org option to create your FNS namespace, the command must be executed by superuser on the machine that owns the file system on which /var is located. The files used by FNS are stored in the /var/fn directory.
Once users' contexts are created, users are allowed to modify their own contexts based on their UNIX credentials.
If exported, the file system /var/fn can be mounted by other systems to access the FNS namespace.
Once the namespace has been set up, you can browse using the following commands:
fnlist to list context contents (see "Listing Context Contents")
fnlookup to display the bindings of a composite name (see "Displaying the Bindings of a Composite Name").
fnattr to show the attributes of a composite name (see "Showing the Attributes of a Composite Name").
The fnlist command displays the names and references bound in the context of name.
fnlist [-lvA] [name] |
Option |
Description |
---|---|
name |
A composite name. Displays the names bound in the context of name |
-v |
Verbose. Displays the binding in more detail |
-l |
Also displays the bindings of the names bound in the named context |
-A |
Forces fnlist to obtain its information from the authoritative server. Under NIS and NIS+, that is the domain master server. The -A option has no effect when the primary naming service is files. |
For example:
To list names in the initial context:
% fnlist |
To list in detail all the users in the current organizational unit:
% fnlist -v user |
To list the contents of the service context for the user pug:
% fnlist user/pug/service |
To list names and bindings from the authoritative server:
% fnlist -l -A |
The fnlookup command shows the binding of the given composite name.
fnlookup [-vAL] [name] |
Option |
Description |
---|---|
name |
The name of a context. Displays the binding and XFN link of name |
-v |
Verbose. Displays the binding in more detail |
-L |
Also displays the XFN link that the name is bound to |
-A |
Forces fnlist to obtain its information from the authoritative server. Under NIS and NIS+, that is the domain master server. The -A option has no effect when the primary naming service is files-based. |
For example: to display the binding of user/ana/service/printer:
# fnlookup user/ana/service/printer |
The fnattr command displays (and updates) the attributes of the given composite name.
For example, to search for the attributes associated with a user named ada:
# fnattr user/ada |
To search for the attributes associated with a printer named laser-9:
# fnattr thisorgunit/service/printer/laser-9 |
See "Working With Attributes" for more details.
The fnsearch command displays the names and, optionally, the attributes and references of objects bound at or below a composite name whose attributes satisfy the given search criteria.
For example:
To list the users and their attributes who have an attribute called realname:
% fnsearch user realname |
To list the users with the attribute realname whose value is Ravi Chattha:
% fnsearch user "realname == 'Ravi Chattha'" |
The fnsearch command uses the common Boolean operators. Note the use of double and single quotes and double equals sign in the above example.
Once the namespace has been set up, you can add, delete, and modify elements using the following commands:
fnbind to bind new references to a composite name (see "Binding a Reference to a Composite Name").
fnunbind to remove bindings (see "Removing Bindings").
fncreate to create new organization, user, host, site, and service contexts (see "Creating New Contexts").
fncreate_fs to create new file system contexts (see "Creating File Contexts").
fncreate_printer to create new printer contexts (see "Creating Printer Contexts").
fndestroy to destroy contexts (see "Destroying Contexts").
fnattr to display, create, modify, and remove attributes (see "Working With Attributes").
fncopy to copy FNS contexts and attributes from one naming service to another (see "Copying and Converting FNS Contexts").
FNS System administration varies according to the underlying naming service:
NIS+. Under NIS+, FNS system administration tasks can only be performed by those with authorization to do so. The usual method of granting system administration privileges is to create an NIS+ group and assign that group the necessary privileges for that domain. Any member of the group can then perform system administration functions.
NIS. Under NIS, FNS administration tasks must be performed by root on the NIS master server.
Files. Under a files-based naming system, FNS administration tasks must be performed by someone with root access to the /var/fn directory.
The ability of users to make changes to their own user sub-contexts varies according to the underlying naming service:
NIS+. Under NIS+, a user's context (and associated sub-contexts) are owned by them. When logged in as an NIS+ principle, users who have the appropriate credentials and privileges can make changes to their own context using the fncreate, fnbind, fnunbind, and similar commands.
NIS. Under NIS, users cannot make any changes to any FNS data. Only those with root access on the NIS master server can change FNS data.
Files. Under a files-based naming system, users own their own contexts. Standard UNIX access controls apply to FNS files.
The fnbind command is used to bind an existing reference (name) to a new composite name.
fnbind -r [-s][-v][-L] name [-O|-U] newname reftype addrtype [-c|-x] address |
Option |
Description |
---|---|
name |
The existing composite name |
newname |
The composite name of the new binding |
addrtype |
Address type to use. Applications-specific such as onc_cal_str. |
address |
Address contents to use. For example, tsvi@altair. |
reftype |
Reference type to use. Applications-specific such as one_calendar. |
-s |
Bind to newname even if it is already bound. This replaces the previous binding of newname. Without -s, fnbind fails if newname is already bound. |
-v |
Display the reference that will be bound to newname. |
-L |
Create an XFN link using oldname and bind it to newname. |
-r |
Bind newname to the reference constructed by the command line arguments. |
-c |
Store address contents in the form as entered, do not use XDR-encoding. |
-x |
Convert address to a hexadecimal string without converting it to XDR-encoding. |
-O |
The identifier format is FN_ID_ISO_OID_STRING, an ASN.1 dot-separated integer list string. |
-U |
The identifier format is FN_ID_DCE_UUID, a DCE UUID in string form. |
For example:
To add a calendar binding for the user jamal:
# fnbind -r user/jamal/service/calendar onc_calendar onc_cal_str jamal@cygnus |
To replace the existing binding of org//service/Sparc-4 with that of org//service/printer:
# fnbind -s org//service/printer org//service/Sparc-4 |
To copy the reference site/bldg-5/service/printer to user/ando/service/printer:
# fnbind site/bldg-5/service/printer user/ando/service/printer |
To bind the reference site/bldg-5/service/printer to user/ando/service/printer using a symbolic link:
# fnbind -L site/bldg-5/service/printer user/ando/service/printer |
To bind the name thisens/service/calendar to the address staff@altair, when staff@altair is a reference of the type onc_cal and an address of the type onc_cal_str:
# fnbind -r thisens/service/calendar onc_calendar onc_cal_str staff@altair |
To bind newname to the reference constructed by its command line address
# fnbind -r [-sv] newname [-O|-U] reftype {[-O|-U] addrtype [-c|-x] address} |
The fnunbind name command is used to remove bindings.
For example: to remove the binding for user/jsmith/service/calendar:
# fnunbind user/jsmith/service/calendar |
The fncreate command is used to create contexts.
fncreate -t context [-f file] [-o] [-r reference] [-s] [-v] [-D] name |
Option |
Description |
---|---|
-t context |
Create context of type context. Context types can be: org, hostname, host, username, user, service, fs, site, nsid, and generic. |
-f file |
Use an input file to list users and hosts for whom to create contexts. |
-r reference |
Type of reference. The -r reference option can only be used with -t generic. |
name |
A composite name |
-o |
Create only the context identified by name. |
-s |
Overwrite (supersede) any existing binding. If -s is not used, fncreate will fail if name is already bound. |
-D |
Display information about each context and corresponding tables, directories, and files as it is created. |
-v |
Verbose. Display information about each context as it is displayed. |
For example:
To create a context and subcontexts for the root organization:
# fncreate -t org org// |
To create a context, and subcontexts, for the host deneb:
# fncreate -t host host/deneb |
To create a context, service and file subcontexts, and then add a calendar binding for the user sisulu:
# fncreate -t user user/sisulu # fnbind -r user/sisulu onc_calendar onc_cal_str sisulu@deneb |
To create a site context for the sales organization:
# fncreate -t site org/sales/site/ |
The site context supports a hierarchal namespace, with dot-separated right-to-left names, which allows sites to be partitioned by their geographical coverage relationships. For example, to create a site context alameda and a site subcontext bldg-6.alameda for it:
# fncreate -t site org/sales/site/alameda # fncreate -t site org/sales/site/bldg-6.alameda |
The fncreate_fs command creates file contexts for organizations and sites with the description of the binding entered from the command line.
fncreate_fs [-r] [-v] name [options] [mount] |
The fncreate_fs command creates file contexts for organizations and sites with the description of the bindings supplied by an input file.
fncreate_fs [-r] [-v] -f file name |
Option |
Description |
---|---|
name |
The name of the file context |
options |
Mount options |
mount |
Mount location |
-f file |
Input file |
-v |
Verbose. Displays information about the contexts being created |
-r |
Replace the bindings in the context name with those specified in the input. |
For example:
To create a file system context named data for the sales organization bound to the /export/data path of an NFS server named server4.
# fncreate_fs org/sales/fs/data server4:/export/data |
To create a hierarchy of file system contexts for the sales organization named buyers and buyers/orders mounted on two different servers:
# fncreate_fs org/sales/fs/buyers server2:/export/buyers # fncreate_fs org/sales/fs/buyers/orders server3:/export/orders |
To create a file system context named leads for the sales organization bound to a server and path specified by an input file named input_a:
# fncreate_fs -f input_a org/sales/fs/leads |
(See the fncreate_fs man page for information on input file format.)
The fncreate_printer command creates printer contexts for organizations, users, hosts and site contexts. The printer context is created under the service context of the respective composite name.
fncreate_printer [-vs] name printer [prntaddr] |
fncreate_printer [-vs] [-f [file]] name |
Option |
Description |
---|---|
name |
The name of the org, host, user, or site of the printer |
printer |
The name of the printer |
prntaddr |
The printer address in the form <addresstype>=<address> |
-f file |
Use the named file as input for a list of printers to be created. The input file is in the format of the /etc/printers.conf file. If neither a printer name nor a -f file is specified, fncreate_printer uses the /etc/printer.conf file on the machine where fncreate_printer is run as a default input file. |
-s |
Replace an existing address with the same address-type. |
-v |
Verbose. Displays the binding in more detail |
For example:
To create printers for the sales organization based on the printers listed in the /etc/printers.conf file of the machine on which fncreate_printer is run:
# fncreate_printer -s org/sales/ |
Assume that the machine altair is the server for a printer named Sparc-5. To create a printer named invoices for the user nguyen that is actually the Sparc-5 printer:
# fncreate_printer user/nguyen invoices bsdaddr=altair,Sparc-5 |
It is also possible to organize printers hierarchically. For example, the fncreate_printer command can create printer contexts for the printers, color, color/inkjet and color/Sparc with the resulting contexts:
org/doc.com/service/printer/color org/doc.com/service/printer/color/inkjet org/doc.com/service/printer/color/Sparc |
To create the above contexts, you would run:
# fncreate_printer org/doc.com color bsdaddr=colorful,color # fncreate_printer org/doc.com color/inkjet bsdaddr=colorjet,inkjet # fncreate_printer org/doc.com color/Sparc bsdaddr=colorprt,Sparc |
The fndestroy command is used to destroy empty contexts.
For example, to destroy the service context of the user patel:
# fndestroy user/patel/service |
The fnattr command can be used to add, delete or modify attributes associated with a name. You can make modifications one at a time, or batch several within the same command.
fnattr [-l] name to list attributes for name.
fnattr name -a-s -U -O attrib values to add an attribute
fnattr name -m -O -U attrib oldvalue newvalue to modify an attribute
fnattr name -d -O | -U [values attrib] to destroy an attribute
Option |
Description |
---|---|
name |
The composite name |
attrib |
The identifier of an attribute |
values |
One or more attribute values |
oldvalue |
An attribute value to be replaced by a new value |
newvalue |
The attribute value that replaces an old value |
-a |
Add an attribute |
-d |
Destroy an attribute |
-l |
List attributes |
-m |
Modify an attribute |
-s |
Replace all old attribute values with the new values for the attribute specified. |
-O |
The identifier format is FN_ID_ISO_OID_STRING, an ASN.1 dot-separated integer list string. |
-U |
The identifier format is FN_ID_DCE_UUID, a DCE UUID in string form. |
For example:
To show all of the attributes associated with the user name rosa:
# fnattr user/rosa |
To display the size attribute associated with the user uri:
# fnattr user/uri/ size |
For a user named devlin, to add an attribute named shoesize with a value of small, delete the hatsize attribute, and change the dresssize attribute value from 12 to 8:
# fnattr user/devlin -a shoesize small -d hatsize -m dresssize 12 8 |
You can federate NIS+ or NIS to a global naming service like DNS and X.500.
To federate an NIS+ or NIS namespace under DNS or X.500, you first need to obtain the root reference for the NIS+ hierarchy or NIS domain.
From the point of view of the global name service, the root reference is known as the next naming system reference because it refers to the next naming system beneath the DNS domain or X.500 entry. To federate NIS+ or NIS with a global name service, you add the root reference information to that global service.
Once you have added the root reference information to the global service, clients outside of your NIS+ hierarchy or NIS domain can access and perform operations on the contexts in the NIS+ hierarchy or NIS domain. Foreign NIS+ clients access the hierarchy as unauthenticated NIS+ clients.
For example:
If NIS+ is federated underneath the DNS domain doc.com., you can now list the root of the NIS+ enterprise using the command
# fnlist .../doc.com/ |
If NIS+ is federated underneath the X.500 entry /c=us/o=doc, you can list the root of the NIS+ enterprise using the command:
# fnlist .../c=us/o=doc/ |
Note the mandatory trailing slash in both examples.
The fncopy command can be used to copy or convert an FNS context and attributes to a new FNS context.
By using the -i and -o options, you can copy FNS contexts based on one underlying enterprise-level name service to a context based on a different underlying name service. For example, if you have an FNS installation running on top of NIS, and you upgrade your NIS service to NIS+, you can use fncopy to create a new context using NIS+.
Note that:
If the new FNS context that you are copying an old context to already exists for the target name service, only new contexts and bindings are copied. The contexts are not over-written or changed
fncopy does not follow links, but copies the FNS link bound to a name to the new context namespace.
Option |
Description |
---|---|
-i oldservice |
The old (input) underlying enterprise-level name service. For example, -i nis specifies that the old service is NIS. Allowed values are files, nis, nisplus. |
-o newservice |
The new (output) underlying enterprise-level name. For example, o nisplus specifies that the new service is NIS+. Allowed values are files, nis, nisplus. |
-f filename |
A text file listing FNS contexts to be copied. In the absence of the -i and -o options, contexts must be identifies using global names. |
oldcontext |
The name of the context being copied |
newcontext |
The name of the context being created or copied to. |
For example, to copy the doc.com printer contexts (and sub-contexts) and bindings to orgunit/east/doc.com:
# fncopy .../doc.com/service/printer .../doc.com/orgunit/east/service/printer |
To copy the NIS FNS users' contexts specified in the file user_list to a NIS+ FNS users' context of the orgunit west/doc.com:
# fncopy -i nis -o nisplus -f /etc/user_list thisorgunit/user org/doc.com/user |
The programming examples in this section shows the usage of XFN APIs to perform the following operations:
The example below shows XFN operations to list a context.
#include <stdio.h> #include <xfn/xfn.h> #include <string.h> #include <stdlib.h> /* This routine returns the list of names bound under the given context (ctx_name). Examples of ctx_name are "user", "thisorgunit/service", host/alto/service, user/jsmit/service/calendar, etc., */ typedef struct fns_listing { char *name; struct fns_listing *next; } fns_listing; fns_listing * fns_list_names(const char *ctx_name) { FN_status_t *status; FN_ctx_t *initial_context; FN_composite_name_t *context_name; FN_namelist_t *name_list; FN_string_t *name; unsigned int stat; fns_listing *head = 0, *current, *prev; int no_names = 0; status = fn_status_create(); /* Obtain the initial context */ initial_context = fn_ctx_handle_from_initial(0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain intial context\n"); return (0); } context_name = fn_composite_name_from_str((unsigned char *) ctx_name); /* FNS call to list names */ name_list = fn_ctx_list_names(initial_context, context_name, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to list names\n"); return (0); } /* Obtain the names individually */ while (name = fn_namelist_next(name_list, status)) { no_names++; current = (fns_listing *) malloc(sizeof(fns_listing)); current->name = (char *) malloc(strlen((char *) fn_string_str(name, &stat)) + 1); strcpy(current->name, (char *) fn_string_str(name, &stat)); current->next = 0; if (head) { prev->next = current; prev = current; } else { head = current; prev = current; } fn_string_destroy(name); } fn_namelist_destroy(name_list); fn_status_destroy(status); fn_ctx_destroy(initial_context); return (head); |
Example 20-1 shows how to create a binding.
#include <stdio.h> #include <xfn/xfn.h> #include <string.h> /* This routine creates a binding with a name provided by "name" and having a reference type "reference_type" and address type "address_type". An example of using the function could be: fns_create_bindings( "user/jsmith/service/calendar", "onc_calendar", "onc_cal_str", "jsmith&calserver"); */ int fns_create_bindings( char *name, char *reference_type, char *address_type, char *data) { int return_status; FN_composite_name_t *binding_name; FN_identifier_t ref_id, addr_id; FN_status_t *status; FN_ref_t *reference; FN_ref_addr_t *address; FN_ctx_t *initial_context; /* Obtain the initial context */ status = fn_status_create(); initial_context = fn_ctx_handle_from_initial(0, status); /* Check status for any error messages */ if ((return_status = fn_status_code(status)) != FN_SUCCESS) { fprintf(stderr, "Unable to obtain the initial context\n"); return (return_status); } /* Get the composite name for the printer name */ binding_name = fn_composite_name_from_str((unsigned char *) name); /* Construct the Address */ addr_id.format = FN_ID_STRING; addr_id.length = strlen(address_type); addr_id.contents = (void *) address_type; address = fn_ref_addr_create(&addr_id, strlen(data), (const void *) data); /* Construct the Reference */ ref_id.format = FN_ID_STRING; ref_id.length = strlen(reference_type); ref_id.contents = (void *) reference_type; reference = fn_ref_create(&ref_id); /* Add Address to the Reference */ fn_ref_append_addr(reference, address); /* Create a binding */ fn_ctx_bind(initial_context, binding_name, reference, 0, status); /* Check the error status and return */ return_status = fn_status_code(status); fn_composite_name_destroy(binding_name); fn_ref_addr_destroy(address); fn_ref_destroy(reference); fn_ctx_destroy(initial_context); return (return_status); } |
The examples below show techniques to list and work with attributes of an object.
The example below shows how to list the attributes of an object.
#include <stdio.h> #include <xfn/xfn.h> /* This routine prints all the attributes associated with the named object to the standard output. Examples of using the function: fns_attr_list("user/jsmith"); fns_attr_list("thisorgunit/service/printer/color"); */ void fns_attr_list(const char *name) { FN_composite_name_t *name_comp; const FN_identifier_t *identifier; FN_attribute_t *attribute; const FN_attrvalue_t *values; char *id, *val; FN_multigetlist_t *attrset; void *ip; FN_status_t *status; FN_ctx_t *initial_context; name_comp = fn_composite_name_from_str((unsigned char *) name); status = fn_status_create(); /* Obtain the initial context */ initial_context = fn_ctx_handle_from_initial(0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain intial context\n"); return; } /* Obtain all the attributes */ attrset = fn_attr_multi_get(initial_context, name_comp, 0, 0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain attributes\n"); return; } /* List all attributes */ while (attribute = fn_multigetlist_next(attrset, status)) { identifier = fn_attribute_identifier(attribute); switch(identifier->format) { case FN_ID_STRING: id = (char *) malloc(identifier->length + 1); memcpy(id, identifier->contents, identifier->length); id[identifier->length] = '\0'; printf("Attribute Identifier: %s", id); free(id); break; default: printf("Attribute of non-string format\n\n"); continue; } for (values = fn_attribute_first(attribute, &ip); values != NULL; values = fn_attribute_next(attribute, &ip)) { val = (char *) malloc(values->length + 1); memcpy(val, values->contents, values->length); val[values->length] = '\0'; printf("Value: %s", val); free(val); } fn_attribute_destroy(attribute); printf("\n"); } fn_multigetlist_destroy(attrset); fn_ctx_destroy(initial_context); fn_status_destroy(status); fn_composite_name_destroy(name_comp); } |
The example below shows how to add, delete, or modify an object's attributes.
#include <stdio.h> #include <xfn/xfn.h> /* This routine modifies an attribute associated with the named object. The modify operation supported are: FN_ATTR_OP_ADD FN_ATTR_OP_ADD_EXCLUSIVE FN_ATTR_OP_REMOVE FN_ATTR_OP_ADD_VALUES FN_ATTR_OP_REMOVE_VALUES The function assumes the attribute values to be strings. Examples of using the function: The following function add an attribute of identifier "realname" with value "James Smith" to the user object "user/jsmith". fns_attr_modify( "user/jsmith", "realname", "James Smith", FN_ATTR_OP_ADD); The following function removes an attribute of identifier "location" from the printer object "thisorgunit/service/printer/color". fns_attr_modify( "thisorgunit/service/printer/color", "location", NULL, FN_ATTR_OP_REMOVE); */ static const char *attr_id_syntax = "fn_attr_syntax_ascii"; void fns_attr_modify(const char *name, const char *attr_id, const char *attr_value, unsigned int operation) { FN_composite_name_t *name_comp; FN_identifier_t identifier, syntax; FN_attrvalue_t *values; FN_attribute_t *attribute; FN_status_t *status; FN_ctx_t *initial_context; name_comp = fn_composite_name_from_str((unsigned char *) name); status = fn_status_create(); /* Obtain the initial context */ initial_context = fn_ctx_handle_from_initial(0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain intial context\n"); return; } /* Create the attribute to be added */ /* First, the identifier */ identifier.format = FN_ID_STRING; identifier.length = strlen(attr_id); identifier.contents = (void *) strdup(attr_id); /* Second, the syntax */ syntax.format = FN_ID_STRING; syntax.length = strlen(attr_id_syntax); syntax.contents = (void *) strdup(attr_id_syntax); /* Third, the attribute value */ if (attr_value) { values = (FN_attrvalue_t *) malloc(sizeof(FN_attrvalue_t)); values->length = strlen(attr_value); values->contents = (void *) strdup(attr_value); } else values = NULL; /* Fourth, create the attribute */ attribute = fn_attribute_create(&identifier, &syntax); /*Fifth, add the attribute value */ if (values) fn_attribute_add(attribute, values, 0); /* Perform the XFN operation */ fn_attr_modify(initial_context, name_comp, operation, attribute, 0, status); if (!fn_status_is_success(status)) fprintf(stderr, "Unable to perform attribute operation\n"); fn_ctx_destroy(initial_context); fn_status_destroy(status); fn_composite_name_destroy(name_comp); fn_attibute_destroy(attribute); free(identifier.contents); free(syntax.contents); if (values) { free(values->contents); free(values); ] ] |
The example below shows how to search for objects in a context with a specific attribute identifier and value.
#include <stdio.h> #include <xfn/xfn.h> #include <string.h> #include <stdlib.h> /* This routine searchs for objects in a context which has the specified attribute identifier and value. */ typedef struct fns_search_results { char *name; struct fns_search_results *next; } fns_search_results; static const char *attr_id_syntax = "fn_attr_syntax_ascii"; fns_search_results * fns_attr_search(const char *name, const char *attr_id, const char *attr_value) { FN_status_t *status; FN_ctx_t *initial_context; FN_composite_name_t *context_name; FN_searchlist_t *search_list; FN_string_t *search_name; FN_attribute_t *attribute; FN_attrset_t *attrset; FN_identifier_t identifier, syntax; FN_attrvalue_t *values; unsigned stat; fns_search_results *head = 0, *current, *prev; int no_names = 0; context_name = fn_composite_name_from_str((unsigned char *) name); status = fn_status_create(); initial_context = fn_ctx_handle_from_initial(0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to obtain intial context\n"); return (0); } /* Construnct the attrset with attributes to be searched */ /* First, the identifier */ identifier.format = FN_ID_STRING; identifier.length = strlen(attr_id); identifier.contents = (void *) strdup(attr_id); /* Second, the syntax */ syntax.format = FN_ID_STRING; syntax.length = strlen(attr_id_syntax); syntax.contents = (void *) strdup(attr_id_syntax); /* Third, the attribute value */ values = (FN_attrvalue_t *) malloc(sizeof(FN_attrvalue_t)); values->length = strlen(attr_value); values->contents = (void *) strdup(attr_value); /* Fourth, create the attribute */ attribute = fn_attribute_create(&identifier, &syntax); /* Fifth, add the attribute value */ fn_attribute_add(attribute, values, 0); /* Sixth, create attrset, and add the attribute */ attrset = fn_attrset_create(); fn_attrset_add(attrset, attribute, 0); search_list = prelim_fn_attr_search(initial_context, context_name, attrset, 0, 0, status); if (!fn_status_is_success(status)) { fprintf(stderr, "Unable to list names\n"); return (0); } while (search_name = prelim_fn_searchlist_next(search_list, 0, 0, status)) { no_names++; current = (fns_search_results *) malloc(sizeof(fns_search_results)); current->name = (char *) malloc(strlen((char *) fn_string_str(search_name, &stat)) + 1); strcpy(current->name, (char *) fn_string_str(search_name, &stat)); current->next = 0; if (head) { prev->next = current; prev = current; } else { head = current; prev = current; } fn_string_destroy(search_name); } fn_searchlist_destroy(search_list); fn_status_destroy(status); fn_ctx_destroy(initial_context); fn_attrset_destroy(attrset); fn_attribute_destroy(attribute); free(identifier.contents); free(syntax.contents); free(values->contents); free(values); return (head); } |