xref: /onnv-gate/usr/src/cmd/isns/isnsd/door.c (revision 8971:3d79ca3c1cd9)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
22*8971Swl202157@icefox  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #include    <libxml/xmlreader.h>
277836SJohn.Forte@Sun.COM #include    <libxml/xmlwriter.h>
287836SJohn.Forte@Sun.COM #include    <libxml/tree.h>
297836SJohn.Forte@Sun.COM #include    <libxml/parser.h>
307836SJohn.Forte@Sun.COM #include    <libxml/xpath.h>
317836SJohn.Forte@Sun.COM #include    <stropts.h>
327836SJohn.Forte@Sun.COM #include    <door.h>
337836SJohn.Forte@Sun.COM #include    <errno.h>
347836SJohn.Forte@Sun.COM #include    <sys/types.h>
357836SJohn.Forte@Sun.COM #include    <unistd.h>
367836SJohn.Forte@Sun.COM #include    <pwd.h>
377836SJohn.Forte@Sun.COM #include    <auth_attr.h>
387836SJohn.Forte@Sun.COM #include    <secdb.h>
397836SJohn.Forte@Sun.COM #include    <sys/stat.h>
407836SJohn.Forte@Sun.COM #include    <fcntl.h>
417836SJohn.Forte@Sun.COM #include    <sys/stat.h>
427836SJohn.Forte@Sun.COM #include    <sys/mman.h>
437836SJohn.Forte@Sun.COM #include    <string.h>
447836SJohn.Forte@Sun.COM #include    <alloca.h>
457836SJohn.Forte@Sun.COM #include    <pthread.h>
467836SJohn.Forte@Sun.COM #include    <ucred.h>
477836SJohn.Forte@Sun.COM #include    "isns_server.h"
487836SJohn.Forte@Sun.COM #include    "admintf.h"
497836SJohn.Forte@Sun.COM #include    "isns_mgmt.h"
507836SJohn.Forte@Sun.COM #include    "isns_utils.h"
517836SJohn.Forte@Sun.COM #include    "isns_protocol.h"
527836SJohn.Forte@Sun.COM #include    "isns_log.h"
537836SJohn.Forte@Sun.COM #include    "isns_provider.h"
547836SJohn.Forte@Sun.COM 
55*8971Swl202157@icefox /* door creation flag */
56*8971Swl202157@icefox extern boolean_t door_created;
57*8971Swl202157@icefox 
587836SJohn.Forte@Sun.COM /* macro for allocating name buffers for the request */
597836SJohn.Forte@Sun.COM #define	NEW_REQARGV(old, n) (xmlChar **)realloc((xmlChar *)old, \
607836SJohn.Forte@Sun.COM 	(unsigned)(n+2) * sizeof (xmlChar *))
617836SJohn.Forte@Sun.COM 
627836SJohn.Forte@Sun.COM /* macro for allocating association pair buffers for the request */
637836SJohn.Forte@Sun.COM #define	NEW_REQPAIRARGV(old, n) (assoc_pair_t **)realloc((assoc_pair_t *)old, \
647836SJohn.Forte@Sun.COM 	(unsigned)(n+2) * sizeof (assoc_pair_t *))
657836SJohn.Forte@Sun.COM 
667836SJohn.Forte@Sun.COM /* macro for allocating DD/DD set attribute list buffers for the request */
677836SJohn.Forte@Sun.COM #define	NEW_REQATTRLISTARGV(old, n)\
687836SJohn.Forte@Sun.COM 	(object_attrlist_t **)realloc((object_attrlist_t *)old, \
697836SJohn.Forte@Sun.COM 	(unsigned)(n+2) * sizeof (object_attrlist_t *))
707836SJohn.Forte@Sun.COM 
717836SJohn.Forte@Sun.COM /* operation table */
727836SJohn.Forte@Sun.COM static op_table_entry_t op_table[] = {
737836SJohn.Forte@Sun.COM 	{GET, get_op},
747836SJohn.Forte@Sun.COM 	{GETASSOCIATED, getAssociated_op},
757836SJohn.Forte@Sun.COM 	{ENUMERATE, enumerate_op},
767836SJohn.Forte@Sun.COM 	{CREATEMODIFY, createModify_op},
777836SJohn.Forte@Sun.COM 	{DELETE, delete_op},
787836SJohn.Forte@Sun.COM 	{NULL, 0}
797836SJohn.Forte@Sun.COM };
807836SJohn.Forte@Sun.COM 
817836SJohn.Forte@Sun.COM /* object table */
827836SJohn.Forte@Sun.COM static obj_table_entry_t obj_table[] = {
837836SJohn.Forte@Sun.COM 	{NODEOBJECT, Node},
847836SJohn.Forte@Sun.COM 	{DDOBJECT, DiscoveryDomain},
857836SJohn.Forte@Sun.COM 	{DDSETOBJECT, DiscoveryDomainSet},
867836SJohn.Forte@Sun.COM 	{DDOBJECTMEMBER, DiscoveryDomainMember},
877836SJohn.Forte@Sun.COM 	{DDSETOBJECTMEMBER, DiscoveryDomainSetMember},
887836SJohn.Forte@Sun.COM 	{ISNSSERVER, ServerConfig},
897836SJohn.Forte@Sun.COM 	{NULL, 0}
907836SJohn.Forte@Sun.COM };
917836SJohn.Forte@Sun.COM 
927836SJohn.Forte@Sun.COM /*
937836SJohn.Forte@Sun.COM  * list to capture thread id and associated door return buffer
947836SJohn.Forte@Sun.COM  * the return buffer from the previous door return is freed
957836SJohn.Forte@Sun.COM  * when the same thread is invoked to take another request.
967836SJohn.Forte@Sun.COM  * While the server is running one buffer is outstanding
977836SJohn.Forte@Sun.COM  * to be freed.
987836SJohn.Forte@Sun.COM  */
997836SJohn.Forte@Sun.COM static thr_elem_t *thr_list = NULL;
1007836SJohn.Forte@Sun.COM 
1017836SJohn.Forte@Sun.COM /*
1027836SJohn.Forte@Sun.COM  * get_op_id_from_doc --
1037836SJohn.Forte@Sun.COM  *	    extracts an operation id through the given context ptr.
1047836SJohn.Forte@Sun.COM  *
1057836SJohn.Forte@Sun.COM  * ctext: context ptr for the original doc
1067836SJohn.Forte@Sun.COM  *
1077836SJohn.Forte@Sun.COM  * Returns an operation id if found or -1 otherwise.
1087836SJohn.Forte@Sun.COM  */
1097836SJohn.Forte@Sun.COM static int
get_op_id_from_doc(xmlXPathContextPtr ctext)1107836SJohn.Forte@Sun.COM get_op_id_from_doc(xmlXPathContextPtr ctext)
1117836SJohn.Forte@Sun.COM {
1127836SJohn.Forte@Sun.COM 	xmlChar expr[ISNS_MAX_LABEL_LEN + 13];
1137836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr xpath_obj = NULL;
1147836SJohn.Forte@Sun.COM 	int i;
1157836SJohn.Forte@Sun.COM 
1167836SJohn.Forte@Sun.COM 	for (i = 0; op_table[i].op_str != NULL; i++) {
1177836SJohn.Forte@Sun.COM 	    (void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
1187836SJohn.Forte@Sun.COM 		(const unsigned char *)"%s\"%s\"]", "//*[name()=",
1197836SJohn.Forte@Sun.COM 		op_table[i].op_str);
1207836SJohn.Forte@Sun.COM 	    xpath_obj = xmlXPathEvalExpression(expr, ctext);
1217836SJohn.Forte@Sun.COM 	    if ((xpath_obj) && (xpath_obj->nodesetval) &&
1227836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeNr > 0) &&
1237836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeTab)) {
1247836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "get_op_id_from_doc ",
1257836SJohn.Forte@Sun.COM 		"xpath obj->nodesetval->nodeNr: %d",
1267836SJohn.Forte@Sun.COM 		xpath_obj->nodesetval->nodeNr);
1277836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "get_op_id_from_doc", "operation: %s id: %d",
1287836SJohn.Forte@Sun.COM 		    op_table[i].op_str, op_table[i].op_id);
1297836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
1307836SJohn.Forte@Sun.COM 		return (op_table[i].op_id);
1317836SJohn.Forte@Sun.COM 	    }
1327836SJohn.Forte@Sun.COM 	    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
1337836SJohn.Forte@Sun.COM 	}
1347836SJohn.Forte@Sun.COM 
1357836SJohn.Forte@Sun.COM 	if (xpath_obj) xmlXPathFreeObject(xpath_obj);
1367836SJohn.Forte@Sun.COM 	return (-1);
1377836SJohn.Forte@Sun.COM }
1387836SJohn.Forte@Sun.COM 
1397836SJohn.Forte@Sun.COM /*
1407836SJohn.Forte@Sun.COM  * process_get_request_from_doc --
1417836SJohn.Forte@Sun.COM  *	    looks for the object through the context ptr and gets the object
1427836SJohn.Forte@Sun.COM  *	    name.  Possible object types are Node, DD, DD set and server-config.
1437836SJohn.Forte@Sun.COM  *
1447836SJohn.Forte@Sun.COM  * ctext: context ptr for the original doc to parse request info.
1457836SJohn.Forte@Sun.COM  * req: request to be filled up.
1467836SJohn.Forte@Sun.COM  *
1477836SJohn.Forte@Sun.COM  * Returns 0 if successful or an error code otherwise.
1487836SJohn.Forte@Sun.COM  */
1497836SJohn.Forte@Sun.COM static int
process_get_request_from_doc(xmlXPathContextPtr ctext,request_t * req)1507836SJohn.Forte@Sun.COM process_get_request_from_doc(xmlXPathContextPtr ctext, request_t *req)
1517836SJohn.Forte@Sun.COM {
1527836SJohn.Forte@Sun.COM 	xmlChar expr[ISNS_MAX_LABEL_LEN + 13];
1537836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr xpath_obj = NULL;
1547836SJohn.Forte@Sun.COM 	xmlNodeSetPtr r_nodes = NULL;
1557836SJohn.Forte@Sun.COM 	xmlAttrPtr attr = NULL;
1567836SJohn.Forte@Sun.COM 	int i, cnt;
1577836SJohn.Forte@Sun.COM 
1587836SJohn.Forte@Sun.COM 	int obj = 0;
1597836SJohn.Forte@Sun.COM 
1607836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "process_get_request_from_doc", "entered");
1617836SJohn.Forte@Sun.COM 	(void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
1627836SJohn.Forte@Sun.COM 	    (const unsigned char *)"%s\"%s\"]", "//*[name()=", ISNSOBJECT);
1637836SJohn.Forte@Sun.COM 	xpath_obj = xmlXPathEvalExpression(expr, ctext);
1647836SJohn.Forte@Sun.COM 	if ((xpath_obj) && (xpath_obj->nodesetval) &&
1657836SJohn.Forte@Sun.COM 	    (xpath_obj->nodesetval->nodeTab) &&
1667836SJohn.Forte@Sun.COM 	    (xpath_obj->nodesetval->nodeNr > 0) &&
1677836SJohn.Forte@Sun.COM 	    (xpath_obj->nodesetval->nodeTab[0]->children) &&
1687836SJohn.Forte@Sun.COM 	    (xpath_obj->nodesetval->nodeTab[0]->children->name)) {
1697836SJohn.Forte@Sun.COM 	    for (i = 0; obj_table[i].obj_str != NULL; i++) {
1707836SJohn.Forte@Sun.COM 		/*
1717836SJohn.Forte@Sun.COM 		 * To handle DiscoveryDomain and DiscoveryDomainSet
1727836SJohn.Forte@Sun.COM 		 * searches isnsobject instead of the object directly.
1737836SJohn.Forte@Sun.COM 		 */
1747836SJohn.Forte@Sun.COM 		if (xmlStrncmp(
1757836SJohn.Forte@Sun.COM 		    xpath_obj->nodesetval->nodeTab[0]->children->name,
1767836SJohn.Forte@Sun.COM 		    (xmlChar *)obj_table[i].obj_str, xmlStrlen(
1777836SJohn.Forte@Sun.COM 		    xpath_obj->nodesetval->nodeTab[0]->children->name))
1787836SJohn.Forte@Sun.COM 		    == 0) {
1797836SJohn.Forte@Sun.COM 			obj = obj_table[i].obj_id;
1807836SJohn.Forte@Sun.COM 			break;
1817836SJohn.Forte@Sun.COM 		}
1827836SJohn.Forte@Sun.COM 	    }
1837836SJohn.Forte@Sun.COM 	    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
1847836SJohn.Forte@Sun.COM 	}
1857836SJohn.Forte@Sun.COM 
1867836SJohn.Forte@Sun.COM 	if (obj == 0) {
1877836SJohn.Forte@Sun.COM 	    /* check the server config request. */
1887836SJohn.Forte@Sun.COM 	    (void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
1897836SJohn.Forte@Sun.COM 	    (const unsigned char *)"%s\"%s\"]", "//*[name()=", ISNSSERVER);
1907836SJohn.Forte@Sun.COM 	    xpath_obj = xmlXPathEvalExpression(expr, ctext);
1917836SJohn.Forte@Sun.COM 	    if ((xpath_obj) && (xpath_obj->nodesetval) &&
1927836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeNr > 0) &&
1937836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeTab)) {
1947836SJohn.Forte@Sun.COM 		for (i = 0; obj_table[i].obj_str != NULL; i++) {
1957836SJohn.Forte@Sun.COM 		    if (strncmp(ISNSSERVER, obj_table[i].obj_str,
1967836SJohn.Forte@Sun.COM 			strlen(ISNSSERVER)) == 0) {
1977836SJohn.Forte@Sun.COM 			obj = obj_table[i].obj_id;
1987836SJohn.Forte@Sun.COM 			break;
1997836SJohn.Forte@Sun.COM 		    }
2007836SJohn.Forte@Sun.COM 		}
2017836SJohn.Forte@Sun.COM 	    }
2027836SJohn.Forte@Sun.COM 	    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
2037836SJohn.Forte@Sun.COM 	}
2047836SJohn.Forte@Sun.COM 
2057836SJohn.Forte@Sun.COM 	if (obj == 0) {
2067836SJohn.Forte@Sun.COM 	    return (ERR_XML_VALID_OBJECT_NOT_FOUND);
2077836SJohn.Forte@Sun.COM 	}
2087836SJohn.Forte@Sun.COM 
2097836SJohn.Forte@Sun.COM 	req->op_info.obj = obj;
2107836SJohn.Forte@Sun.COM 
2117836SJohn.Forte@Sun.COM 	if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
2127836SJohn.Forte@Sun.COM 	    ISNS_MGMT_OBJECT_TYPE(obj);
2137836SJohn.Forte@Sun.COM 	}
2147836SJohn.Forte@Sun.COM 
2157836SJohn.Forte@Sun.COM 	(void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 12,
2167836SJohn.Forte@Sun.COM 	    (const unsigned char *)"%s\"%s\"]", "//*[name()=",
2177836SJohn.Forte@Sun.COM 	    obj_table[i].obj_str);
2187836SJohn.Forte@Sun.COM 	xpath_obj = xmlXPathEvalExpression(expr, ctext);
2197836SJohn.Forte@Sun.COM 	if (((xpath_obj == NULL) || (xpath_obj->nodesetval == NULL) ||
2207836SJohn.Forte@Sun.COM 	    (xpath_obj->nodesetval->nodeNr <= 0) ||
2217836SJohn.Forte@Sun.COM 	    (xpath_obj->nodesetval->nodeTab == NULL))) {
2227836SJohn.Forte@Sun.COM 	    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
2237836SJohn.Forte@Sun.COM 	    return (ERR_XML_VALID_OBJECT_NOT_FOUND);
2247836SJohn.Forte@Sun.COM 	}
2257836SJohn.Forte@Sun.COM 
2267836SJohn.Forte@Sun.COM 	switch (obj) {
2277836SJohn.Forte@Sun.COM 	    /* using the same algorithm for isns object */
2287836SJohn.Forte@Sun.COM 	    case Node:
2297836SJohn.Forte@Sun.COM 	    case DiscoveryDomain:
2307836SJohn.Forte@Sun.COM 	    case DiscoveryDomainSet:
2317836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
2327836SJohn.Forte@Sun.COM 		cnt = r_nodes->nodeNr;
2337836SJohn.Forte@Sun.COM 		req->count = 0;
2347836SJohn.Forte@Sun.COM 		req->req_data.data = (xmlChar **) malloc(sizeof (xmlChar *));
2357836SJohn.Forte@Sun.COM 		for (i = 0; i < cnt; i++) {
2367836SJohn.Forte@Sun.COM 		    attr = r_nodes->nodeTab[i]->properties;
2377836SJohn.Forte@Sun.COM 		    for (; attr != NULL; attr = attr->next) {
2387836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)NAMEATTR,
2397836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)NAMEATTR)) == 0) {
2407836SJohn.Forte@Sun.COM 				req->req_data.data =
2417836SJohn.Forte@Sun.COM 				    NEW_REQARGV(req->req_data.data, req->count);
2427836SJohn.Forte@Sun.COM 				if (req->req_data.data == (xmlChar **)NULL) {
2437836SJohn.Forte@Sun.COM 				    if (xpath_obj)
2447836SJohn.Forte@Sun.COM 					xmlXPathFreeObject(xpath_obj);
2457836SJohn.Forte@Sun.COM 				    return (ERR_MALLOC_FAILED);
2467836SJohn.Forte@Sun.COM 				}
2477836SJohn.Forte@Sun.COM 				req->req_data.data[req->count] =
2487836SJohn.Forte@Sun.COM 				    xmlNodeGetContent(attr->children);
2497836SJohn.Forte@Sun.COM 				req->req_data.data[++req->count] = NULL;
2507836SJohn.Forte@Sun.COM 			}
2517836SJohn.Forte@Sun.COM 		    }
2527836SJohn.Forte@Sun.COM 		}
2537836SJohn.Forte@Sun.COM 		break;
2547836SJohn.Forte@Sun.COM 	    case ServerConfig:
2557836SJohn.Forte@Sun.COM 		/* indication the obj type is sufficient. */
2567836SJohn.Forte@Sun.COM 		break;
2577836SJohn.Forte@Sun.COM 	    default:
2587836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
2597836SJohn.Forte@Sun.COM 		return (ERR_XML_OP_FAILED);
2607836SJohn.Forte@Sun.COM 	}
2617836SJohn.Forte@Sun.COM 
2627836SJohn.Forte@Sun.COM 	if (xpath_obj) xmlXPathFreeObject(xpath_obj);
2637836SJohn.Forte@Sun.COM 	return (0);
2647836SJohn.Forte@Sun.COM }
2657836SJohn.Forte@Sun.COM 
2667836SJohn.Forte@Sun.COM /*
2677836SJohn.Forte@Sun.COM  * process_enumerate_request_from_doc --
2687836SJohn.Forte@Sun.COM  *	    looks for the object through the context ptr and sets the
2697836SJohn.Forte@Sun.COM  *	    request with object type.
2707836SJohn.Forte@Sun.COM  *
2717836SJohn.Forte@Sun.COM  * ctext: context ptr for the original doc to parse request info.
2727836SJohn.Forte@Sun.COM  * req: request to be filled up.
2737836SJohn.Forte@Sun.COM  *
2747836SJohn.Forte@Sun.COM  * Returns 0 if successful or an error code otherwise.
2757836SJohn.Forte@Sun.COM  */
2767836SJohn.Forte@Sun.COM static int
process_enumerate_request_from_doc(xmlXPathContextPtr ctext,request_t * req)2777836SJohn.Forte@Sun.COM process_enumerate_request_from_doc(xmlXPathContextPtr ctext, request_t *req)
2787836SJohn.Forte@Sun.COM {
2797836SJohn.Forte@Sun.COM 	xmlChar expr[ISNS_MAX_LABEL_LEN + 13];
2807836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr xpath_obj = NULL;
2817836SJohn.Forte@Sun.COM 	int i;
2827836SJohn.Forte@Sun.COM 
2837836SJohn.Forte@Sun.COM 	int obj = 0;
2847836SJohn.Forte@Sun.COM 
2857836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "process_enumerate_request_from_doc", "entered");
2867836SJohn.Forte@Sun.COM 	(void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
2877836SJohn.Forte@Sun.COM 	    (const unsigned char *)"%s\"%s\"]", "//*[name()=", ISNSOBJECTTYPE);
2887836SJohn.Forte@Sun.COM 	xpath_obj = xmlXPathEvalExpression(expr, ctext);
2897836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "process_enumerate_request_from_doc",
2907836SJohn.Forte@Sun.COM 	"xpath obj->nodesetval->nodeNR: %d", xpath_obj->nodesetval->nodeNr);
2917836SJohn.Forte@Sun.COM 	if ((xpath_obj) && (xpath_obj->nodesetval) &&
2927836SJohn.Forte@Sun.COM 	    (xpath_obj->nodesetval->nodeNr > 0) &&
2937836SJohn.Forte@Sun.COM 	    (xpath_obj->nodesetval->nodeTab)) {
2947836SJohn.Forte@Sun.COM 	    for (i = 0; obj_table[i].obj_str != NULL; i++) {
2957836SJohn.Forte@Sun.COM 		if (xmlStrncmp(
2967836SJohn.Forte@Sun.COM 		    xpath_obj->nodesetval->nodeTab[0]->children->content,
2977836SJohn.Forte@Sun.COM 		    (xmlChar *)obj_table[i].obj_str, xmlStrlen((xmlChar *)
2987836SJohn.Forte@Sun.COM 		    xpath_obj->nodesetval->nodeTab[0]->children->content))
2997836SJohn.Forte@Sun.COM 		    == 0) {
3007836SJohn.Forte@Sun.COM 		    obj = obj_table[i].obj_id;
3017836SJohn.Forte@Sun.COM 		    break;
3027836SJohn.Forte@Sun.COM 		}
3037836SJohn.Forte@Sun.COM 	    }
3047836SJohn.Forte@Sun.COM 	} else {
3057836SJohn.Forte@Sun.COM 	    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
3067836SJohn.Forte@Sun.COM 	    return (ERR_XML_VALID_OBJECT_NOT_FOUND);
3077836SJohn.Forte@Sun.COM 	}
3087836SJohn.Forte@Sun.COM 
3097836SJohn.Forte@Sun.COM 	if (xpath_obj) xmlXPathFreeObject(xpath_obj);
3107836SJohn.Forte@Sun.COM 
3117836SJohn.Forte@Sun.COM 	if (obj == 0) {
3127836SJohn.Forte@Sun.COM 	    return (ERR_XML_VALID_OBJECT_NOT_FOUND);
3137836SJohn.Forte@Sun.COM 	}
3147836SJohn.Forte@Sun.COM 
3157836SJohn.Forte@Sun.COM 	req->op_info.obj = obj;
3167836SJohn.Forte@Sun.COM 
3177836SJohn.Forte@Sun.COM 	if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
3187836SJohn.Forte@Sun.COM 	    ISNS_MGMT_OBJECT_TYPE(obj);
3197836SJohn.Forte@Sun.COM 	}
3207836SJohn.Forte@Sun.COM 
3217836SJohn.Forte@Sun.COM 	return (0);
3227836SJohn.Forte@Sun.COM }
3237836SJohn.Forte@Sun.COM 
3247836SJohn.Forte@Sun.COM /*
3257836SJohn.Forte@Sun.COM  * process_getAssociated_request_from_doc --
3267836SJohn.Forte@Sun.COM  *	    first looks for association type through the contexti and then
3277836SJohn.Forte@Sun.COM  *	    find out the given object.  That will indicate the direction of
3287836SJohn.Forte@Sun.COM  *	    association, containter to member or vice versa.
3297836SJohn.Forte@Sun.COM  *	    Lastly it extract the object name form the doc that assocation
3307836SJohn.Forte@Sun.COM  *	    is requested.
3317836SJohn.Forte@Sun.COM  *
3327836SJohn.Forte@Sun.COM  * ctext: context ptr for the original doc to parse request info.
3337836SJohn.Forte@Sun.COM  * req: request to be filled up.
3347836SJohn.Forte@Sun.COM  *
3357836SJohn.Forte@Sun.COM  * Returns 0 if successful or an error code otherwise.
3367836SJohn.Forte@Sun.COM  */
3377836SJohn.Forte@Sun.COM static int
process_getAssociated_request_from_doc(xmlXPathContextPtr ctext,request_t * req)3387836SJohn.Forte@Sun.COM process_getAssociated_request_from_doc(xmlXPathContextPtr ctext, request_t *req)
3397836SJohn.Forte@Sun.COM {
3407836SJohn.Forte@Sun.COM 	xmlChar expr[ISNS_MAX_LABEL_LEN + 13];
3417836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr xpath_obj = NULL;
3427836SJohn.Forte@Sun.COM 	xmlNodeSetPtr r_nodes = NULL;
3437836SJohn.Forte@Sun.COM 	xmlAttrPtr attr = NULL;
3447836SJohn.Forte@Sun.COM 	int i, cnt, obj = 0;
3457836SJohn.Forte@Sun.COM 
3467836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "process_getAssociated_request_from_doc", "entered");
3477836SJohn.Forte@Sun.COM 	(void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
3487836SJohn.Forte@Sun.COM 	    (const unsigned char *)"%s\"%s\"]", "//*[name()=", ASSOCIATIONTYPE);
3497836SJohn.Forte@Sun.COM 	xpath_obj = xmlXPathEvalExpression(expr, ctext);
3507836SJohn.Forte@Sun.COM 	if ((xpath_obj) && (xpath_obj->nodesetval) &&
3517836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeNr > 0) &&
3527836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeTab)) {
3537836SJohn.Forte@Sun.COM 	    for (i = 0; obj_table[i].obj_str != NULL; i++) {
3547836SJohn.Forte@Sun.COM 		if (xmlStrncmp(
3557836SJohn.Forte@Sun.COM 		    xpath_obj->nodesetval->nodeTab[0]->children->content,
3567836SJohn.Forte@Sun.COM 		    (xmlChar *)obj_table[i].obj_str, xmlStrlen(
3577836SJohn.Forte@Sun.COM 		    xpath_obj->nodesetval->nodeTab[0]->children->content))
3587836SJohn.Forte@Sun.COM 		    == 0) {
3597836SJohn.Forte@Sun.COM 		    obj = obj_table[i].obj_id;
3607836SJohn.Forte@Sun.COM 		    break;
3617836SJohn.Forte@Sun.COM 		}
3627836SJohn.Forte@Sun.COM 	    }
3637836SJohn.Forte@Sun.COM 	}
3647836SJohn.Forte@Sun.COM 
3657836SJohn.Forte@Sun.COM 	if (xpath_obj) xmlXPathFreeObject(xpath_obj);
3667836SJohn.Forte@Sun.COM 
3677836SJohn.Forte@Sun.COM 	if (obj == 0) {
3687836SJohn.Forte@Sun.COM 	    return (ERR_XML_VALID_OBJECT_NOT_FOUND);
3697836SJohn.Forte@Sun.COM 	}
3707836SJohn.Forte@Sun.COM 
3717836SJohn.Forte@Sun.COM 	req->op_info.obj = obj;
3727836SJohn.Forte@Sun.COM 
3737836SJohn.Forte@Sun.COM 	if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
3747836SJohn.Forte@Sun.COM 	    ISNS_MGMT_OBJECT_TYPE(obj);
3757836SJohn.Forte@Sun.COM 	}
3767836SJohn.Forte@Sun.COM 
3777836SJohn.Forte@Sun.COM 	switch (obj) {
3787836SJohn.Forte@Sun.COM 	    /* using the same algorithm for isns object */
3797836SJohn.Forte@Sun.COM 	    case DiscoveryDomainMember:
3807836SJohn.Forte@Sun.COM 		(void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
3817836SJohn.Forte@Sun.COM 		(const unsigned char *)"%s\"%s\"]", "//*[name()=", NODEOBJECT);
3827836SJohn.Forte@Sun.COM 		xpath_obj = xmlXPathEvalExpression(expr, ctext);
3837836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
3847836SJohn.Forte@Sun.COM 		if ((xpath_obj) && (xpath_obj->nodesetval) &&
3857836SJohn.Forte@Sun.COM 		    (xpath_obj->nodesetval->nodeNr > 0) &&
3867836SJohn.Forte@Sun.COM 		    (xpath_obj->nodesetval->nodeTab)) {
3877836SJohn.Forte@Sun.COM 		    req->assoc_req = member_to_container;
3887836SJohn.Forte@Sun.COM 		} else {
3897836SJohn.Forte@Sun.COM 		    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
3907836SJohn.Forte@Sun.COM 		    (void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
3917836SJohn.Forte@Sun.COM 		    (const unsigned char *)"%s\"%s\"]", "//*[name()=",
3927836SJohn.Forte@Sun.COM 		    DDOBJECT);
3937836SJohn.Forte@Sun.COM 		    xpath_obj = xmlXPathEvalExpression(expr, ctext);
3947836SJohn.Forte@Sun.COM 		    r_nodes = xpath_obj->nodesetval;
3957836SJohn.Forte@Sun.COM 		    if ((xpath_obj) && (xpath_obj->nodesetval) &&
3967836SJohn.Forte@Sun.COM 			(xpath_obj->nodesetval->nodeNr > 0) &&
3977836SJohn.Forte@Sun.COM 			(xpath_obj->nodesetval->nodeTab)) {
3987836SJohn.Forte@Sun.COM 			req->assoc_req = container_to_member;
3997836SJohn.Forte@Sun.COM 		    } else {
4007836SJohn.Forte@Sun.COM 			if (xpath_obj) xmlXPathFreeObject(xpath_obj);
4017836SJohn.Forte@Sun.COM 			return (ERR_XML_VALID_OBJECT_NOT_FOUND);
4027836SJohn.Forte@Sun.COM 		    }
4037836SJohn.Forte@Sun.COM 		}
4047836SJohn.Forte@Sun.COM 		break;
4057836SJohn.Forte@Sun.COM 	    case DiscoveryDomainSetMember:
4067836SJohn.Forte@Sun.COM 		(void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
4077836SJohn.Forte@Sun.COM 		(const unsigned char *)"%s\"%s\"]", "//*[name()=", DDSETOBJECT);
4087836SJohn.Forte@Sun.COM 		xpath_obj = xmlXPathEvalExpression(expr, ctext);
4097836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
4107836SJohn.Forte@Sun.COM 		if ((xpath_obj) && (xpath_obj->nodesetval) &&
4117836SJohn.Forte@Sun.COM 		    (xpath_obj->nodesetval->nodeNr > 0) &&
4127836SJohn.Forte@Sun.COM 		    (xpath_obj->nodesetval->nodeTab)) {
4137836SJohn.Forte@Sun.COM 		    req->assoc_req = container_to_member;
4147836SJohn.Forte@Sun.COM 		} else {
4157836SJohn.Forte@Sun.COM 		    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
4167836SJohn.Forte@Sun.COM 		    (void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
4177836SJohn.Forte@Sun.COM 		    (const unsigned char *)"%s\"%s\"]", "//*[name()=",
4187836SJohn.Forte@Sun.COM 			DDOBJECT);
4197836SJohn.Forte@Sun.COM 		    xpath_obj = xmlXPathEvalExpression(expr, ctext);
4207836SJohn.Forte@Sun.COM 		    r_nodes = xpath_obj->nodesetval;
4217836SJohn.Forte@Sun.COM 		    if ((xpath_obj) && (xpath_obj->nodesetval) &&
4227836SJohn.Forte@Sun.COM 			(xpath_obj->nodesetval->nodeNr > 0) &&
4237836SJohn.Forte@Sun.COM 			(xpath_obj->nodesetval->nodeTab)) {
4247836SJohn.Forte@Sun.COM 			req->assoc_req = member_to_container;
4257836SJohn.Forte@Sun.COM 		    } else {
4267836SJohn.Forte@Sun.COM 			if (xpath_obj) xmlXPathFreeObject(xpath_obj);
4277836SJohn.Forte@Sun.COM 			return (ERR_XML_VALID_OBJECT_NOT_FOUND);
4287836SJohn.Forte@Sun.COM 		    }
4297836SJohn.Forte@Sun.COM 		}
4307836SJohn.Forte@Sun.COM 		break;
4317836SJohn.Forte@Sun.COM 	    default:
4327836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
4337836SJohn.Forte@Sun.COM 		return (ERR_XML_OP_FAILED);
4347836SJohn.Forte@Sun.COM 	}
4357836SJohn.Forte@Sun.COM 
4367836SJohn.Forte@Sun.COM 	/* now process the name attr */
4377836SJohn.Forte@Sun.COM 	cnt = r_nodes->nodeNr;
4387836SJohn.Forte@Sun.COM 	req->count = 0;
4397836SJohn.Forte@Sun.COM 	req->req_data.data = (xmlChar **) malloc(sizeof (xmlChar *));
4407836SJohn.Forte@Sun.COM 	/* for (i = cnt - 1; i >= 0; i--) { */
4417836SJohn.Forte@Sun.COM 	for (i = 0; i < cnt; i++) {
4427836SJohn.Forte@Sun.COM 	    attr = r_nodes->nodeTab[i]->properties;
4437836SJohn.Forte@Sun.COM 	    for (; attr != NULL; attr = attr->next) {
4447836SJohn.Forte@Sun.COM 		if (xmlStrncmp(attr->name, (xmlChar *)NAMEATTR,
4457836SJohn.Forte@Sun.COM 		    xmlStrlen((xmlChar *)NAMEATTR)) == 0) {
4467836SJohn.Forte@Sun.COM 			req->req_data.data =
4477836SJohn.Forte@Sun.COM 			    NEW_REQARGV(req->req_data.data, req->count);
4487836SJohn.Forte@Sun.COM 			if (req->req_data.data == (xmlChar **)NULL) {
4497836SJohn.Forte@Sun.COM 			    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
4507836SJohn.Forte@Sun.COM 			    return (ERR_MALLOC_FAILED);
4517836SJohn.Forte@Sun.COM 			}
4527836SJohn.Forte@Sun.COM 			req->req_data.data[req->count++] =
4537836SJohn.Forte@Sun.COM 			xmlNodeGetContent(attr->children);
4547836SJohn.Forte@Sun.COM 			req->req_data.data[req->count] = NULL;
4557836SJohn.Forte@Sun.COM 		}
4567836SJohn.Forte@Sun.COM 	    }
4577836SJohn.Forte@Sun.COM 	}
4587836SJohn.Forte@Sun.COM 
4597836SJohn.Forte@Sun.COM 	if (xpath_obj) xmlXPathFreeObject(xpath_obj);
4607836SJohn.Forte@Sun.COM 	return (0);
4617836SJohn.Forte@Sun.COM }
4627836SJohn.Forte@Sun.COM 
4637836SJohn.Forte@Sun.COM /*
4647836SJohn.Forte@Sun.COM  * process_delete_request_from_doc --
4657836SJohn.Forte@Sun.COM  *	    first looks for the object through the context ptr and sets the
4667836SJohn.Forte@Sun.COM  *	    request with additional data.
4677836SJohn.Forte@Sun.COM  *	    For DD and DD set, the name is given.
4687836SJohn.Forte@Sun.COM  *	    For DD and DD set membership, container and member pairs are given.
4697836SJohn.Forte@Sun.COM  *
4707836SJohn.Forte@Sun.COM  * ctext: context ptr for the original doc to parse request info.
4717836SJohn.Forte@Sun.COM  * req: request to be filled up.
4727836SJohn.Forte@Sun.COM  *
4737836SJohn.Forte@Sun.COM  * Returns 0 if successful or an error code otherwise.
4747836SJohn.Forte@Sun.COM  */
4757836SJohn.Forte@Sun.COM static int
process_delete_request_from_doc(xmlXPathContextPtr ctext,request_t * req)4767836SJohn.Forte@Sun.COM process_delete_request_from_doc(xmlXPathContextPtr ctext, request_t *req)
4777836SJohn.Forte@Sun.COM {
4787836SJohn.Forte@Sun.COM 	xmlChar expr[ISNS_MAX_LABEL_LEN + 13];
4797836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr xpath_obj = NULL;
4807836SJohn.Forte@Sun.COM 	xmlNodeSetPtr r_nodes = NULL;
4817836SJohn.Forte@Sun.COM 	xmlAttrPtr attr = NULL;
4827836SJohn.Forte@Sun.COM 	xmlChar *container = NULL, *member = NULL;
4837836SJohn.Forte@Sun.COM 	int i, cnt;
4847836SJohn.Forte@Sun.COM 
4857836SJohn.Forte@Sun.COM 	int obj = 0;
4867836SJohn.Forte@Sun.COM 
4877836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "process_delete_request_from_doc", "entered");
4887836SJohn.Forte@Sun.COM 	for (i = 0; obj_table[i].obj_str != NULL; i++) {
4897836SJohn.Forte@Sun.COM 	    (void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
4907836SJohn.Forte@Sun.COM 		(const unsigned char *)"%s\"%s\"]", "//*[name()=",
4917836SJohn.Forte@Sun.COM 		obj_table[i].obj_str);
4927836SJohn.Forte@Sun.COM 	    xpath_obj = xmlXPathEvalExpression(expr, ctext);
4937836SJohn.Forte@Sun.COM 	    if ((xpath_obj) && (xpath_obj->nodesetval) &&
4947836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeNr > 0) &&
4957836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeTab)) {
4967836SJohn.Forte@Sun.COM 		obj = obj_table[i].obj_id;
4977836SJohn.Forte@Sun.COM 		break;
4987836SJohn.Forte@Sun.COM 	    }
4997836SJohn.Forte@Sun.COM 	    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
5007836SJohn.Forte@Sun.COM 	}
5017836SJohn.Forte@Sun.COM 
5027836SJohn.Forte@Sun.COM 	if (obj == 0) {
5037836SJohn.Forte@Sun.COM 	    return (ERR_XML_VALID_OBJECT_NOT_FOUND);
5047836SJohn.Forte@Sun.COM 	}
5057836SJohn.Forte@Sun.COM 
5067836SJohn.Forte@Sun.COM 	req->op_info.obj = obj;
5077836SJohn.Forte@Sun.COM 
5087836SJohn.Forte@Sun.COM 	if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
5097836SJohn.Forte@Sun.COM 	    ISNS_MGMT_OBJECT_TYPE(obj);
5107836SJohn.Forte@Sun.COM 	}
5117836SJohn.Forte@Sun.COM 
5127836SJohn.Forte@Sun.COM 	switch (obj) {
5137836SJohn.Forte@Sun.COM 	    case DiscoveryDomainMember:
5147836SJohn.Forte@Sun.COM 		/* at least one object exists to get here. */
5157836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
5167836SJohn.Forte@Sun.COM 		cnt = r_nodes->nodeNr;
5177836SJohn.Forte@Sun.COM 		req->count = 0;
5187836SJohn.Forte@Sun.COM 		req->req_data.pair =
5197836SJohn.Forte@Sun.COM 		(assoc_pair_t **)malloc(sizeof (assoc_pair_t *));
5207836SJohn.Forte@Sun.COM 		for (i = 0; i < cnt; i++) {
5217836SJohn.Forte@Sun.COM 		    attr = r_nodes->nodeTab[i]->properties;
5227836SJohn.Forte@Sun.COM 		    for (; attr != NULL; attr = attr->next) {
5237836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)DDNAMEATTR,
5247836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)DDNAMEATTR)) == 0) {
5257836SJohn.Forte@Sun.COM 				container =
5267836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
5277836SJohn.Forte@Sun.COM 			}
5287836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)NODENAMEATTR,
5297836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)NODENAMEATTR)) == 0) {
5307836SJohn.Forte@Sun.COM 				member =
5317836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
5327836SJohn.Forte@Sun.COM 			}
5337836SJohn.Forte@Sun.COM 		    }
5347836SJohn.Forte@Sun.COM 		    if (container != NULL && member != NULL) {
5357836SJohn.Forte@Sun.COM 			    req->req_data.pair =
5367836SJohn.Forte@Sun.COM 			    NEW_REQPAIRARGV(req->req_data.pair, req->count);
5377836SJohn.Forte@Sun.COM 			    if (req->req_data.pair == (assoc_pair_t **)NULL) {
5387836SJohn.Forte@Sun.COM 				if (xpath_obj) xmlXPathFreeObject(xpath_obj);
5397836SJohn.Forte@Sun.COM 				return (ERR_MALLOC_FAILED);
5407836SJohn.Forte@Sun.COM 			    }
5417836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count] = (assoc_pair_t *)
5427836SJohn.Forte@Sun.COM 				malloc(sizeof (assoc_pair_t));
5437836SJohn.Forte@Sun.COM 			    if (req->req_data.pair[req->count] == NULL) {
5447836SJohn.Forte@Sun.COM 				if (xpath_obj) xmlXPathFreeObject(xpath_obj);
5457836SJohn.Forte@Sun.COM 				return (ERR_MALLOC_FAILED);
5467836SJohn.Forte@Sun.COM 			    }
5477836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count]->container =
5487836SJohn.Forte@Sun.COM 				container;
5497836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count]->member =
5507836SJohn.Forte@Sun.COM 				member;
5517836SJohn.Forte@Sun.COM 			    req->req_data.data[++req->count] = NULL;
5527836SJohn.Forte@Sun.COM 		    } else {
5537836SJohn.Forte@Sun.COM 			    if (container != NULL) {
5547836SJohn.Forte@Sun.COM 				xmlFree(container);
5557836SJohn.Forte@Sun.COM 			    }
5567836SJohn.Forte@Sun.COM 			    if (member != NULL) {
5577836SJohn.Forte@Sun.COM 				xmlFree(member);
5587836SJohn.Forte@Sun.COM 			    }
5597836SJohn.Forte@Sun.COM 			    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
5607836SJohn.Forte@Sun.COM 			    return (ERR_XML_OP_FAILED);
5617836SJohn.Forte@Sun.COM 		    }
5627836SJohn.Forte@Sun.COM 		    container = NULL;
5637836SJohn.Forte@Sun.COM 		    member = NULL;
5647836SJohn.Forte@Sun.COM 		}
5657836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
5667836SJohn.Forte@Sun.COM 		break;
5677836SJohn.Forte@Sun.COM 	    case DiscoveryDomainSetMember:
5687836SJohn.Forte@Sun.COM 		/* at least one object exists to get here. */
5697836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
5707836SJohn.Forte@Sun.COM 		cnt = r_nodes->nodeNr;
5717836SJohn.Forte@Sun.COM 		req->count = 0;
5727836SJohn.Forte@Sun.COM 		req->req_data.pair =
5737836SJohn.Forte@Sun.COM 		(assoc_pair_t **)malloc(sizeof (assoc_pair_t *));
5747836SJohn.Forte@Sun.COM 		for (i = 0; i < cnt; i++) {
5757836SJohn.Forte@Sun.COM 		    attr = r_nodes->nodeTab[i]->properties;
5767836SJohn.Forte@Sun.COM 		    for (; attr != NULL; attr = attr->next) {
5777836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)DDSETNAMEATTR,
5787836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)DDNAMEATTR)) == 0) {
5797836SJohn.Forte@Sun.COM 				container =
5807836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
5817836SJohn.Forte@Sun.COM 			}
5827836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)DDNAMEATTR,
5837836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)NODENAMEATTR)) == 0) {
5847836SJohn.Forte@Sun.COM 				member =
5857836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
5867836SJohn.Forte@Sun.COM 			}
5877836SJohn.Forte@Sun.COM 		    }
5887836SJohn.Forte@Sun.COM 		    if (container != NULL && member != NULL) {
5897836SJohn.Forte@Sun.COM 			    req->req_data.pair =
5907836SJohn.Forte@Sun.COM 			    NEW_REQPAIRARGV(req->req_data.pair, req->count);
5917836SJohn.Forte@Sun.COM 			    if (req->req_data.pair == (assoc_pair_t **)NULL) {
5927836SJohn.Forte@Sun.COM 				if (xpath_obj) xmlXPathFreeObject(xpath_obj);
5937836SJohn.Forte@Sun.COM 				return (ERR_MALLOC_FAILED);
5947836SJohn.Forte@Sun.COM 			    }
5957836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count] = (assoc_pair_t *)
5967836SJohn.Forte@Sun.COM 				malloc(sizeof (assoc_pair_t));
5977836SJohn.Forte@Sun.COM 			    if (req->req_data.pair[req->count] == NULL) {
5987836SJohn.Forte@Sun.COM 				if (xpath_obj) xmlXPathFreeObject(xpath_obj);
5997836SJohn.Forte@Sun.COM 				return (ERR_MALLOC_FAILED);
6007836SJohn.Forte@Sun.COM 			    }
6017836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count]->container =
6027836SJohn.Forte@Sun.COM 				container;
6037836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count++]->member =
6047836SJohn.Forte@Sun.COM 				member;
6057836SJohn.Forte@Sun.COM 			    req->req_data.data[req->count] = NULL;
6067836SJohn.Forte@Sun.COM 		    } else {
6077836SJohn.Forte@Sun.COM 			    if (container != NULL) {
6087836SJohn.Forte@Sun.COM 				xmlFree(container);
6097836SJohn.Forte@Sun.COM 			    }
6107836SJohn.Forte@Sun.COM 			    if (member != NULL) {
6117836SJohn.Forte@Sun.COM 				xmlFree(member);
6127836SJohn.Forte@Sun.COM 			    }
6137836SJohn.Forte@Sun.COM 			    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
6147836SJohn.Forte@Sun.COM 			    return (ERR_XML_OP_FAILED);
6157836SJohn.Forte@Sun.COM 		    }
6167836SJohn.Forte@Sun.COM 		}
6177836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
6187836SJohn.Forte@Sun.COM 		break;
6197836SJohn.Forte@Sun.COM 	    case DiscoveryDomain:
6207836SJohn.Forte@Sun.COM 	    case DiscoveryDomainSet:
6217836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
6227836SJohn.Forte@Sun.COM 		cnt = r_nodes->nodeNr;
6237836SJohn.Forte@Sun.COM 		req->count = 0;
6247836SJohn.Forte@Sun.COM 		req->req_data.data = (xmlChar **) malloc(sizeof (xmlChar *));
6257836SJohn.Forte@Sun.COM 		for (i = 0; i < cnt; i++) {
6267836SJohn.Forte@Sun.COM 		    attr = r_nodes->nodeTab[i]->properties;
6277836SJohn.Forte@Sun.COM 		    for (; attr != NULL; attr = attr->next) {
6287836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)NAMEATTR,
6297836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)NAMEATTR)) == 0) {
6307836SJohn.Forte@Sun.COM 				req->req_data.data =
6317836SJohn.Forte@Sun.COM 				    NEW_REQARGV(req->req_data.data, req->count);
6327836SJohn.Forte@Sun.COM 				if (req->req_data.data == (xmlChar **)NULL) {
6337836SJohn.Forte@Sun.COM 				    if (xpath_obj)
6347836SJohn.Forte@Sun.COM 					xmlXPathFreeObject(xpath_obj);
6357836SJohn.Forte@Sun.COM 				    return (ERR_MALLOC_FAILED);
6367836SJohn.Forte@Sun.COM 				}
6377836SJohn.Forte@Sun.COM 				req->req_data.data[req->count] =
6387836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
6397836SJohn.Forte@Sun.COM 				req->req_data.data[++req->count] = NULL;
6407836SJohn.Forte@Sun.COM 			}
6417836SJohn.Forte@Sun.COM 		    }
6427836SJohn.Forte@Sun.COM 		}
6437836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
6447836SJohn.Forte@Sun.COM 		break;
6457836SJohn.Forte@Sun.COM 	    default:
6467836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
6477836SJohn.Forte@Sun.COM 		return (ERR_XML_OP_FAILED);
6487836SJohn.Forte@Sun.COM 	}
6497836SJohn.Forte@Sun.COM 
6507836SJohn.Forte@Sun.COM 	return (0);
6517836SJohn.Forte@Sun.COM }
6527836SJohn.Forte@Sun.COM 
6537836SJohn.Forte@Sun.COM /*
6547836SJohn.Forte@Sun.COM  * process_createModify_request_from_doc --
6557836SJohn.Forte@Sun.COM  *	    first looks for the object through the context ptr and sets the
6567836SJohn.Forte@Sun.COM  *	    request with additional data.
6577836SJohn.Forte@Sun.COM  *	    For DD and DD set, the name is given.
6587836SJohn.Forte@Sun.COM  *	    For DD and DD set membership, container and member pairs are given.
6597836SJohn.Forte@Sun.COM  *
6607836SJohn.Forte@Sun.COM  * ctext: context ptr for the original doc to parse request info.
6617836SJohn.Forte@Sun.COM  * req: request to be filled up.
6627836SJohn.Forte@Sun.COM  *
6637836SJohn.Forte@Sun.COM  * Returns 0 if successful or an error code otherwise.
6647836SJohn.Forte@Sun.COM  */
6657836SJohn.Forte@Sun.COM static int
process_createModify_request_from_doc(xmlXPathContextPtr ctext,request_t * req)6667836SJohn.Forte@Sun.COM process_createModify_request_from_doc(xmlXPathContextPtr ctext, request_t *req)
6677836SJohn.Forte@Sun.COM {
6687836SJohn.Forte@Sun.COM 	xmlChar expr[ISNS_MAX_LABEL_LEN + 13];
6697836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr xpath_obj = NULL;
6707836SJohn.Forte@Sun.COM 	xmlNodeSetPtr r_nodes = NULL;
6717836SJohn.Forte@Sun.COM 	xmlAttrPtr attr = NULL;
6727836SJohn.Forte@Sun.COM 	xmlChar *container = NULL, *member = NULL, *xml_id;
6737836SJohn.Forte@Sun.COM 	int i, cnt;
6747836SJohn.Forte@Sun.COM 
6757836SJohn.Forte@Sun.COM 	int obj = 0;
6767836SJohn.Forte@Sun.COM 
6777836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "process_createModify_request_from_doc", "entered");
6787836SJohn.Forte@Sun.COM 	for (i = 0; obj_table[i].obj_str != NULL; i++) {
6797836SJohn.Forte@Sun.COM 	    (void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
6807836SJohn.Forte@Sun.COM 		(const unsigned char *)"%s\"%s\"]", "//*[name()=",
6817836SJohn.Forte@Sun.COM 		obj_table[i].obj_str);
6827836SJohn.Forte@Sun.COM 	    xpath_obj = xmlXPathEvalExpression(expr, ctext);
6837836SJohn.Forte@Sun.COM 	    if ((xpath_obj) && (xpath_obj->nodesetval) &&
6847836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeNr > 0) &&
6857836SJohn.Forte@Sun.COM 		(xpath_obj->nodesetval->nodeTab)) {
6867836SJohn.Forte@Sun.COM 		obj = obj_table[i].obj_id;
6877836SJohn.Forte@Sun.COM 		break;
6887836SJohn.Forte@Sun.COM 	    }
6897836SJohn.Forte@Sun.COM 	    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
6907836SJohn.Forte@Sun.COM 	}
6917836SJohn.Forte@Sun.COM 
6927836SJohn.Forte@Sun.COM 	if (obj == 0) {
6937836SJohn.Forte@Sun.COM 	    return (ERR_XML_VALID_OBJECT_NOT_FOUND);
6947836SJohn.Forte@Sun.COM 	}
6957836SJohn.Forte@Sun.COM 
6967836SJohn.Forte@Sun.COM 	req->op_info.obj = obj;
6977836SJohn.Forte@Sun.COM 
6987836SJohn.Forte@Sun.COM 	if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
6997836SJohn.Forte@Sun.COM 	    ISNS_MGMT_OBJECT_TYPE(obj);
7007836SJohn.Forte@Sun.COM 	}
7017836SJohn.Forte@Sun.COM 
7027836SJohn.Forte@Sun.COM 	switch (obj) {
7037836SJohn.Forte@Sun.COM 	    case DiscoveryDomainMember:
7047836SJohn.Forte@Sun.COM 		/* at least one object exists to get here. */
7057836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
7067836SJohn.Forte@Sun.COM 		cnt = r_nodes->nodeNr;
7077836SJohn.Forte@Sun.COM 		req->count = 0;
7087836SJohn.Forte@Sun.COM 		req->req_data.pair =
7097836SJohn.Forte@Sun.COM 		(assoc_pair_t **)malloc(sizeof (assoc_pair_t *));
7107836SJohn.Forte@Sun.COM 		for (i = 0; i < cnt; i++) {
7117836SJohn.Forte@Sun.COM 		    attr = r_nodes->nodeTab[i]->properties;
7127836SJohn.Forte@Sun.COM 		    for (; attr != NULL; attr = attr->next) {
7137836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)DDNAMEATTR,
7147836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)DDNAMEATTR)) == 0) {
7157836SJohn.Forte@Sun.COM 				container =
7167836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
7177836SJohn.Forte@Sun.COM 			}
7187836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)NODENAMEATTR,
7197836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)NODENAMEATTR)) == 0) {
7207836SJohn.Forte@Sun.COM 				member =
7217836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
7227836SJohn.Forte@Sun.COM 			}
7237836SJohn.Forte@Sun.COM 		    }
7247836SJohn.Forte@Sun.COM 		    if (container != NULL && member != NULL) {
7257836SJohn.Forte@Sun.COM 			    req->req_data.pair =
7267836SJohn.Forte@Sun.COM 			    NEW_REQPAIRARGV(req->req_data.pair, req->count);
7277836SJohn.Forte@Sun.COM 			    if (req->req_data.pair == (assoc_pair_t **)NULL) {
7287836SJohn.Forte@Sun.COM 				if (xpath_obj) xmlXPathFreeObject(xpath_obj);
7297836SJohn.Forte@Sun.COM 				return (ERR_MALLOC_FAILED);
7307836SJohn.Forte@Sun.COM 			    }
7317836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count] = (assoc_pair_t *)
7327836SJohn.Forte@Sun.COM 				malloc(sizeof (assoc_pair_t));
7337836SJohn.Forte@Sun.COM 			    if (req->req_data.pair[req->count] == NULL) {
7347836SJohn.Forte@Sun.COM 				if (xpath_obj) xmlXPathFreeObject(xpath_obj);
7357836SJohn.Forte@Sun.COM 				return (ERR_MALLOC_FAILED);
7367836SJohn.Forte@Sun.COM 			    }
7377836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count]->container =
7387836SJohn.Forte@Sun.COM 				container;
7397836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count]->member =
7407836SJohn.Forte@Sun.COM 				member;
7417836SJohn.Forte@Sun.COM 			    req->req_data.data[++req->count] = NULL;
7427836SJohn.Forte@Sun.COM 		    } else {
7437836SJohn.Forte@Sun.COM 			    if (container != NULL) {
7447836SJohn.Forte@Sun.COM 				xmlFree(container);
7457836SJohn.Forte@Sun.COM 			    }
7467836SJohn.Forte@Sun.COM 			    if (member != NULL) {
7477836SJohn.Forte@Sun.COM 				xmlFree(member);
7487836SJohn.Forte@Sun.COM 			    }
7497836SJohn.Forte@Sun.COM 			    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
7507836SJohn.Forte@Sun.COM 			    return (ERR_XML_OP_FAILED);
7517836SJohn.Forte@Sun.COM 		    }
7527836SJohn.Forte@Sun.COM 		    container = member = NULL;
7537836SJohn.Forte@Sun.COM 		}
7547836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
7557836SJohn.Forte@Sun.COM 		break;
7567836SJohn.Forte@Sun.COM 	    case DiscoveryDomainSetMember:
7577836SJohn.Forte@Sun.COM 		/* at least one object exists to get here. */
7587836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
7597836SJohn.Forte@Sun.COM 		cnt = r_nodes->nodeNr;
7607836SJohn.Forte@Sun.COM 		req->count = 0;
7617836SJohn.Forte@Sun.COM 		req->req_data.pair =
7627836SJohn.Forte@Sun.COM 		(assoc_pair_t **)malloc(sizeof (assoc_pair_t *));
7637836SJohn.Forte@Sun.COM 		for (i = 0; i < cnt; i++) {
7647836SJohn.Forte@Sun.COM 		    attr = r_nodes->nodeTab[i]->properties;
7657836SJohn.Forte@Sun.COM 		    for (; attr != NULL; attr = attr->next) {
7667836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)DDSETNAMEATTR,
7677836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)DDSETNAMEATTR)) == 0) {
7687836SJohn.Forte@Sun.COM 				container =
7697836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
7707836SJohn.Forte@Sun.COM 			}
7717836SJohn.Forte@Sun.COM 			if (xmlStrncmp(attr->name, (xmlChar *)DDNAMEATTR,
7727836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)DDNAMEATTR)) == 0) {
7737836SJohn.Forte@Sun.COM 				member =
7747836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
7757836SJohn.Forte@Sun.COM 			}
7767836SJohn.Forte@Sun.COM 		    }
7777836SJohn.Forte@Sun.COM 		    if (container != NULL && member != NULL) {
7787836SJohn.Forte@Sun.COM 			    req->req_data.pair =
7797836SJohn.Forte@Sun.COM 			    NEW_REQPAIRARGV(req->req_data.pair, req->count);
7807836SJohn.Forte@Sun.COM 			    if (req->req_data.pair == (assoc_pair_t **)NULL) {
7817836SJohn.Forte@Sun.COM 				if (xpath_obj) xmlXPathFreeObject(xpath_obj);
7827836SJohn.Forte@Sun.COM 				return (ERR_MALLOC_FAILED);
7837836SJohn.Forte@Sun.COM 			    }
7847836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count] = (assoc_pair_t *)
7857836SJohn.Forte@Sun.COM 				malloc(sizeof (assoc_pair_t));
7867836SJohn.Forte@Sun.COM 			    if (req->req_data.pair[req->count] == NULL) {
7877836SJohn.Forte@Sun.COM 				if (xpath_obj) xmlXPathFreeObject(xpath_obj);
7887836SJohn.Forte@Sun.COM 				return (ERR_MALLOC_FAILED);
7897836SJohn.Forte@Sun.COM 			    }
7907836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count]->container =
7917836SJohn.Forte@Sun.COM 				container;
7927836SJohn.Forte@Sun.COM 			    req->req_data.pair[req->count]->member =
7937836SJohn.Forte@Sun.COM 				member;
7947836SJohn.Forte@Sun.COM 			    req->req_data.data[++req->count] = NULL;
7957836SJohn.Forte@Sun.COM 		    } else {
7967836SJohn.Forte@Sun.COM 			    if (container != NULL) {
7977836SJohn.Forte@Sun.COM 				xmlFree(container);
7987836SJohn.Forte@Sun.COM 			    }
7997836SJohn.Forte@Sun.COM 			    if (member != NULL) {
8007836SJohn.Forte@Sun.COM 				xmlFree(member);
8017836SJohn.Forte@Sun.COM 			    }
8027836SJohn.Forte@Sun.COM 			    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
8037836SJohn.Forte@Sun.COM 			    return (ERR_XML_OP_FAILED);
8047836SJohn.Forte@Sun.COM 		    }
8057836SJohn.Forte@Sun.COM 		    container = member = NULL;
8067836SJohn.Forte@Sun.COM 		}
8077836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
8087836SJohn.Forte@Sun.COM 		break;
8097836SJohn.Forte@Sun.COM 	    case DiscoveryDomain:
8107836SJohn.Forte@Sun.COM 	    case DiscoveryDomainSet:
8117836SJohn.Forte@Sun.COM 		/* at least one object exists to get here. */
8127836SJohn.Forte@Sun.COM 		r_nodes = xpath_obj->nodesetval;
8137836SJohn.Forte@Sun.COM 		cnt = r_nodes->nodeNr;
8147836SJohn.Forte@Sun.COM 		req->count = 0;
8157836SJohn.Forte@Sun.COM 		req->req_data.attrlist =
8167836SJohn.Forte@Sun.COM 		(object_attrlist_t **)malloc(sizeof (object_attrlist_t *));
8177836SJohn.Forte@Sun.COM 		for (i = 0; i < cnt; i++) {
8187836SJohn.Forte@Sun.COM 		    req->req_data.attrlist =
8197836SJohn.Forte@Sun.COM 			NEW_REQATTRLISTARGV(req->req_data.attrlist, req->count);
8207836SJohn.Forte@Sun.COM 		    if (req->req_data.attrlist ==
8217836SJohn.Forte@Sun.COM 			(object_attrlist_t **)NULL) {
8227836SJohn.Forte@Sun.COM 			if (xpath_obj) xmlXPathFreeObject(xpath_obj);
8237836SJohn.Forte@Sun.COM 			return (ERR_MALLOC_FAILED);
8247836SJohn.Forte@Sun.COM 		    }
8257836SJohn.Forte@Sun.COM 		    req->req_data.attrlist[req->count] = (object_attrlist_t *)
8267836SJohn.Forte@Sun.COM 			malloc(sizeof (object_attrlist_t));
8277836SJohn.Forte@Sun.COM 		    if (req->req_data.attrlist[req->count] == NULL) {
8287836SJohn.Forte@Sun.COM 			if (xpath_obj) xmlXPathFreeObject(xpath_obj);
8297836SJohn.Forte@Sun.COM 			return (ERR_MALLOC_FAILED);
8307836SJohn.Forte@Sun.COM 		    }
8317836SJohn.Forte@Sun.COM 		    req->req_data.attrlist[req->count]->name = NULL;
8327836SJohn.Forte@Sun.COM 		    req->req_data.attrlist[req->count]->id = NULL;
8337836SJohn.Forte@Sun.COM 		    req->req_data.attrlist[req->count]->enabled = NULL;
8347836SJohn.Forte@Sun.COM 		    attr = r_nodes->nodeTab[i]->properties;
8357836SJohn.Forte@Sun.COM 		    for (; attr != NULL; attr = attr->next) {
8367836SJohn.Forte@Sun.COM 			if ((xmlStrncmp(attr->name, (xmlChar *)NAMEATTR,
8377836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)NAMEATTR))) == 0) {
8387836SJohn.Forte@Sun.COM 				req->req_data.attrlist[req->count]->name =
8397836SJohn.Forte@Sun.COM 				xmlNodeGetContent(attr->children);
8407836SJohn.Forte@Sun.COM 			}
8417836SJohn.Forte@Sun.COM 			if ((xmlStrncmp(attr->name, (xmlChar *)IDATTR,
8427836SJohn.Forte@Sun.COM 			    xmlStrlen((xmlChar *)IDATTR))) == 0) {
8437836SJohn.Forte@Sun.COM 				req->req_data.attrlist[req->count]->id =
8447836SJohn.Forte@Sun.COM 				    (uint32_t *)calloc(1, sizeof (uint32_t));
8457836SJohn.Forte@Sun.COM 				if (req->req_data.attrlist[req->count]->id ==
8467836SJohn.Forte@Sun.COM 				    NULL) {
8477836SJohn.Forte@Sun.COM 				    if (xpath_obj)
8487836SJohn.Forte@Sun.COM 					xmlXPathFreeObject(xpath_obj);
8497836SJohn.Forte@Sun.COM 				    return (ERR_MALLOC_FAILED);
8507836SJohn.Forte@Sun.COM 				}
8517836SJohn.Forte@Sun.COM 				xml_id = xmlNodeGetContent(attr->children);
8527836SJohn.Forte@Sun.COM 				if (xml_id != NULL) {
8537836SJohn.Forte@Sun.COM 				    *(req->req_data.attrlist[req->count]->id) =
8547836SJohn.Forte@Sun.COM 					atoi((const char *)xml_id);
8557836SJohn.Forte@Sun.COM 				    xmlFree(xml_id);
8567836SJohn.Forte@Sun.COM 				}
8577836SJohn.Forte@Sun.COM 			}
8587836SJohn.Forte@Sun.COM 		    }
8597836SJohn.Forte@Sun.COM 			/*
8607836SJohn.Forte@Sun.COM 			 * check the enabled element.
8617836SJohn.Forte@Sun.COM 			 * Only one child element so check the children ptr.
8627836SJohn.Forte@Sun.COM 			 */
8637836SJohn.Forte@Sun.COM 		    if (r_nodes->nodeTab[i]->children) {
8647836SJohn.Forte@Sun.COM 			req->req_data.attrlist[req->count]->enabled =
8657836SJohn.Forte@Sun.COM 			    (boolean_t *)malloc(sizeof (boolean_t));
8667836SJohn.Forte@Sun.COM 			if (req->req_data.attrlist[req->count]->enabled
8677836SJohn.Forte@Sun.COM 			    == NULL) {
8687836SJohn.Forte@Sun.COM 			    if (xpath_obj) xmlXPathFreeObject(xpath_obj);
8697836SJohn.Forte@Sun.COM 			    return (ERR_MALLOC_FAILED);
8707836SJohn.Forte@Sun.COM 			}
8717836SJohn.Forte@Sun.COM 			/* value is children of enabled. */
8727836SJohn.Forte@Sun.COM 			if (xmlStrncmp(
8737836SJohn.Forte@Sun.COM 			    r_nodes->nodeTab[i]->children->children->content,
8747836SJohn.Forte@Sun.COM 			    (xmlChar *)XMLTRUE, xmlStrlen((xmlChar *)XMLTRUE))
8757836SJohn.Forte@Sun.COM 			    == 0) {
8767836SJohn.Forte@Sun.COM 			    *(req->req_data.attrlist[req->count]->enabled)
8777836SJohn.Forte@Sun.COM 				= B_TRUE;
8787836SJohn.Forte@Sun.COM 			} else {
8797836SJohn.Forte@Sun.COM 			    *(req->req_data.attrlist[req->count]->enabled)
8807836SJohn.Forte@Sun.COM 				= B_FALSE;
8817836SJohn.Forte@Sun.COM 			}
8827836SJohn.Forte@Sun.COM 		    }
8837836SJohn.Forte@Sun.COM 		    req->req_data.attrlist[++req->count] = NULL;
8847836SJohn.Forte@Sun.COM 		}
8857836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
8867836SJohn.Forte@Sun.COM 		break;
8877836SJohn.Forte@Sun.COM 	    default:
8887836SJohn.Forte@Sun.COM 		if (xpath_obj) xmlXPathFreeObject(xpath_obj);
8897836SJohn.Forte@Sun.COM 		return (ERR_XML_OP_FAILED);
8907836SJohn.Forte@Sun.COM 	}
8917836SJohn.Forte@Sun.COM 
8927836SJohn.Forte@Sun.COM 	return (0);
8937836SJohn.Forte@Sun.COM }
8947836SJohn.Forte@Sun.COM 
8957836SJohn.Forte@Sun.COM /*
8967836SJohn.Forte@Sun.COM  * build_mgmt_request -- extracts the request info from the given XML doc.
8977836SJohn.Forte@Sun.COM  *
8987836SJohn.Forte@Sun.COM  * x_doc: ptr to the request XML doc
8997836SJohn.Forte@Sun.COM  * req: ptr to the request struct to be filled up.
9007836SJohn.Forte@Sun.COM  *
9017836SJohn.Forte@Sun.COM  * Return value: ISNS_RSP_SUCCESSFUL if successful or an error code.
9027836SJohn.Forte@Sun.COM  */
9037836SJohn.Forte@Sun.COM static int
process_mgmt_request(xmlDocPtr x_doc,request_t * req,ucred_t * uc)9047836SJohn.Forte@Sun.COM process_mgmt_request(xmlDocPtr x_doc, request_t *req, ucred_t *uc)
9057836SJohn.Forte@Sun.COM {
9067836SJohn.Forte@Sun.COM 	result_code_t   ret;
9077836SJohn.Forte@Sun.COM 	int		op;
9087836SJohn.Forte@Sun.COM 	xmlXPathContextPtr ctext = NULL;
9097836SJohn.Forte@Sun.COM 	uid_t			user;
9107836SJohn.Forte@Sun.COM 	struct passwd		pwds, *pwd;
9117836SJohn.Forte@Sun.COM 	char			buf_pwd[1024];
9127836SJohn.Forte@Sun.COM 
9137836SJohn.Forte@Sun.COM 
9147836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "process_mgmt_request", "entered");
9157836SJohn.Forte@Sun.COM 	(void) memset(req, 0, sizeof (request_t));
9167836SJohn.Forte@Sun.COM 	/* get the operation first. */
9177836SJohn.Forte@Sun.COM 	ctext = xmlXPathNewContext(x_doc);
9187836SJohn.Forte@Sun.COM 	if (ctext == NULL) {
9197836SJohn.Forte@Sun.COM 	    return (ERR_XML_FAILED_TO_SET_XPATH_CONTEXT);
9207836SJohn.Forte@Sun.COM 	}
9217836SJohn.Forte@Sun.COM 
9227836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "process_mgmt_request", "xpath context succeeded");
9237836SJohn.Forte@Sun.COM 	op = get_op_id_from_doc(ctext);
9247836SJohn.Forte@Sun.COM 	if (op == -1) {
9257836SJohn.Forte@Sun.COM 	    if (ctext) xmlXPathFreeContext(ctext);
9267836SJohn.Forte@Sun.COM 	    return (ERR_XML_VALID_OPERATION_NOT_FOUND);
9277836SJohn.Forte@Sun.COM 	}
9287836SJohn.Forte@Sun.COM 
9297836SJohn.Forte@Sun.COM 	user = ucred_getruid(uc);
9307836SJohn.Forte@Sun.COM 	ret = getpwuid_r(user, &pwds, buf_pwd, sizeof (buf_pwd), &pwd);
9317836SJohn.Forte@Sun.COM 	if (ret != 0) {
9327836SJohn.Forte@Sun.COM 	    if (ctext) xmlXPathFreeContext(ctext);
9337836SJohn.Forte@Sun.COM 	    return (ERR_DOOR_SERVER_DETECTED_INVALID_USER);
9347836SJohn.Forte@Sun.COM 	}
9357836SJohn.Forte@Sun.COM 
9367836SJohn.Forte@Sun.COM 	/* write operations are restricted. */
9377836SJohn.Forte@Sun.COM 	if ((op == delete_op) || (op == createModify_op)) {
9387836SJohn.Forte@Sun.COM 	    if (!chkauthattr(ISNS_ADMIN_WRITE_AUTH, pwd->pw_name)) {
9397836SJohn.Forte@Sun.COM 		if (ctext) xmlXPathFreeContext(ctext);
9407836SJohn.Forte@Sun.COM 		return (ERR_DOOR_SERVER_DETECTED_NOT_AUTHORIZED_USER);
9417836SJohn.Forte@Sun.COM 	    }
9427836SJohn.Forte@Sun.COM 	}
9437836SJohn.Forte@Sun.COM 
9447836SJohn.Forte@Sun.COM 	req->op_info.op = op;
9457836SJohn.Forte@Sun.COM 
9467836SJohn.Forte@Sun.COM 	if (ISNS_MGMT_OPERATION_TYPE_ENABLED()) {
9477836SJohn.Forte@Sun.COM 	    ISNS_MGMT_OPERATION_TYPE(op);
9487836SJohn.Forte@Sun.COM 	}
9497836SJohn.Forte@Sun.COM 
9507836SJohn.Forte@Sun.COM 	switch (op) {
9517836SJohn.Forte@Sun.COM 	    case (get_op):
9527836SJohn.Forte@Sun.COM 		ret = process_get_request_from_doc(ctext, req);
9537836SJohn.Forte@Sun.COM 		break;
9547836SJohn.Forte@Sun.COM 	    case (getAssociated_op):
9557836SJohn.Forte@Sun.COM 		ret = process_getAssociated_request_from_doc(ctext, req);
9567836SJohn.Forte@Sun.COM 		break;
9577836SJohn.Forte@Sun.COM 	    case (enumerate_op):
9587836SJohn.Forte@Sun.COM 		ret = process_enumerate_request_from_doc(ctext, req);
9597836SJohn.Forte@Sun.COM 		break;
9607836SJohn.Forte@Sun.COM 	    case (delete_op):
9617836SJohn.Forte@Sun.COM 		ret = process_delete_request_from_doc(ctext, req);
9627836SJohn.Forte@Sun.COM 		break;
9637836SJohn.Forte@Sun.COM 	    case (createModify_op):
9647836SJohn.Forte@Sun.COM 		ret = process_createModify_request_from_doc(ctext, req);
9657836SJohn.Forte@Sun.COM 		break;
9667836SJohn.Forte@Sun.COM 	    default:
9677836SJohn.Forte@Sun.COM 		ret = ERR_XML_VALID_OPERATION_NOT_FOUND;
9687836SJohn.Forte@Sun.COM 	}
9697836SJohn.Forte@Sun.COM 
9707836SJohn.Forte@Sun.COM 	if (ctext) xmlXPathFreeContext(ctext);
9717836SJohn.Forte@Sun.COM 	return (ret);
9727836SJohn.Forte@Sun.COM }
9737836SJohn.Forte@Sun.COM 
9747836SJohn.Forte@Sun.COM /*
9757836SJohn.Forte@Sun.COM  * build_mgmt_response -- sets an XML doc with a root and calls a porper
9767836SJohn.Forte@Sun.COM  *	    routine based on the request.  If the called routine constructed
9777836SJohn.Forte@Sun.COM  *	    the response doc with the result element, this routine fills up
9787836SJohn.Forte@Sun.COM  *	    response buffer with raw XML doc.
9797836SJohn.Forte@Sun.COM  *
9807836SJohn.Forte@Sun.COM  * reponse: ptr to response buffer
9817836SJohn.Forte@Sun.COM  * req: request to be processed.
9827836SJohn.Forte@Sun.COM  * size: ptr to the response doc buffer
9837836SJohn.Forte@Sun.COM  */
9847836SJohn.Forte@Sun.COM static int
build_mgmt_response(xmlChar ** response,request_t req,int * size)9857836SJohn.Forte@Sun.COM build_mgmt_response(xmlChar **response, request_t req, int *size)
9867836SJohn.Forte@Sun.COM {
9877836SJohn.Forte@Sun.COM 
9887836SJohn.Forte@Sun.COM 	int ret;
9897836SJohn.Forte@Sun.COM 	xmlDocPtr	doc;
9907836SJohn.Forte@Sun.COM 	xmlNodePtr	root;
9917836SJohn.Forte@Sun.COM 	xmlXPathContextPtr ctext = NULL;
9927836SJohn.Forte@Sun.COM 	xmlChar expr[ISNS_MAX_LABEL_LEN + 13];
9937836SJohn.Forte@Sun.COM 	xmlXPathObjectPtr xpath_obj = NULL;
9947836SJohn.Forte@Sun.COM 
9957836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "build_mgmt_response", "entered");
9967836SJohn.Forte@Sun.COM 
9977836SJohn.Forte@Sun.COM 	doc = xmlNewDoc((uchar_t *)"1.0");
9987836SJohn.Forte@Sun.COM 	root = xmlNewNode(NULL, (xmlChar *)ISNSRESPONSE);
9997836SJohn.Forte@Sun.COM 	(void) xmlDocSetRootElement(doc, root);
10007836SJohn.Forte@Sun.COM 	if (xmlSetProp(root, (xmlChar *)XMLNSATTR, (xmlChar *)XMLNSATTRVAL) ==
10017836SJohn.Forte@Sun.COM 	    NULL) {
10027836SJohn.Forte@Sun.COM 	    return (ERR_XML_SETPROP_FAILED);
10037836SJohn.Forte@Sun.COM 	}
10047836SJohn.Forte@Sun.COM 
10057836SJohn.Forte@Sun.COM 	switch (req.op_info.op) {
10067836SJohn.Forte@Sun.COM 	    case get_op:
10077836SJohn.Forte@Sun.COM 		switch (req.op_info.obj) {
10087836SJohn.Forte@Sun.COM 		    case Node:
10097836SJohn.Forte@Sun.COM 			ret = get_node_op(&req, doc);
10107836SJohn.Forte@Sun.COM 			break;
10117836SJohn.Forte@Sun.COM 		    case DiscoveryDomain:
10127836SJohn.Forte@Sun.COM 			ret = get_dd_op(&req, doc);
10137836SJohn.Forte@Sun.COM 			break;
10147836SJohn.Forte@Sun.COM 		    case DiscoveryDomainSet:
10157836SJohn.Forte@Sun.COM 			ret = get_ddset_op(&req, doc);
10167836SJohn.Forte@Sun.COM 			break;
10177836SJohn.Forte@Sun.COM 		    case ServerConfig:
10187836SJohn.Forte@Sun.COM 			ret = get_serverconfig_op(doc);
10197836SJohn.Forte@Sun.COM 			break;
10207836SJohn.Forte@Sun.COM 		    default:
10217836SJohn.Forte@Sun.COM 			ret = ERR_INVALID_MGMT_REQUEST;
10227836SJohn.Forte@Sun.COM 		}
10237836SJohn.Forte@Sun.COM 		break;
10247836SJohn.Forte@Sun.COM 	    case enumerate_op:
10257836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "build_mgmt_response", "enumerate_op");
10267836SJohn.Forte@Sun.COM 		switch (req.op_info.obj) {
10277836SJohn.Forte@Sun.COM 		    case Node:
10287836SJohn.Forte@Sun.COM 			ret = enumerate_node_op(doc);
10297836SJohn.Forte@Sun.COM 			break;
10307836SJohn.Forte@Sun.COM 		    case DiscoveryDomain:
10317836SJohn.Forte@Sun.COM 			ret = enumerate_dd_op(doc);
10327836SJohn.Forte@Sun.COM 			break;
10337836SJohn.Forte@Sun.COM 		    case DiscoveryDomainSet:
10347836SJohn.Forte@Sun.COM 			ret = enumerate_ddset_op(doc);
10357836SJohn.Forte@Sun.COM 			break;
10367836SJohn.Forte@Sun.COM 		    default:
10377836SJohn.Forte@Sun.COM 			ret = ERR_INVALID_MGMT_REQUEST;
10387836SJohn.Forte@Sun.COM 		}
10397836SJohn.Forte@Sun.COM 		break;
10407836SJohn.Forte@Sun.COM 	    case getAssociated_op:
10417836SJohn.Forte@Sun.COM 		switch (req.op_info.obj) {
10427836SJohn.Forte@Sun.COM 		    case DiscoveryDomainMember:
10437836SJohn.Forte@Sun.COM 			if (req.assoc_req == container_to_member) {
10447836SJohn.Forte@Sun.COM 			    ret = getAssociated_dd_to_node_op(&req, doc);
10457836SJohn.Forte@Sun.COM 			} else {
10467836SJohn.Forte@Sun.COM 			    ret = getAssociated_node_to_dd_op(&req, doc);
10477836SJohn.Forte@Sun.COM 			}
10487836SJohn.Forte@Sun.COM 			break;
10497836SJohn.Forte@Sun.COM 		    case DiscoveryDomainSetMember:
10507836SJohn.Forte@Sun.COM 			if (req.assoc_req == container_to_member) {
10517836SJohn.Forte@Sun.COM 			    ret = getAssociated_ddset_to_dd_op(&req, doc);
10527836SJohn.Forte@Sun.COM 			} else {
10537836SJohn.Forte@Sun.COM 			    ret = getAssociated_dd_to_ddset_op(&req, doc);
10547836SJohn.Forte@Sun.COM 			}
10557836SJohn.Forte@Sun.COM 			break;
10567836SJohn.Forte@Sun.COM 		    default:
10577836SJohn.Forte@Sun.COM 			ret = ERR_INVALID_MGMT_REQUEST;
10587836SJohn.Forte@Sun.COM 		}
10597836SJohn.Forte@Sun.COM 		break;
10607836SJohn.Forte@Sun.COM 	    case createModify_op:
10617836SJohn.Forte@Sun.COM 		switch (req.op_info.obj) {
10627836SJohn.Forte@Sun.COM 		    case DiscoveryDomain:
10637836SJohn.Forte@Sun.COM 		    case DiscoveryDomainSet:
10647836SJohn.Forte@Sun.COM 			ret = createModify_dd_ddset_op(&req, doc);
10657836SJohn.Forte@Sun.COM 			break;
10667836SJohn.Forte@Sun.COM 		    case DiscoveryDomainMember:
10677836SJohn.Forte@Sun.COM 		    case DiscoveryDomainSetMember:
10687836SJohn.Forte@Sun.COM 			ret = create_ddmember_ddsetmember_op(&req, doc,
10697836SJohn.Forte@Sun.COM 			    req.op_info.obj);
10707836SJohn.Forte@Sun.COM 			break;
10717836SJohn.Forte@Sun.COM 		    default:
10727836SJohn.Forte@Sun.COM 			ret = ERR_INVALID_MGMT_REQUEST;
10737836SJohn.Forte@Sun.COM 		}
10747836SJohn.Forte@Sun.COM 		break;
10757836SJohn.Forte@Sun.COM 	    case delete_op:
10767836SJohn.Forte@Sun.COM 		switch (req.op_info.obj) {
10777836SJohn.Forte@Sun.COM 		    case DiscoveryDomainMember:
10787836SJohn.Forte@Sun.COM 		    case DiscoveryDomainSetMember:
10797836SJohn.Forte@Sun.COM 			ret = delete_ddmember_ddsetmember_op(&req, doc,
10807836SJohn.Forte@Sun.COM 			    req.op_info.obj);
10817836SJohn.Forte@Sun.COM 			break;
10827836SJohn.Forte@Sun.COM 		    case DiscoveryDomain:
10837836SJohn.Forte@Sun.COM 		    case DiscoveryDomainSet:
10847836SJohn.Forte@Sun.COM 			ret = delete_dd_ddset_op(&req, doc, req.op_info.obj);
10857836SJohn.Forte@Sun.COM 			break;
10867836SJohn.Forte@Sun.COM 		    default:
10877836SJohn.Forte@Sun.COM 			ret = ERR_INVALID_MGMT_REQUEST;
10887836SJohn.Forte@Sun.COM 		}
10897836SJohn.Forte@Sun.COM 		break;
10907836SJohn.Forte@Sun.COM 	    default:
10917836SJohn.Forte@Sun.COM 		ret = ERR_INVALID_MGMT_REQUEST;
10927836SJohn.Forte@Sun.COM 	}
10937836SJohn.Forte@Sun.COM 
10947836SJohn.Forte@Sun.COM 	/*
10957836SJohn.Forte@Sun.COM 	 * if failed check to see the doc contains the result element.
10967836SJohn.Forte@Sun.COM 	 * if not, the response is set with only an error code.
10977836SJohn.Forte@Sun.COM 	 */
10987836SJohn.Forte@Sun.COM 	if (ret != ISNS_RSP_SUCCESSFUL) {
10997836SJohn.Forte@Sun.COM 	    ctext = xmlXPathNewContext(doc);
11007836SJohn.Forte@Sun.COM 	    if (ctext != NULL) {
11017836SJohn.Forte@Sun.COM 		(void) xmlStrPrintf(expr, ISNS_MAX_LABEL_LEN + 13,
11027836SJohn.Forte@Sun.COM 		    (const unsigned char *)"%s\"%s\"]", "//*[name()=", RESULT);
11037836SJohn.Forte@Sun.COM 		xpath_obj = xmlXPathEvalExpression(expr, ctext);
11047836SJohn.Forte@Sun.COM 		if ((xpath_obj == NULL) || (xpath_obj->nodesetval == NULL) ||
11057836SJohn.Forte@Sun.COM 		    (xpath_obj->nodesetval->nodeNr <= 0) ||
11067836SJohn.Forte@Sun.COM 		    (xpath_obj->nodesetval->nodeTab == NULL)) {
11077836SJohn.Forte@Sun.COM 		    isnslog(LOG_DEBUG,
11087836SJohn.Forte@Sun.COM 			"build_mgmt_response",
11097836SJohn.Forte@Sun.COM 			"returning repsonse only with error code %d\n", ret);
11107836SJohn.Forte@Sun.COM 			*response = malloc(sizeof (ret));
11117836SJohn.Forte@Sun.COM 			if (*response) **response = ret;
11127836SJohn.Forte@Sun.COM 			*size = sizeof (ret);
11137836SJohn.Forte@Sun.COM 		} else {
11147836SJohn.Forte@Sun.COM 		    xmlDocDumpMemory(doc, response, size);
11157836SJohn.Forte@Sun.COM 		}
11167836SJohn.Forte@Sun.COM 	    } else {
11177836SJohn.Forte@Sun.COM 		/* can't verify the xml doc. dump return the doc anyway. */
11187836SJohn.Forte@Sun.COM 		xmlDocDumpMemory(doc, response, size);
11197836SJohn.Forte@Sun.COM 	    }
11207836SJohn.Forte@Sun.COM 	} else {
11217836SJohn.Forte@Sun.COM 	    xmlDocDumpMemory(doc, response, size);
11227836SJohn.Forte@Sun.COM 	}
11237836SJohn.Forte@Sun.COM 
11247836SJohn.Forte@Sun.COM 	if (xpath_obj) xmlXPathFreeObject(xpath_obj);
11257836SJohn.Forte@Sun.COM 	if (ctext) xmlXPathFreeContext(ctext);
11267836SJohn.Forte@Sun.COM 	if (doc) xmlFreeDoc(doc);
11277836SJohn.Forte@Sun.COM 	return (ret);
11287836SJohn.Forte@Sun.COM }
11297836SJohn.Forte@Sun.COM 
11307836SJohn.Forte@Sun.COM /*
11317836SJohn.Forte@Sun.COM  * build_result_message -- construct a response doc with the given result.
11327836SJohn.Forte@Sun.COM  *	    Result contains status code and message.
11337836SJohn.Forte@Sun.COM  *
11347836SJohn.Forte@Sun.COM  * reponse: ptr to response doc
11357836SJohn.Forte@Sun.COM  * code: result code
11367836SJohn.Forte@Sun.COM  * size: ptr to the response doc size
11377836SJohn.Forte@Sun.COM  */
11387836SJohn.Forte@Sun.COM static int
build_result_message(xmlChar ** response,result_code_t code,int * size)11397836SJohn.Forte@Sun.COM build_result_message(xmlChar **response, result_code_t code, int *size)
11407836SJohn.Forte@Sun.COM {
11417836SJohn.Forte@Sun.COM 	int ret = ISNS_RSP_SUCCESSFUL;
11427836SJohn.Forte@Sun.COM 	xmlDocPtr	doc;
11437836SJohn.Forte@Sun.COM 	xmlNodePtr	root, n_obj;
11447836SJohn.Forte@Sun.COM 	char		numbuf[32];
11457836SJohn.Forte@Sun.COM 
11467836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "build_result_response", "entered");
11477836SJohn.Forte@Sun.COM 
11487836SJohn.Forte@Sun.COM 	doc = xmlNewDoc((uchar_t *)"1.0");
11497836SJohn.Forte@Sun.COM 	root = xmlNewNode(NULL, (xmlChar *)ISNSRESPONSE);
11507836SJohn.Forte@Sun.COM 	(void) xmlDocSetRootElement(doc, root);
11517836SJohn.Forte@Sun.COM 
11527836SJohn.Forte@Sun.COM 	n_obj = xmlNewChild(root, NULL, (xmlChar *)RESULT, NULL);
11537836SJohn.Forte@Sun.COM 
11547836SJohn.Forte@Sun.COM 	if (code == ISNS_RSP_SUCCESSFUL) {
11557836SJohn.Forte@Sun.COM 	    (void) sprintf(numbuf, "%d", ISNS_RSP_SUCCESSFUL);
11567836SJohn.Forte@Sun.COM 	    if (xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
11577836SJohn.Forte@Sun.COM 		(xmlChar *)numbuf) == NULL) {
11587836SJohn.Forte@Sun.COM 		ret = ERR_XML_NEWCHILD_FAILED;
11597836SJohn.Forte@Sun.COM 	    }
11607836SJohn.Forte@Sun.COM 	} else {
11617836SJohn.Forte@Sun.COM 	    (void) sprintf(numbuf, "%d", code);
11627836SJohn.Forte@Sun.COM 	    if (xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
11637836SJohn.Forte@Sun.COM 		(xmlChar *)numbuf) == NULL) {
11647836SJohn.Forte@Sun.COM 		ret = ERR_XML_NEWCHILD_FAILED;
11657836SJohn.Forte@Sun.COM 	    }
11667836SJohn.Forte@Sun.COM 	    if (xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
11677836SJohn.Forte@Sun.COM 		(xmlChar *)result_code_to_str(code)) == NULL) {
11687836SJohn.Forte@Sun.COM 		ret = ERR_XML_NEWCHILD_FAILED;
11697836SJohn.Forte@Sun.COM 	    }
11707836SJohn.Forte@Sun.COM 	}
11717836SJohn.Forte@Sun.COM 
11727836SJohn.Forte@Sun.COM 	xmlDocDumpMemory(doc, response, size);
11737836SJohn.Forte@Sun.COM 
11747836SJohn.Forte@Sun.COM 	if (doc) xmlFreeDoc(doc);
11757836SJohn.Forte@Sun.COM 	return (ret);
11767836SJohn.Forte@Sun.COM }
11777836SJohn.Forte@Sun.COM 
11787836SJohn.Forte@Sun.COM /*
11797836SJohn.Forte@Sun.COM  * cleanup_request -- deallocatate memory associated with the given request
11807836SJohn.Forte@Sun.COM  *	    structure.
11817836SJohn.Forte@Sun.COM  */
11827836SJohn.Forte@Sun.COM static void
cleanup_request(request_t req)11837836SJohn.Forte@Sun.COM cleanup_request(request_t req)
11847836SJohn.Forte@Sun.COM {
11857836SJohn.Forte@Sun.COM 	int i;
11867836SJohn.Forte@Sun.COM 
11877836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "cleanup_request", "entered");
11887836SJohn.Forte@Sun.COM 	switch (req.op_info.op) {
11897836SJohn.Forte@Sun.COM 	    case (get_op):
11907836SJohn.Forte@Sun.COM 		for (i = 0; i < req.count; i++) {
11917836SJohn.Forte@Sun.COM 		    if (req.req_data.data[i])
11927836SJohn.Forte@Sun.COM 			xmlFree(req.req_data.data[i]);
11937836SJohn.Forte@Sun.COM 		}
11947836SJohn.Forte@Sun.COM 		if (req.req_data.data) free(req.req_data.data);
11957836SJohn.Forte@Sun.COM 		break;
11967836SJohn.Forte@Sun.COM 	    case (getAssociated_op):
11977836SJohn.Forte@Sun.COM 		for (i = 0; i < req.count; i++) {
11987836SJohn.Forte@Sun.COM 		    if (req.req_data.data[i])
11997836SJohn.Forte@Sun.COM 			xmlFree(req.req_data.data[i]);
12007836SJohn.Forte@Sun.COM 		}
12017836SJohn.Forte@Sun.COM 		if (req.req_data.data) free(req.req_data.data);
12027836SJohn.Forte@Sun.COM 		break;
12037836SJohn.Forte@Sun.COM 	    case (enumerate_op):
12047836SJohn.Forte@Sun.COM 		break;
12057836SJohn.Forte@Sun.COM 	    case (delete_op):
12067836SJohn.Forte@Sun.COM 		if ((req.op_info.obj == DiscoveryDomainMember) ||
12077836SJohn.Forte@Sun.COM 		    (req.op_info.obj == DiscoveryDomainSetMember)) {
12087836SJohn.Forte@Sun.COM 		    for (i = 0; i < req.count; i++) {
12097836SJohn.Forte@Sun.COM 			if (req.req_data.pair[i]->container)
12107836SJohn.Forte@Sun.COM 			    xmlFree(req.req_data.pair[i]->container);
12117836SJohn.Forte@Sun.COM 			if (req.req_data.pair[i]->member)
12127836SJohn.Forte@Sun.COM 			    xmlFree(req.req_data.pair[i]->member);
12137836SJohn.Forte@Sun.COM 			if (req.req_data.pair[i])
12147836SJohn.Forte@Sun.COM 			    free(req.req_data.pair[i]);
12157836SJohn.Forte@Sun.COM 		    }
12167836SJohn.Forte@Sun.COM 		    if (req.req_data.pair) free(req.req_data.pair);
12177836SJohn.Forte@Sun.COM 		} else {
12187836SJohn.Forte@Sun.COM 		    for (i = 0; i < req.count; i++) {
12197836SJohn.Forte@Sun.COM 			if (req.req_data.data[i])
12207836SJohn.Forte@Sun.COM 			    xmlFree(req.req_data.data[i]);
12217836SJohn.Forte@Sun.COM 		    }
12227836SJohn.Forte@Sun.COM 		    if (req.req_data.data) free(req.req_data.data);
12237836SJohn.Forte@Sun.COM 		}
12247836SJohn.Forte@Sun.COM 		break;
12257836SJohn.Forte@Sun.COM 	    case (createModify_op):
12267836SJohn.Forte@Sun.COM 		if ((req.op_info.obj == DiscoveryDomainMember) ||
12277836SJohn.Forte@Sun.COM 		    (req.op_info.obj == DiscoveryDomainSetMember)) {
12287836SJohn.Forte@Sun.COM 		    for (i = 0; i < req.count; i++) {
12297836SJohn.Forte@Sun.COM 			if (req.req_data.pair[i]->container)
12307836SJohn.Forte@Sun.COM 			    xmlFree(req.req_data.pair[i]->container);
12317836SJohn.Forte@Sun.COM 			if (req.req_data.pair[i]->member)
12327836SJohn.Forte@Sun.COM 			    xmlFree(req.req_data.pair[i]->member);
12337836SJohn.Forte@Sun.COM 			if (req.req_data.pair[i])
12347836SJohn.Forte@Sun.COM 			    free(req.req_data.pair[i]);
12357836SJohn.Forte@Sun.COM 		    }
12367836SJohn.Forte@Sun.COM 		    if (req.req_data.pair) free(req.req_data.pair);
12377836SJohn.Forte@Sun.COM 		} else if ((req.op_info.obj == DiscoveryDomain) ||
12387836SJohn.Forte@Sun.COM 		    (req.op_info.obj == DiscoveryDomainSet)) {
12397836SJohn.Forte@Sun.COM 		    for (i = 0; i < req.count; i++) {
12407836SJohn.Forte@Sun.COM 			if (req.req_data.attrlist[i]->name)
12417836SJohn.Forte@Sun.COM 			    xmlFree(req.req_data.attrlist[i]->name);
12427836SJohn.Forte@Sun.COM 			if (req.req_data.attrlist[i]->id)
12437836SJohn.Forte@Sun.COM 			    free(req.req_data.attrlist[i]->id);
12447836SJohn.Forte@Sun.COM 			if (req.req_data.attrlist[i]->enabled)
12457836SJohn.Forte@Sun.COM 			    free(req.req_data.attrlist[i]->enabled);
12467836SJohn.Forte@Sun.COM 			if (req.req_data.pair[i])
12477836SJohn.Forte@Sun.COM 			    free(req.req_data.pair[i]);
12487836SJohn.Forte@Sun.COM 		    }
12497836SJohn.Forte@Sun.COM 		    if (req.req_data.attrlist) free(req.req_data.attrlist);
12507836SJohn.Forte@Sun.COM 		}
12517836SJohn.Forte@Sun.COM 		break;
12527836SJohn.Forte@Sun.COM 	}
12537836SJohn.Forte@Sun.COM }
12547836SJohn.Forte@Sun.COM 
12557836SJohn.Forte@Sun.COM /*
12567836SJohn.Forte@Sun.COM  * Find a matching entry for the given thread id.
12577836SJohn.Forte@Sun.COM  */
match_entry(pthread_t tid)12587836SJohn.Forte@Sun.COM static thr_elem_t *match_entry(pthread_t tid)
12597836SJohn.Forte@Sun.COM {
12607836SJohn.Forte@Sun.COM 
12617836SJohn.Forte@Sun.COM 	thr_elem_t *thr = thr_list;
12627836SJohn.Forte@Sun.COM 
12637836SJohn.Forte@Sun.COM 	while (thr) {
12647836SJohn.Forte@Sun.COM 	    if (pthread_equal(thr->thr_id, tid)) {
12657836SJohn.Forte@Sun.COM 		return (thr);
12667836SJohn.Forte@Sun.COM 	    }
12677836SJohn.Forte@Sun.COM 	    thr = thr->next;
12687836SJohn.Forte@Sun.COM 	}
12697836SJohn.Forte@Sun.COM 
12707836SJohn.Forte@Sun.COM 	return (NULL);
12717836SJohn.Forte@Sun.COM }
12727836SJohn.Forte@Sun.COM 
12737836SJohn.Forte@Sun.COM /*
12747836SJohn.Forte@Sun.COM  * Add an entry to the thr_list for the given thread id.
12757836SJohn.Forte@Sun.COM  */
12767836SJohn.Forte@Sun.COM static int
add_entry(pthread_t tid,xmlChar * doc)12777836SJohn.Forte@Sun.COM add_entry(pthread_t tid, xmlChar *doc)
12787836SJohn.Forte@Sun.COM {
12797836SJohn.Forte@Sun.COM 
12807836SJohn.Forte@Sun.COM 	thr_elem_t *new_e;
12817836SJohn.Forte@Sun.COM 	thr_elem_t *thr = thr_list;
12827836SJohn.Forte@Sun.COM 
12837836SJohn.Forte@Sun.COM 	if ((new_e = malloc(sizeof (thr_elem_t))) == NULL) {
12847836SJohn.Forte@Sun.COM 	    return (ERR_MALLOC_FAILED);
12857836SJohn.Forte@Sun.COM 	}
12867836SJohn.Forte@Sun.COM 	new_e->thr_id = tid;
12877836SJohn.Forte@Sun.COM 	new_e->doc = doc;
12887836SJohn.Forte@Sun.COM 	new_e->next = NULL;
12897836SJohn.Forte@Sun.COM 
12907836SJohn.Forte@Sun.COM 	if (thr_list == NULL) {
12917836SJohn.Forte@Sun.COM 	    thr_list = new_e;
12927836SJohn.Forte@Sun.COM 	} else {
12937836SJohn.Forte@Sun.COM 	    while (thr->next) {
12947836SJohn.Forte@Sun.COM 		thr = thr->next;
12957836SJohn.Forte@Sun.COM 	    }
12967836SJohn.Forte@Sun.COM 	    thr->next = new_e;
12977836SJohn.Forte@Sun.COM 	}
12987836SJohn.Forte@Sun.COM 
12997836SJohn.Forte@Sun.COM 	return (ISNS_RSP_SUCCESSFUL);
13007836SJohn.Forte@Sun.COM }
13017836SJohn.Forte@Sun.COM 
13027836SJohn.Forte@Sun.COM /*
13037836SJohn.Forte@Sun.COM  * door_server -- proecess the management request and send response back
13047836SJohn.Forte@Sun.COM  *		the client.
13057836SJohn.Forte@Sun.COM  *
13067836SJohn.Forte@Sun.COM  * In order to handle allocation after door_return,
13077836SJohn.Forte@Sun.COM  * a global list, thr_list, is maintained to free the response buffer
13087836SJohn.Forte@Sun.COM  * from the previous invocation of the server function on the same thread.
13097836SJohn.Forte@Sun.COM  * Note:  the door framework creates a thread and the same thread is used
13107836SJohn.Forte@Sun.COM  * while a new thread is created for concurrent door_calls.
13117836SJohn.Forte@Sun.COM  *
13127836SJohn.Forte@Sun.COM  * If a thread is used once the buffer will be left allocated.
13137836SJohn.Forte@Sun.COM  */
13147836SJohn.Forte@Sun.COM /*ARGSUSED*/
13157836SJohn.Forte@Sun.COM static void
door_server(void * cookie,char * argp,size_t arg_size,door_desc_t * dp,uint_t n_desc)13167836SJohn.Forte@Sun.COM door_server(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
13177836SJohn.Forte@Sun.COM     uint_t n_desc)
13187836SJohn.Forte@Sun.COM {
13197836SJohn.Forte@Sun.COM 	request_t		req;
13207836SJohn.Forte@Sun.COM 	xmlDocPtr		x_doc;
13217836SJohn.Forte@Sun.COM 	xmlChar			*resp_buf = NULL;
13227836SJohn.Forte@Sun.COM 	int			ret, size = 0;
13237836SJohn.Forte@Sun.COM 	pthread_t		tid;
13247836SJohn.Forte@Sun.COM 	thr_elem_t		*thr;
13257836SJohn.Forte@Sun.COM 	ucred_t			*uc = NULL;
13267836SJohn.Forte@Sun.COM 
13277836SJohn.Forte@Sun.COM 	if (ISNS_MGMT_REQUEST_RECEIVED_ENABLED()) {
13287836SJohn.Forte@Sun.COM 	    ISNS_MGMT_REQUEST_RECEIVED();
13297836SJohn.Forte@Sun.COM 	}
13307836SJohn.Forte@Sun.COM 
13317836SJohn.Forte@Sun.COM 	if (door_ucred(&uc) != 0) {
13327836SJohn.Forte@Sun.COM 	    isnslog(LOG_DEBUG, "door_server",
13337836SJohn.Forte@Sun.COM 		"door_ucred failed. errno: %d\n", errno);
13347836SJohn.Forte@Sun.COM 	    ret = build_result_message(&resp_buf,
13357836SJohn.Forte@Sun.COM 		ERR_DOOR_UCRED_FAILED, &size);
13367836SJohn.Forte@Sun.COM 	    if (ret == ISNS_RSP_SUCCESSFUL) {
13377836SJohn.Forte@Sun.COM 		(void) door_return((char *)resp_buf, size + 1,  NULL, 0);
13387836SJohn.Forte@Sun.COM 		/* Not reached */
13397836SJohn.Forte@Sun.COM 	    } else {
13407836SJohn.Forte@Sun.COM 		ret = ERR_DOOR_UCRED_FAILED;
13417836SJohn.Forte@Sun.COM 		(void) door_return((void *)&ret, sizeof (ret),  NULL, 0);
13427836SJohn.Forte@Sun.COM 		/* Not reached */
13437836SJohn.Forte@Sun.COM 	    }
13447836SJohn.Forte@Sun.COM 	}
13457836SJohn.Forte@Sun.COM 
13467836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "door_server", "entered with request:\n %s\n", argp);
13477836SJohn.Forte@Sun.COM 	if ((x_doc = xmlParseMemory(argp, arg_size)) != NULL) {
13487836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "door_server", "ParseMemory succeeded");
13497836SJohn.Forte@Sun.COM 		if ((ret = process_mgmt_request(x_doc, &req, uc)) == 0) {
13507836SJohn.Forte@Sun.COM 		    ret = build_mgmt_response(&resp_buf, req, &size);
13517836SJohn.Forte@Sun.COM 		} else {
13527836SJohn.Forte@Sun.COM 		    ret = build_result_message(&resp_buf, ret, &size);
13537836SJohn.Forte@Sun.COM 		}
13547836SJohn.Forte@Sun.COM 		xmlFreeDoc(x_doc);
13557836SJohn.Forte@Sun.COM 		cleanup_request(req);
13567836SJohn.Forte@Sun.COM 	} else {
13577836SJohn.Forte@Sun.COM 		ret = build_result_message(&resp_buf,
13587836SJohn.Forte@Sun.COM 		    ERR_XML_PARSE_MEMORY_FAILED, &size);
13597836SJohn.Forte@Sun.COM 	}
13607836SJohn.Forte@Sun.COM 
13617836SJohn.Forte@Sun.COM 	/* free the ucred */
13627836SJohn.Forte@Sun.COM 	ucred_free(uc);
13637836SJohn.Forte@Sun.COM 
13647836SJohn.Forte@Sun.COM 	if (resp_buf) {
13657836SJohn.Forte@Sun.COM 	    tid = pthread_self();
13667836SJohn.Forte@Sun.COM 	    if ((thr = match_entry(tid)) == NULL) {
13677836SJohn.Forte@Sun.COM 		(void) add_entry(tid, resp_buf);
13687836SJohn.Forte@Sun.COM 	    } else {
13697836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "door_server",
13707836SJohn.Forte@Sun.COM 		    "free the previouly returned buffer %x on this thread\n",
13717836SJohn.Forte@Sun.COM 		    thr->doc);
13727836SJohn.Forte@Sun.COM 		xmlFree(thr->doc);
13737836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "door_server",
13747836SJohn.Forte@Sun.COM 		    "store the currently allocated buffer %x on this thread\n",
13757836SJohn.Forte@Sun.COM 		    resp_buf);
13767836SJohn.Forte@Sun.COM 		thr->doc = resp_buf;
13777836SJohn.Forte@Sun.COM 	    }
13787836SJohn.Forte@Sun.COM 	    isnslog(LOG_DEBUG,
13797836SJohn.Forte@Sun.COM 		"door_server", "exiting with response:\n %s\n",
13807836SJohn.Forte@Sun.COM 		    (const char *)resp_buf);
13817836SJohn.Forte@Sun.COM 
13827836SJohn.Forte@Sun.COM 	    if (ISNS_MGMT_REQUEST_RESPONDED_ENABLED()) {
13837836SJohn.Forte@Sun.COM 		ISNS_MGMT_REQUEST_RESPONDED();
13847836SJohn.Forte@Sun.COM 	    }
13857836SJohn.Forte@Sun.COM 
13867836SJohn.Forte@Sun.COM 	    (void) door_return((char *)resp_buf, size + 1,  NULL, 0);
13877836SJohn.Forte@Sun.COM 		/* Not reached */
13887836SJohn.Forte@Sun.COM 	}
13897836SJohn.Forte@Sun.COM 
13907836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG,
13917836SJohn.Forte@Sun.COM 	    "door_server", "exiting only with error code %d\n", ret);
13927836SJohn.Forte@Sun.COM 
13937836SJohn.Forte@Sun.COM 	if (ISNS_MGMT_REQUEST_RESPONDED_ENABLED()) {
13947836SJohn.Forte@Sun.COM 	    ISNS_MGMT_REQUEST_RESPONDED();
13957836SJohn.Forte@Sun.COM 	}
13967836SJohn.Forte@Sun.COM 
13977836SJohn.Forte@Sun.COM 	(void) door_return((void *)&ret, sizeof (ret),  NULL, 0);
13987836SJohn.Forte@Sun.COM 
13997836SJohn.Forte@Sun.COM }
14007836SJohn.Forte@Sun.COM 
14017836SJohn.Forte@Sun.COM /*
14027836SJohn.Forte@Sun.COM  * setup_mgmt_door -- Create a door portal for management application requests
14037836SJohn.Forte@Sun.COM  *
14047836SJohn.Forte@Sun.COM  * First check to see if another daemon is already running by attempting
14057836SJohn.Forte@Sun.COM  * to send an empty request to the door. If successful it means this
14067836SJohn.Forte@Sun.COM  * daemon should exit.
14077836SJohn.Forte@Sun.COM  */
14087836SJohn.Forte@Sun.COM int
setup_mgmt_door(msg_queue_t * sys_q)14097836SJohn.Forte@Sun.COM setup_mgmt_door(msg_queue_t *sys_q)
14107836SJohn.Forte@Sun.COM {
14117836SJohn.Forte@Sun.COM 	int fd, door_id;
14127836SJohn.Forte@Sun.COM 	struct stat buf;
14137836SJohn.Forte@Sun.COM 	door_arg_t darg;
14147836SJohn.Forte@Sun.COM 
14157836SJohn.Forte@Sun.COM 	isnslog(LOG_DEBUG, "setup_mgmt_door", "entered");
14167836SJohn.Forte@Sun.COM 	/* check if a door is already running. */
14177836SJohn.Forte@Sun.COM 	if ((fd = open(ISNS_DOOR_NAME, 0)) >= 0) {
14187836SJohn.Forte@Sun.COM 		darg.data_ptr = "<?xml version='1.0' encoding='UTF-8'?>"
14197836SJohn.Forte@Sun.COM 				"<isnsRequest><get><isnsObject>"
14207836SJohn.Forte@Sun.COM 				"<DiscoveryDomain name=\"default\">"
14217836SJohn.Forte@Sun.COM 				"</DiscoveryDomain></isnsObject></get>"
14227836SJohn.Forte@Sun.COM 				"</isnsRequest>";
14237836SJohn.Forte@Sun.COM 		darg.data_size = xmlStrlen((xmlChar *)darg.data_ptr) + 1;
14247836SJohn.Forte@Sun.COM 		darg.desc_ptr = NULL;
14257836SJohn.Forte@Sun.COM 		darg.desc_num = 0;
14267836SJohn.Forte@Sun.COM 		darg.rbuf = NULL;
14277836SJohn.Forte@Sun.COM 		darg.rsize = 0;
14287836SJohn.Forte@Sun.COM 
14297836SJohn.Forte@Sun.COM 		if (door_call(fd, &darg) == 0) {
14307836SJohn.Forte@Sun.COM 			/* door already running. */
14317836SJohn.Forte@Sun.COM 			(void) close(fd);
14327836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "setup_mgmt_door",
14337836SJohn.Forte@Sun.COM 			    "management door is already runninng.");
14347836SJohn.Forte@Sun.COM 			if (darg.rsize > darg.data_size) {
14357836SJohn.Forte@Sun.COM 			    (void) munmap(darg.rbuf, darg.rsize);
14367836SJohn.Forte@Sun.COM 			}
1437*8971Swl202157@icefox 			door_created = B_FALSE;
14387836SJohn.Forte@Sun.COM 			return (0);
14397836SJohn.Forte@Sun.COM 		}
14407836SJohn.Forte@Sun.COM 		(void) close(fd);
14417836SJohn.Forte@Sun.COM 	}
14427836SJohn.Forte@Sun.COM 
14437836SJohn.Forte@Sun.COM 	if ((door_id = door_create(door_server, (void *)sys_q, 0)) < 0) {
14447836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "setup_mgmt_door",
14457836SJohn.Forte@Sun.COM 			"Failed to create managment door");
14467836SJohn.Forte@Sun.COM 		exit(1);
14477836SJohn.Forte@Sun.COM 	}
14487836SJohn.Forte@Sun.COM 
14497836SJohn.Forte@Sun.COM 	if (stat(ISNS_DOOR_NAME, &buf) < 0) {
14507836SJohn.Forte@Sun.COM 	    if ((fd = creat(ISNS_DOOR_NAME, 0666)) < 0) {
14517836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "setup_mgmt_door",
14527836SJohn.Forte@Sun.COM 		    "open failed on %s errno = %d", ISNS_DOOR_NAME, errno);
14537836SJohn.Forte@Sun.COM 		exit(1);
14547836SJohn.Forte@Sun.COM 	    }
14557836SJohn.Forte@Sun.COM 	    (void) close(fd);
14567836SJohn.Forte@Sun.COM 	}
14577836SJohn.Forte@Sun.COM 
14587836SJohn.Forte@Sun.COM 	/* make sure the file permission set to general access. */
14597836SJohn.Forte@Sun.COM 	(void) chmod(ISNS_DOOR_NAME, 0666);
14607836SJohn.Forte@Sun.COM 	(void) fdetach(ISNS_DOOR_NAME);
14617836SJohn.Forte@Sun.COM 
14627836SJohn.Forte@Sun.COM 	if (fattach(door_id, ISNS_DOOR_NAME) < 0) {
14637836SJohn.Forte@Sun.COM 		syslog(LOG_DEBUG, "setup_mgmt_door",
14647836SJohn.Forte@Sun.COM 		    "fattach failed on %s errno=%d",
14657836SJohn.Forte@Sun.COM 		    ISNS_DOOR_NAME, errno);
14667836SJohn.Forte@Sun.COM 		return (-1);
14677836SJohn.Forte@Sun.COM 	}
14687836SJohn.Forte@Sun.COM 
1469*8971Swl202157@icefox 	door_created = B_TRUE;
1470*8971Swl202157@icefox 
14717836SJohn.Forte@Sun.COM 	return (0);
14727836SJohn.Forte@Sun.COM }
1473