PreviousNext

The sample_resolve_by_name Routine

The sample_resolve_by_name( ) routine derives the ACL UUID of an object from its name.

/******
*
* sample_resolve_by_name -- take the name of an object, and return the
* UUID of the object's ACL.
*
* The address of this function is passed (via the call to
* server_acl_mgr_setup()) to the dce_acl_register_object_type() call. So
* it gets implicitly called anytime someone tries to retrieve the ACL of
* an object managed by the ACL manager we've set up.
*
*
* Basically, the most a server needs is one resolve-by-name routine and
* one resolve-by-UUID routine; the former gets you the desired object's
* UUID; and the latter then will get you the object data itself (the way
* this works can be seen in the body of this routine below). In most
* cases, these routines will share the same name and UUID databases; if
* they don't, the resolver_arg can be used to point to the correct other
* database. Typically, the only difference between the managers is that
* they use different print strings.
*
*
* For the official statement of the signature of a dce_acl_resolve_func_t,
* see the dce_acl_resolve_by_uuid() reference page; that routine has the same
* type.
*
*
*******/

dce_acl_resolve_func_t sample_resolve_by_name(
handle_t h, /* Client binding handle passed into the */
/* server stub. sec_acl_bind() is used to */
/* create this handle. */
sec_acl_component_name_t name, /* The object whose ACL's UUID we want. */
sec_acl_type_t sec_acl_type, /* The type of ACL whose UUID we want. */
uuid_t *manager_type, /* The object's manager type. */
/* NOTE that this parameter isn't used */
/* below. */
boolean32 writing, /* "This parameter is ignored in OSF's */
/* implementation" (from the reference page*/
/* for dce_acl_resolve_by_uuid()). */
void *resolver_arg, /* This is the app-defined argument passed */
/* to dce_acl_register_object_type(); it */
/* should be a handle for a backing store */
/* indexed by UUID. Note that it isn't */
/* used here though. */
uuid_t *acl_uuid, /* To return ACL's UUID in. */
error_status_t *st /* To return status in. */
)
{
uuid_t u, *up; /* To hold the retrieved object UUID, and to */
/* take a pointer to it. */
unsigned_char_t *uuid_string;
sec_acl_t retrieved_acl;

/* The definition of the following is in the sample.idl file. */
/* */
/* See the "Examples" section in the dce_db_open() ref page, */
/* where the skeleton IDL interface for a server's backing */
/* store is given. The data type definition (which is what */
/* sample_data_t is) is there prescribed as consisting of a */
/* dce_db_header_t, plus whatever server-specific data is */
/* quired, all in a single structure. */
/* */
/* Essentially it's a dce_db_header_t structure (with an */
/* application-defined message string tacked on); this is */
/* the object header data structure that is returned, such as, */
/* by dce_db_header_fetch(); in other words, this is the */
/* thingie that actually contains the data "in" an object */
/* held in an object store. */
sample_data_t dataheader;

*st = error_status_ok;

/* Check for nonexistence of object name... */
if (!name || !*name)
{

dce_svc_printf(CANNOT_RESOLVE_NAME_MSG);
return;
}

/* Get the object's UUID, which will be the key that we will use to */
/* fetch this particular object's data in the call following this */
/* one... */
dce_db_fetch_by_name(db_name, (char *)name, /* (void *) */ &u, st);

up = &u; /* ...take the pointer to the key. */

/* Using the UUID "key" that we just retrieved, get the dataheader */
/* for the desired object (note that the data that one retrieves */
/* with this routine can be anything; it depends on what we are */
/* using the backing store for)... */
dce_db_fetch_by_uuid(db_object, up, /* (void *) */ &dataheader, st);

/* Now, depending on the kind of ACL we're hunting for (that is */
/* object, container, etc.), extract its UUID from the object's */
/* header structure... */
switch (sec_acl_type)
{
case 1:
*acl_uuid = dataheader.s_hdr.tagged_union.h.def_object_acl;
break;
case 2:
*acl_uuid = dataheader.s_hdr.tagged_union.h.def_container_acl;
break;
default:
*acl_uuid = dataheader.s_hdr.tagged_union.h.acl_uuid;
}

/* Here it might be interesting to try retrieving the ACL itself, */
/* and e.g seeing what its manager type is... */
dce_db_fetch_by_uuid(db_acl,
acl_uuid,
&retrieved_acl,
st);

/* We are handling two ACL managers through this function, so we */
/* have to make sure that we've extracted from the single ACL */
/* database the correct ACL: that is, one whose manager type UUID is */
/* identical to the manager_type parameter we were passed: this is */
/* the manager whose ACL the runtime is trying to bind to. So... */
if ((manager_type != NULL) &&
(!uuid_equal(manager_type, &(retrieved_acl.sec_acl_manager_type), st)))
{
/* Return a bad status... */
*st = acl_s_bad_manager_type;
/* And no ACL UUID... */
acl_uuid = NULL;
return(0);
}

}