4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <libxml/xmlreader.h>
27 #include <libxml/xmlwriter.h>
28 #include <libxml/tree.h>
29 #include <libxml/parser.h>
30 #include <libxml/xpath.h>
34 #include <sys/types.h>
37 #include <auth_attr.h>
47 #include "isns_server.h"
49 #include "isns_mgmt.h"
50 #include "isns_utils.h"
51 #include "isns_protocol.h"
53 #include "isns_provider.h"
55 /* door creation flag */
56 extern boolean_t door_created
;
58 /* macro for allocating name buffers for the request */
59 #define NEW_REQARGV(old, n) (xmlChar **)reallocarray((old), \
60 (n) + 2, sizeof (xmlChar *))
62 /* macro for allocating association pair buffers for the request */
63 #define NEW_REQPAIRARGV(old, n) (assoc_pair_t **)reallocarray(old, \
64 (n) + 2, sizeof (assoc_pair_t *))
66 /* macro for allocating DD/DD set attribute list buffers for the request */
67 #define NEW_REQATTRLISTARGV(old, n)\
68 (object_attrlist_t **)reallocarray(old, \
69 (n) + 2, sizeof (object_attrlist_t *))
71 #if LIBXML_VERSION >= 20904
72 #define XMLSTRING_CAST (const char *)
74 #define XMLSTRING_CAST (const xmlChar *)
78 static op_table_entry_t op_table
[] = {
80 {GETASSOCIATED
, getAssociated_op
},
81 {ENUMERATE
, enumerate_op
},
82 {CREATEMODIFY
, createModify_op
},
88 static obj_table_entry_t obj_table
[] = {
90 {DDOBJECT
, DiscoveryDomain
},
91 {DDSETOBJECT
, DiscoveryDomainSet
},
92 {DDOBJECTMEMBER
, DiscoveryDomainMember
},
93 {DDSETOBJECTMEMBER
, DiscoveryDomainSetMember
},
94 {ISNSSERVER
, ServerConfig
},
99 * list to capture thread id and associated door return buffer
100 * the return buffer from the previous door return is freed
101 * when the same thread is invoked to take another request.
102 * While the server is running one buffer is outstanding
105 static thr_elem_t
*thr_list
= NULL
;
108 * get_op_id_from_doc --
109 * extracts an operation id through the given context ptr.
111 * ctext: context ptr for the original doc
113 * Returns an operation id if found or -1 otherwise.
116 get_op_id_from_doc(xmlXPathContextPtr ctext
)
118 xmlChar expr
[ISNS_MAX_LABEL_LEN
+ 13];
119 xmlXPathObjectPtr xpath_obj
= NULL
;
122 for (i
= 0; op_table
[i
].op_str
!= NULL
; i
++) {
123 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
124 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=",
126 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
127 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
128 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
129 (xpath_obj
->nodesetval
->nodeTab
)) {
130 isnslog(LOG_DEBUG
, "get_op_id_from_doc ",
131 "xpath obj->nodesetval->nodeNr: %d",
132 xpath_obj
->nodesetval
->nodeNr
);
133 isnslog(LOG_DEBUG
, "get_op_id_from_doc", "operation: %s id: %d",
134 op_table
[i
].op_str
, op_table
[i
].op_id
);
135 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
136 return (op_table
[i
].op_id
);
138 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
141 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
146 * process_get_request_from_doc --
147 * looks for the object through the context ptr and gets the object
148 * name. Possible object types are Node, DD, DD set and server-config.
150 * ctext: context ptr for the original doc to parse request info.
151 * req: request to be filled up.
153 * Returns 0 if successful or an error code otherwise.
156 process_get_request_from_doc(xmlXPathContextPtr ctext
, request_t
*req
)
158 xmlChar expr
[ISNS_MAX_LABEL_LEN
+ 13];
159 xmlXPathObjectPtr xpath_obj
= NULL
;
160 xmlNodeSetPtr r_nodes
= NULL
;
161 xmlAttrPtr attr
= NULL
;
166 isnslog(LOG_DEBUG
, "process_get_request_from_doc", "entered");
167 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
168 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=", ISNSOBJECT
);
169 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
170 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
171 (xpath_obj
->nodesetval
->nodeTab
) &&
172 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
173 (xpath_obj
->nodesetval
->nodeTab
[0]->children
) &&
174 (xpath_obj
->nodesetval
->nodeTab
[0]->children
->name
)) {
175 for (i
= 0; obj_table
[i
].obj_str
!= NULL
; i
++) {
177 * To handle DiscoveryDomain and DiscoveryDomainSet
178 * searches isnsobject instead of the object directly.
181 xpath_obj
->nodesetval
->nodeTab
[0]->children
->name
,
182 (xmlChar
*)obj_table
[i
].obj_str
, xmlStrlen(
183 xpath_obj
->nodesetval
->nodeTab
[0]->children
->name
))
185 obj
= obj_table
[i
].obj_id
;
189 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
193 /* check the server config request. */
194 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
195 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=", ISNSSERVER
);
196 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
197 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
198 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
199 (xpath_obj
->nodesetval
->nodeTab
)) {
200 for (i
= 0; obj_table
[i
].obj_str
!= NULL
; i
++) {
201 if (strncmp(ISNSSERVER
, obj_table
[i
].obj_str
,
202 strlen(ISNSSERVER
)) == 0) {
203 obj
= obj_table
[i
].obj_id
;
208 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
212 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
215 req
->op_info
.obj
= obj
;
217 if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
218 ISNS_MGMT_OBJECT_TYPE(obj
);
221 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 12,
222 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=",
223 obj_table
[i
].obj_str
);
224 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
225 if (((xpath_obj
== NULL
) || (xpath_obj
->nodesetval
== NULL
) ||
226 (xpath_obj
->nodesetval
->nodeNr
<= 0) ||
227 (xpath_obj
->nodesetval
->nodeTab
== NULL
))) {
228 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
229 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
233 /* using the same algorithm for isns object */
235 case DiscoveryDomain
:
236 case DiscoveryDomainSet
:
237 r_nodes
= xpath_obj
->nodesetval
;
238 cnt
= r_nodes
->nodeNr
;
240 req
->req_data
.data
= (xmlChar
**) malloc(sizeof (xmlChar
*));
241 for (i
= 0; i
< cnt
; i
++) {
242 attr
= r_nodes
->nodeTab
[i
]->properties
;
243 for (; attr
!= NULL
; attr
= attr
->next
) {
244 if (xmlStrncmp(attr
->name
, (xmlChar
*)NAMEATTR
,
245 xmlStrlen((xmlChar
*)NAMEATTR
)) == 0) {
247 NEW_REQARGV(req
->req_data
.data
, req
->count
);
248 if (req
->req_data
.data
== (xmlChar
**)NULL
) {
250 xmlXPathFreeObject(xpath_obj
);
251 return (ERR_MALLOC_FAILED
);
253 req
->req_data
.data
[req
->count
] =
254 xmlNodeGetContent(attr
->children
);
255 req
->req_data
.data
[++req
->count
] = NULL
;
261 /* indication the obj type is sufficient. */
264 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
265 return (ERR_XML_OP_FAILED
);
268 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
273 * process_enumerate_request_from_doc --
274 * looks for the object through the context ptr and sets the
275 * request with object type.
277 * ctext: context ptr for the original doc to parse request info.
278 * req: request to be filled up.
280 * Returns 0 if successful or an error code otherwise.
283 process_enumerate_request_from_doc(xmlXPathContextPtr ctext
, request_t
*req
)
285 xmlChar expr
[ISNS_MAX_LABEL_LEN
+ 13];
286 xmlXPathObjectPtr xpath_obj
= NULL
;
291 isnslog(LOG_DEBUG
, "process_enumerate_request_from_doc", "entered");
292 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
293 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=", ISNSOBJECTTYPE
);
294 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
295 isnslog(LOG_DEBUG
, "process_enumerate_request_from_doc",
296 "xpath obj->nodesetval->nodeNR: %d", xpath_obj
->nodesetval
->nodeNr
);
297 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
298 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
299 (xpath_obj
->nodesetval
->nodeTab
)) {
300 for (i
= 0; obj_table
[i
].obj_str
!= NULL
; i
++) {
302 xpath_obj
->nodesetval
->nodeTab
[0]->children
->content
,
303 (xmlChar
*)obj_table
[i
].obj_str
, xmlStrlen((xmlChar
*)
304 xpath_obj
->nodesetval
->nodeTab
[0]->children
->content
))
306 obj
= obj_table
[i
].obj_id
;
311 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
312 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
315 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
318 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
321 req
->op_info
.obj
= obj
;
323 if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
324 ISNS_MGMT_OBJECT_TYPE(obj
);
331 * process_getAssociated_request_from_doc --
332 * first looks for association type through the contexti and then
333 * find out the given object. That will indicate the direction of
334 * association, containter to member or vice versa.
335 * Lastly it extract the object name form the doc that assocation
338 * ctext: context ptr for the original doc to parse request info.
339 * req: request to be filled up.
341 * Returns 0 if successful or an error code otherwise.
344 process_getAssociated_request_from_doc(xmlXPathContextPtr ctext
, request_t
*req
)
346 xmlChar expr
[ISNS_MAX_LABEL_LEN
+ 13];
347 xmlXPathObjectPtr xpath_obj
= NULL
;
348 xmlNodeSetPtr r_nodes
= NULL
;
349 xmlAttrPtr attr
= NULL
;
352 isnslog(LOG_DEBUG
, "process_getAssociated_request_from_doc", "entered");
353 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
354 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=", ASSOCIATIONTYPE
);
355 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
356 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
357 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
358 (xpath_obj
->nodesetval
->nodeTab
)) {
359 for (i
= 0; obj_table
[i
].obj_str
!= NULL
; i
++) {
361 xpath_obj
->nodesetval
->nodeTab
[0]->children
->content
,
362 (xmlChar
*)obj_table
[i
].obj_str
, xmlStrlen(
363 xpath_obj
->nodesetval
->nodeTab
[0]->children
->content
))
365 obj
= obj_table
[i
].obj_id
;
371 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
374 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
377 req
->op_info
.obj
= obj
;
379 if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
380 ISNS_MGMT_OBJECT_TYPE(obj
);
384 /* using the same algorithm for isns object */
385 case DiscoveryDomainMember
:
386 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
387 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=", NODEOBJECT
);
388 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
389 r_nodes
= xpath_obj
->nodesetval
;
390 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
391 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
392 (xpath_obj
->nodesetval
->nodeTab
)) {
393 req
->assoc_req
= member_to_container
;
395 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
396 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
397 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=",
399 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
400 r_nodes
= xpath_obj
->nodesetval
;
401 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
402 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
403 (xpath_obj
->nodesetval
->nodeTab
)) {
404 req
->assoc_req
= container_to_member
;
406 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
407 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
411 case DiscoveryDomainSetMember
:
412 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
413 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=", DDSETOBJECT
);
414 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
415 r_nodes
= xpath_obj
->nodesetval
;
416 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
417 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
418 (xpath_obj
->nodesetval
->nodeTab
)) {
419 req
->assoc_req
= container_to_member
;
421 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
422 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
423 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=",
425 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
426 r_nodes
= xpath_obj
->nodesetval
;
427 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
428 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
429 (xpath_obj
->nodesetval
->nodeTab
)) {
430 req
->assoc_req
= member_to_container
;
432 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
433 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
438 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
439 return (ERR_XML_OP_FAILED
);
442 /* now process the name attr */
443 cnt
= r_nodes
->nodeNr
;
445 req
->req_data
.data
= (xmlChar
**) malloc(sizeof (xmlChar
*));
446 /* for (i = cnt - 1; i >= 0; i--) { */
447 for (i
= 0; i
< cnt
; i
++) {
448 attr
= r_nodes
->nodeTab
[i
]->properties
;
449 for (; attr
!= NULL
; attr
= attr
->next
) {
450 if (xmlStrncmp(attr
->name
, (xmlChar
*)NAMEATTR
,
451 xmlStrlen((xmlChar
*)NAMEATTR
)) == 0) {
453 NEW_REQARGV(req
->req_data
.data
, req
->count
);
454 if (req
->req_data
.data
== (xmlChar
**)NULL
) {
455 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
456 return (ERR_MALLOC_FAILED
);
458 req
->req_data
.data
[req
->count
++] =
459 xmlNodeGetContent(attr
->children
);
460 req
->req_data
.data
[req
->count
] = NULL
;
465 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
470 * process_delete_request_from_doc --
471 * first looks for the object through the context ptr and sets the
472 * request with additional data.
473 * For DD and DD set, the name is given.
474 * For DD and DD set membership, container and member pairs are given.
476 * ctext: context ptr for the original doc to parse request info.
477 * req: request to be filled up.
479 * Returns 0 if successful or an error code otherwise.
482 process_delete_request_from_doc(xmlXPathContextPtr ctext
, request_t
*req
)
484 xmlChar expr
[ISNS_MAX_LABEL_LEN
+ 13];
485 xmlXPathObjectPtr xpath_obj
= NULL
;
486 xmlNodeSetPtr r_nodes
= NULL
;
487 xmlAttrPtr attr
= NULL
;
488 xmlChar
*container
= NULL
, *member
= NULL
;
493 isnslog(LOG_DEBUG
, "process_delete_request_from_doc", "entered");
494 for (i
= 0; obj_table
[i
].obj_str
!= NULL
; i
++) {
495 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
496 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=",
497 obj_table
[i
].obj_str
);
498 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
499 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
500 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
501 (xpath_obj
->nodesetval
->nodeTab
)) {
502 obj
= obj_table
[i
].obj_id
;
505 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
509 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
512 req
->op_info
.obj
= obj
;
514 if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
515 ISNS_MGMT_OBJECT_TYPE(obj
);
519 case DiscoveryDomainMember
:
520 /* at least one object exists to get here. */
521 r_nodes
= xpath_obj
->nodesetval
;
522 cnt
= r_nodes
->nodeNr
;
525 (assoc_pair_t
**)malloc(sizeof (assoc_pair_t
*));
526 for (i
= 0; i
< cnt
; i
++) {
527 attr
= r_nodes
->nodeTab
[i
]->properties
;
528 for (; attr
!= NULL
; attr
= attr
->next
) {
529 if (xmlStrncmp(attr
->name
, (xmlChar
*)DDNAMEATTR
,
530 xmlStrlen((xmlChar
*)DDNAMEATTR
)) == 0) {
532 xmlNodeGetContent(attr
->children
);
534 if (xmlStrncmp(attr
->name
, (xmlChar
*)NODENAMEATTR
,
535 xmlStrlen((xmlChar
*)NODENAMEATTR
)) == 0) {
537 xmlNodeGetContent(attr
->children
);
540 if (container
!= NULL
&& member
!= NULL
) {
542 NEW_REQPAIRARGV(req
->req_data
.pair
, req
->count
);
543 if (req
->req_data
.pair
== (assoc_pair_t
**)NULL
) {
544 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
545 return (ERR_MALLOC_FAILED
);
547 req
->req_data
.pair
[req
->count
] = (assoc_pair_t
*)
548 malloc(sizeof (assoc_pair_t
));
549 if (req
->req_data
.pair
[req
->count
] == NULL
) {
550 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
551 return (ERR_MALLOC_FAILED
);
553 req
->req_data
.pair
[req
->count
]->container
=
555 req
->req_data
.pair
[req
->count
]->member
=
557 req
->req_data
.data
[++req
->count
] = NULL
;
559 if (container
!= NULL
) {
562 if (member
!= NULL
) {
565 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
566 return (ERR_XML_OP_FAILED
);
571 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
573 case DiscoveryDomainSetMember
:
574 /* at least one object exists to get here. */
575 r_nodes
= xpath_obj
->nodesetval
;
576 cnt
= r_nodes
->nodeNr
;
579 (assoc_pair_t
**)malloc(sizeof (assoc_pair_t
*));
580 for (i
= 0; i
< cnt
; i
++) {
581 attr
= r_nodes
->nodeTab
[i
]->properties
;
582 for (; attr
!= NULL
; attr
= attr
->next
) {
583 if (xmlStrncmp(attr
->name
, (xmlChar
*)DDSETNAMEATTR
,
584 xmlStrlen((xmlChar
*)DDNAMEATTR
)) == 0) {
586 xmlNodeGetContent(attr
->children
);
588 if (xmlStrncmp(attr
->name
, (xmlChar
*)DDNAMEATTR
,
589 xmlStrlen((xmlChar
*)NODENAMEATTR
)) == 0) {
591 xmlNodeGetContent(attr
->children
);
594 if (container
!= NULL
&& member
!= NULL
) {
596 NEW_REQPAIRARGV(req
->req_data
.pair
, req
->count
);
597 if (req
->req_data
.pair
== (assoc_pair_t
**)NULL
) {
598 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
599 return (ERR_MALLOC_FAILED
);
601 req
->req_data
.pair
[req
->count
] = (assoc_pair_t
*)
602 malloc(sizeof (assoc_pair_t
));
603 if (req
->req_data
.pair
[req
->count
] == NULL
) {
604 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
605 return (ERR_MALLOC_FAILED
);
607 req
->req_data
.pair
[req
->count
]->container
=
609 req
->req_data
.pair
[req
->count
++]->member
=
611 req
->req_data
.data
[req
->count
] = NULL
;
613 if (container
!= NULL
) {
616 if (member
!= NULL
) {
619 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
620 return (ERR_XML_OP_FAILED
);
623 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
625 case DiscoveryDomain
:
626 case DiscoveryDomainSet
:
627 r_nodes
= xpath_obj
->nodesetval
;
628 cnt
= r_nodes
->nodeNr
;
630 req
->req_data
.data
= (xmlChar
**) malloc(sizeof (xmlChar
*));
631 for (i
= 0; i
< cnt
; i
++) {
632 attr
= r_nodes
->nodeTab
[i
]->properties
;
633 for (; attr
!= NULL
; attr
= attr
->next
) {
634 if (xmlStrncmp(attr
->name
, (xmlChar
*)NAMEATTR
,
635 xmlStrlen((xmlChar
*)NAMEATTR
)) == 0) {
637 NEW_REQARGV(req
->req_data
.data
, req
->count
);
638 if (req
->req_data
.data
== (xmlChar
**)NULL
) {
640 xmlXPathFreeObject(xpath_obj
);
641 return (ERR_MALLOC_FAILED
);
643 req
->req_data
.data
[req
->count
] =
644 xmlNodeGetContent(attr
->children
);
645 req
->req_data
.data
[++req
->count
] = NULL
;
649 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
652 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
653 return (ERR_XML_OP_FAILED
);
660 * process_createModify_request_from_doc --
661 * first looks for the object through the context ptr and sets the
662 * request with additional data.
663 * For DD and DD set, the name is given.
664 * For DD and DD set membership, container and member pairs are given.
666 * ctext: context ptr for the original doc to parse request info.
667 * req: request to be filled up.
669 * Returns 0 if successful or an error code otherwise.
672 process_createModify_request_from_doc(xmlXPathContextPtr ctext
, request_t
*req
)
674 xmlChar expr
[ISNS_MAX_LABEL_LEN
+ 13];
675 xmlXPathObjectPtr xpath_obj
= NULL
;
676 xmlNodeSetPtr r_nodes
= NULL
;
677 xmlAttrPtr attr
= NULL
;
678 xmlChar
*container
= NULL
, *member
= NULL
, *xml_id
;
683 isnslog(LOG_DEBUG
, "process_createModify_request_from_doc", "entered");
684 for (i
= 0; obj_table
[i
].obj_str
!= NULL
; i
++) {
685 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
686 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=",
687 obj_table
[i
].obj_str
);
688 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
689 if ((xpath_obj
) && (xpath_obj
->nodesetval
) &&
690 (xpath_obj
->nodesetval
->nodeNr
> 0) &&
691 (xpath_obj
->nodesetval
->nodeTab
)) {
692 obj
= obj_table
[i
].obj_id
;
695 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
699 return (ERR_XML_VALID_OBJECT_NOT_FOUND
);
702 req
->op_info
.obj
= obj
;
704 if (ISNS_MGMT_OBJECT_TYPE_ENABLED()) {
705 ISNS_MGMT_OBJECT_TYPE(obj
);
709 case DiscoveryDomainMember
:
710 /* at least one object exists to get here. */
711 r_nodes
= xpath_obj
->nodesetval
;
712 cnt
= r_nodes
->nodeNr
;
715 (assoc_pair_t
**)malloc(sizeof (assoc_pair_t
*));
716 for (i
= 0; i
< cnt
; i
++) {
717 attr
= r_nodes
->nodeTab
[i
]->properties
;
718 for (; attr
!= NULL
; attr
= attr
->next
) {
719 if (xmlStrncmp(attr
->name
, (xmlChar
*)DDNAMEATTR
,
720 xmlStrlen((xmlChar
*)DDNAMEATTR
)) == 0) {
722 xmlNodeGetContent(attr
->children
);
724 if (xmlStrncmp(attr
->name
, (xmlChar
*)NODENAMEATTR
,
725 xmlStrlen((xmlChar
*)NODENAMEATTR
)) == 0) {
727 xmlNodeGetContent(attr
->children
);
730 if (container
!= NULL
&& member
!= NULL
) {
732 NEW_REQPAIRARGV(req
->req_data
.pair
, req
->count
);
733 if (req
->req_data
.pair
== (assoc_pair_t
**)NULL
) {
734 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
735 return (ERR_MALLOC_FAILED
);
737 req
->req_data
.pair
[req
->count
] = (assoc_pair_t
*)
738 malloc(sizeof (assoc_pair_t
));
739 if (req
->req_data
.pair
[req
->count
] == NULL
) {
740 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
741 return (ERR_MALLOC_FAILED
);
743 req
->req_data
.pair
[req
->count
]->container
=
745 req
->req_data
.pair
[req
->count
]->member
=
747 req
->req_data
.data
[++req
->count
] = NULL
;
749 if (container
!= NULL
) {
752 if (member
!= NULL
) {
755 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
756 return (ERR_XML_OP_FAILED
);
758 container
= member
= NULL
;
760 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
762 case DiscoveryDomainSetMember
:
763 /* at least one object exists to get here. */
764 r_nodes
= xpath_obj
->nodesetval
;
765 cnt
= r_nodes
->nodeNr
;
768 (assoc_pair_t
**)malloc(sizeof (assoc_pair_t
*));
769 for (i
= 0; i
< cnt
; i
++) {
770 attr
= r_nodes
->nodeTab
[i
]->properties
;
771 for (; attr
!= NULL
; attr
= attr
->next
) {
772 if (xmlStrncmp(attr
->name
, (xmlChar
*)DDSETNAMEATTR
,
773 xmlStrlen((xmlChar
*)DDSETNAMEATTR
)) == 0) {
775 xmlNodeGetContent(attr
->children
);
777 if (xmlStrncmp(attr
->name
, (xmlChar
*)DDNAMEATTR
,
778 xmlStrlen((xmlChar
*)DDNAMEATTR
)) == 0) {
780 xmlNodeGetContent(attr
->children
);
783 if (container
!= NULL
&& member
!= NULL
) {
785 NEW_REQPAIRARGV(req
->req_data
.pair
, req
->count
);
786 if (req
->req_data
.pair
== (assoc_pair_t
**)NULL
) {
787 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
788 return (ERR_MALLOC_FAILED
);
790 req
->req_data
.pair
[req
->count
] = (assoc_pair_t
*)
791 malloc(sizeof (assoc_pair_t
));
792 if (req
->req_data
.pair
[req
->count
] == NULL
) {
793 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
794 return (ERR_MALLOC_FAILED
);
796 req
->req_data
.pair
[req
->count
]->container
=
798 req
->req_data
.pair
[req
->count
]->member
=
800 req
->req_data
.data
[++req
->count
] = NULL
;
802 if (container
!= NULL
) {
805 if (member
!= NULL
) {
808 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
809 return (ERR_XML_OP_FAILED
);
811 container
= member
= NULL
;
813 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
815 case DiscoveryDomain
:
816 case DiscoveryDomainSet
:
817 /* at least one object exists to get here. */
818 r_nodes
= xpath_obj
->nodesetval
;
819 cnt
= r_nodes
->nodeNr
;
821 req
->req_data
.attrlist
=
822 (object_attrlist_t
**)malloc(sizeof (object_attrlist_t
*));
823 for (i
= 0; i
< cnt
; i
++) {
824 req
->req_data
.attrlist
=
825 NEW_REQATTRLISTARGV(req
->req_data
.attrlist
, req
->count
);
826 if (req
->req_data
.attrlist
==
827 (object_attrlist_t
**)NULL
) {
828 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
829 return (ERR_MALLOC_FAILED
);
831 req
->req_data
.attrlist
[req
->count
] = (object_attrlist_t
*)
832 malloc(sizeof (object_attrlist_t
));
833 if (req
->req_data
.attrlist
[req
->count
] == NULL
) {
834 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
835 return (ERR_MALLOC_FAILED
);
837 req
->req_data
.attrlist
[req
->count
]->name
= NULL
;
838 req
->req_data
.attrlist
[req
->count
]->id
= NULL
;
839 req
->req_data
.attrlist
[req
->count
]->enabled
= NULL
;
840 attr
= r_nodes
->nodeTab
[i
]->properties
;
841 for (; attr
!= NULL
; attr
= attr
->next
) {
842 if ((xmlStrncmp(attr
->name
, (xmlChar
*)NAMEATTR
,
843 xmlStrlen((xmlChar
*)NAMEATTR
))) == 0) {
844 req
->req_data
.attrlist
[req
->count
]->name
=
845 xmlNodeGetContent(attr
->children
);
847 if ((xmlStrncmp(attr
->name
, (xmlChar
*)IDATTR
,
848 xmlStrlen((xmlChar
*)IDATTR
))) == 0) {
849 req
->req_data
.attrlist
[req
->count
]->id
=
850 (uint32_t *)calloc(1, sizeof (uint32_t));
851 if (req
->req_data
.attrlist
[req
->count
]->id
==
854 xmlXPathFreeObject(xpath_obj
);
855 return (ERR_MALLOC_FAILED
);
857 xml_id
= xmlNodeGetContent(attr
->children
);
858 if (xml_id
!= NULL
) {
859 *(req
->req_data
.attrlist
[req
->count
]->id
) =
860 atoi((const char *)xml_id
);
866 * check the enabled element.
867 * Only one child element so check the children ptr.
869 if (r_nodes
->nodeTab
[i
]->children
) {
870 req
->req_data
.attrlist
[req
->count
]->enabled
=
871 (boolean_t
*)malloc(sizeof (boolean_t
));
872 if (req
->req_data
.attrlist
[req
->count
]->enabled
874 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
875 return (ERR_MALLOC_FAILED
);
877 /* value is children of enabled. */
879 r_nodes
->nodeTab
[i
]->children
->children
->content
,
880 (xmlChar
*)XMLTRUE
, xmlStrlen((xmlChar
*)XMLTRUE
))
882 *(req
->req_data
.attrlist
[req
->count
]->enabled
)
885 *(req
->req_data
.attrlist
[req
->count
]->enabled
)
889 req
->req_data
.attrlist
[++req
->count
] = NULL
;
891 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
894 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
895 return (ERR_XML_OP_FAILED
);
902 * build_mgmt_request -- extracts the request info from the given XML doc.
904 * x_doc: ptr to the request XML doc
905 * req: ptr to the request struct to be filled up.
907 * Return value: ISNS_RSP_SUCCESSFUL if successful or an error code.
910 process_mgmt_request(xmlDocPtr x_doc
, request_t
*req
, ucred_t
*uc
)
914 xmlXPathContextPtr ctext
= NULL
;
916 struct passwd pwds
, *pwd
;
920 isnslog(LOG_DEBUG
, "process_mgmt_request", "entered");
921 (void) memset(req
, 0, sizeof (request_t
));
922 /* get the operation first. */
923 ctext
= xmlXPathNewContext(x_doc
);
925 return (ERR_XML_FAILED_TO_SET_XPATH_CONTEXT
);
928 isnslog(LOG_DEBUG
, "process_mgmt_request", "xpath context succeeded");
929 op
= get_op_id_from_doc(ctext
);
931 if (ctext
) xmlXPathFreeContext(ctext
);
932 return (ERR_XML_VALID_OPERATION_NOT_FOUND
);
935 user
= ucred_getruid(uc
);
936 ret
= getpwuid_r(user
, &pwds
, buf_pwd
, sizeof (buf_pwd
), &pwd
);
938 if (ctext
) xmlXPathFreeContext(ctext
);
939 return (ERR_DOOR_SERVER_DETECTED_INVALID_USER
);
942 /* write operations are restricted. */
943 if ((op
== delete_op
) || (op
== createModify_op
)) {
944 if (!chkauthattr(ISNS_ADMIN_WRITE_AUTH
, pwd
->pw_name
)) {
945 if (ctext
) xmlXPathFreeContext(ctext
);
946 return (ERR_DOOR_SERVER_DETECTED_NOT_AUTHORIZED_USER
);
950 req
->op_info
.op
= op
;
952 if (ISNS_MGMT_OPERATION_TYPE_ENABLED()) {
953 ISNS_MGMT_OPERATION_TYPE(op
);
958 ret
= process_get_request_from_doc(ctext
, req
);
960 case (getAssociated_op
):
961 ret
= process_getAssociated_request_from_doc(ctext
, req
);
964 ret
= process_enumerate_request_from_doc(ctext
, req
);
967 ret
= process_delete_request_from_doc(ctext
, req
);
969 case (createModify_op
):
970 ret
= process_createModify_request_from_doc(ctext
, req
);
973 ret
= ERR_XML_VALID_OPERATION_NOT_FOUND
;
976 if (ctext
) xmlXPathFreeContext(ctext
);
981 * build_mgmt_response -- sets an XML doc with a root and calls a porper
982 * routine based on the request. If the called routine constructed
983 * the response doc with the result element, this routine fills up
984 * response buffer with raw XML doc.
986 * reponse: ptr to response buffer
987 * req: request to be processed.
988 * size: ptr to the response doc buffer
991 build_mgmt_response(xmlChar
**response
, request_t req
, int *size
)
997 xmlXPathContextPtr ctext
= NULL
;
998 xmlChar expr
[ISNS_MAX_LABEL_LEN
+ 13];
999 xmlXPathObjectPtr xpath_obj
= NULL
;
1001 isnslog(LOG_DEBUG
, "build_mgmt_response", "entered");
1003 doc
= xmlNewDoc((uchar_t
*)"1.0");
1004 root
= xmlNewNode(NULL
, (xmlChar
*)ISNSRESPONSE
);
1005 (void) xmlDocSetRootElement(doc
, root
);
1006 if (xmlSetProp(root
, (xmlChar
*)XMLNSATTR
, (xmlChar
*)XMLNSATTRVAL
) ==
1008 return (ERR_XML_SETPROP_FAILED
);
1011 switch (req
.op_info
.op
) {
1013 switch (req
.op_info
.obj
) {
1015 ret
= get_node_op(&req
, doc
);
1017 case DiscoveryDomain
:
1018 ret
= get_dd_op(&req
, doc
);
1020 case DiscoveryDomainSet
:
1021 ret
= get_ddset_op(&req
, doc
);
1024 ret
= get_serverconfig_op(doc
);
1027 ret
= ERR_INVALID_MGMT_REQUEST
;
1031 isnslog(LOG_DEBUG
, "build_mgmt_response", "enumerate_op");
1032 switch (req
.op_info
.obj
) {
1034 ret
= enumerate_node_op(doc
);
1036 case DiscoveryDomain
:
1037 ret
= enumerate_dd_op(doc
);
1039 case DiscoveryDomainSet
:
1040 ret
= enumerate_ddset_op(doc
);
1043 ret
= ERR_INVALID_MGMT_REQUEST
;
1046 case getAssociated_op
:
1047 switch (req
.op_info
.obj
) {
1048 case DiscoveryDomainMember
:
1049 if (req
.assoc_req
== container_to_member
) {
1050 ret
= getAssociated_dd_to_node_op(&req
, doc
);
1052 ret
= getAssociated_node_to_dd_op(&req
, doc
);
1055 case DiscoveryDomainSetMember
:
1056 if (req
.assoc_req
== container_to_member
) {
1057 ret
= getAssociated_ddset_to_dd_op(&req
, doc
);
1059 ret
= getAssociated_dd_to_ddset_op(&req
, doc
);
1063 ret
= ERR_INVALID_MGMT_REQUEST
;
1066 case createModify_op
:
1067 switch (req
.op_info
.obj
) {
1068 case DiscoveryDomain
:
1069 case DiscoveryDomainSet
:
1070 ret
= createModify_dd_ddset_op(&req
, doc
);
1072 case DiscoveryDomainMember
:
1073 case DiscoveryDomainSetMember
:
1074 ret
= create_ddmember_ddsetmember_op(&req
, doc
,
1078 ret
= ERR_INVALID_MGMT_REQUEST
;
1082 switch (req
.op_info
.obj
) {
1083 case DiscoveryDomainMember
:
1084 case DiscoveryDomainSetMember
:
1085 ret
= delete_ddmember_ddsetmember_op(&req
, doc
,
1088 case DiscoveryDomain
:
1089 case DiscoveryDomainSet
:
1090 ret
= delete_dd_ddset_op(&req
, doc
, req
.op_info
.obj
);
1093 ret
= ERR_INVALID_MGMT_REQUEST
;
1097 ret
= ERR_INVALID_MGMT_REQUEST
;
1101 * if failed check to see the doc contains the result element.
1102 * if not, the response is set with only an error code.
1104 if (ret
!= ISNS_RSP_SUCCESSFUL
) {
1105 ctext
= xmlXPathNewContext(doc
);
1106 if (ctext
!= NULL
) {
1107 (void) xmlStrPrintf(expr
, ISNS_MAX_LABEL_LEN
+ 13,
1108 XMLSTRING_CAST
"%s\"%s\"]", "//*[name()=", RESULT
);
1109 xpath_obj
= xmlXPathEvalExpression(expr
, ctext
);
1110 if ((xpath_obj
== NULL
) || (xpath_obj
->nodesetval
== NULL
) ||
1111 (xpath_obj
->nodesetval
->nodeNr
<= 0) ||
1112 (xpath_obj
->nodesetval
->nodeTab
== NULL
)) {
1114 "build_mgmt_response",
1115 "returning repsonse only with error code %d\n", ret
);
1116 *response
= malloc(sizeof (ret
));
1117 if (*response
) **response
= ret
;
1118 *size
= sizeof (ret
);
1120 xmlDocDumpMemory(doc
, response
, size
);
1123 /* can't verify the xml doc. dump return the doc anyway. */
1124 xmlDocDumpMemory(doc
, response
, size
);
1127 xmlDocDumpMemory(doc
, response
, size
);
1130 if (xpath_obj
) xmlXPathFreeObject(xpath_obj
);
1131 if (ctext
) xmlXPathFreeContext(ctext
);
1132 if (doc
) xmlFreeDoc(doc
);
1137 * build_result_message -- construct a response doc with the given result.
1138 * Result contains status code and message.
1140 * reponse: ptr to response doc
1142 * size: ptr to the response doc size
1145 build_result_message(xmlChar
**response
, result_code_t code
, int *size
)
1147 int ret
= ISNS_RSP_SUCCESSFUL
;
1149 xmlNodePtr root
, n_obj
;
1152 isnslog(LOG_DEBUG
, "build_result_response", "entered");
1154 doc
= xmlNewDoc((uchar_t
*)"1.0");
1155 root
= xmlNewNode(NULL
, (xmlChar
*)ISNSRESPONSE
);
1156 (void) xmlDocSetRootElement(doc
, root
);
1158 n_obj
= xmlNewChild(root
, NULL
, (xmlChar
*)RESULT
, NULL
);
1160 if (code
== ISNS_RSP_SUCCESSFUL
) {
1161 (void) sprintf(numbuf
, "%d", ISNS_RSP_SUCCESSFUL
);
1162 if (xmlNewChild(n_obj
, NULL
, (xmlChar
*)STATUSELEMENT
,
1163 (xmlChar
*)numbuf
) == NULL
) {
1164 ret
= ERR_XML_NEWCHILD_FAILED
;
1167 (void) sprintf(numbuf
, "%d", code
);
1168 if (xmlNewChild(n_obj
, NULL
, (xmlChar
*)STATUSELEMENT
,
1169 (xmlChar
*)numbuf
) == NULL
) {
1170 ret
= ERR_XML_NEWCHILD_FAILED
;
1172 if (xmlNewChild(n_obj
, NULL
, (xmlChar
*)MESSAGEELEMENT
,
1173 (xmlChar
*)result_code_to_str(code
)) == NULL
) {
1174 ret
= ERR_XML_NEWCHILD_FAILED
;
1178 xmlDocDumpMemory(doc
, response
, size
);
1180 if (doc
) xmlFreeDoc(doc
);
1185 * cleanup_request -- deallocatate memory associated with the given request
1189 cleanup_request(request_t req
)
1193 isnslog(LOG_DEBUG
, "cleanup_request", "entered");
1194 switch (req
.op_info
.op
) {
1196 for (i
= 0; i
< req
.count
; i
++) {
1197 if (req
.req_data
.data
[i
])
1198 xmlFree(req
.req_data
.data
[i
]);
1200 free(req
.req_data
.data
);
1202 case (getAssociated_op
):
1203 for (i
= 0; i
< req
.count
; i
++) {
1204 if (req
.req_data
.data
[i
])
1205 xmlFree(req
.req_data
.data
[i
]);
1207 free(req
.req_data
.data
);
1209 case (enumerate_op
):
1212 if ((req
.op_info
.obj
== DiscoveryDomainMember
) ||
1213 (req
.op_info
.obj
== DiscoveryDomainSetMember
)) {
1214 for (i
= 0; i
< req
.count
; i
++) {
1215 if (req
.req_data
.pair
[i
]->container
)
1216 xmlFree(req
.req_data
.pair
[i
]->container
);
1217 if (req
.req_data
.pair
[i
]->member
)
1218 xmlFree(req
.req_data
.pair
[i
]->member
);
1219 free(req
.req_data
.pair
[i
]);
1221 free(req
.req_data
.pair
);
1223 for (i
= 0; i
< req
.count
; i
++) {
1224 if (req
.req_data
.data
[i
])
1225 xmlFree(req
.req_data
.data
[i
]);
1227 free(req
.req_data
.data
);
1230 case (createModify_op
):
1231 if ((req
.op_info
.obj
== DiscoveryDomainMember
) ||
1232 (req
.op_info
.obj
== DiscoveryDomainSetMember
)) {
1233 for (i
= 0; i
< req
.count
; i
++) {
1234 if (req
.req_data
.pair
[i
]->container
)
1235 xmlFree(req
.req_data
.pair
[i
]->container
);
1236 if (req
.req_data
.pair
[i
]->member
)
1237 xmlFree(req
.req_data
.pair
[i
]->member
);
1238 free(req
.req_data
.pair
[i
]);
1240 free(req
.req_data
.pair
);
1241 } else if ((req
.op_info
.obj
== DiscoveryDomain
) ||
1242 (req
.op_info
.obj
== DiscoveryDomainSet
)) {
1243 for (i
= 0; i
< req
.count
; i
++) {
1244 if (req
.req_data
.attrlist
[i
]->name
)
1245 xmlFree(req
.req_data
.attrlist
[i
]->name
);
1246 free(req
.req_data
.attrlist
[i
]->id
);
1247 free(req
.req_data
.attrlist
[i
]->enabled
);
1248 free(req
.req_data
.pair
[i
]);
1250 free(req
.req_data
.attrlist
);
1257 * Find a matching entry for the given thread id.
1259 static thr_elem_t
*match_entry(pthread_t tid
)
1262 thr_elem_t
*thr
= thr_list
;
1265 if (pthread_equal(thr
->thr_id
, tid
)) {
1275 * Add an entry to the thr_list for the given thread id.
1278 add_entry(pthread_t tid
, xmlChar
*doc
)
1282 thr_elem_t
*thr
= thr_list
;
1284 if ((new_e
= malloc(sizeof (thr_elem_t
))) == NULL
) {
1285 return (ERR_MALLOC_FAILED
);
1287 new_e
->thr_id
= tid
;
1291 if (thr_list
== NULL
) {
1300 return (ISNS_RSP_SUCCESSFUL
);
1304 * door_server -- proecess the management request and send response back
1307 * In order to handle allocation after door_return,
1308 * a global list, thr_list, is maintained to free the response buffer
1309 * from the previous invocation of the server function on the same thread.
1310 * Note: the door framework creates a thread and the same thread is used
1311 * while a new thread is created for concurrent door_calls.
1313 * If a thread is used once the buffer will be left allocated.
1317 door_server(void *cookie
, char *argp
, size_t arg_size
, door_desc_t
*dp
,
1322 xmlChar
*resp_buf
= NULL
;
1328 if (ISNS_MGMT_REQUEST_RECEIVED_ENABLED()) {
1329 ISNS_MGMT_REQUEST_RECEIVED();
1332 if (door_ucred(&uc
) != 0) {
1333 isnslog(LOG_DEBUG
, "door_server",
1334 "door_ucred failed. errno: %d\n", errno
);
1335 ret
= build_result_message(&resp_buf
,
1336 ERR_DOOR_UCRED_FAILED
, &size
);
1337 if (ret
== ISNS_RSP_SUCCESSFUL
) {
1338 (void) door_return((char *)resp_buf
, size
+ 1, NULL
, 0);
1341 ret
= ERR_DOOR_UCRED_FAILED
;
1342 (void) door_return((void *)&ret
, sizeof (ret
), NULL
, 0);
1347 isnslog(LOG_DEBUG
, "door_server", "entered with request:\n %s\n", argp
);
1348 if ((x_doc
= xmlParseMemory(argp
, arg_size
)) != NULL
) {
1349 isnslog(LOG_DEBUG
, "door_server", "ParseMemory succeeded");
1350 if ((ret
= process_mgmt_request(x_doc
, &req
, uc
)) == 0) {
1351 ret
= build_mgmt_response(&resp_buf
, req
, &size
);
1353 ret
= build_result_message(&resp_buf
, ret
, &size
);
1356 cleanup_request(req
);
1358 ret
= build_result_message(&resp_buf
,
1359 ERR_XML_PARSE_MEMORY_FAILED
, &size
);
1362 /* free the ucred */
1366 tid
= pthread_self();
1367 if ((thr
= match_entry(tid
)) == NULL
) {
1368 (void) add_entry(tid
, resp_buf
);
1370 isnslog(LOG_DEBUG
, "door_server",
1371 "free the previouly returned buffer %x on this thread\n",
1374 isnslog(LOG_DEBUG
, "door_server",
1375 "store the currently allocated buffer %x on this thread\n",
1377 thr
->doc
= resp_buf
;
1380 "door_server", "exiting with response:\n %s\n",
1381 (const char *)resp_buf
);
1383 if (ISNS_MGMT_REQUEST_RESPONDED_ENABLED()) {
1384 ISNS_MGMT_REQUEST_RESPONDED();
1387 (void) door_return((char *)resp_buf
, size
+ 1, NULL
, 0);
1392 "door_server", "exiting only with error code %d\n", ret
);
1394 if (ISNS_MGMT_REQUEST_RESPONDED_ENABLED()) {
1395 ISNS_MGMT_REQUEST_RESPONDED();
1398 (void) door_return((void *)&ret
, sizeof (ret
), NULL
, 0);
1403 * setup_mgmt_door -- Create a door portal for management application requests
1405 * First check to see if another daemon is already running by attempting
1406 * to send an empty request to the door. If successful it means this
1407 * daemon should exit.
1410 setup_mgmt_door(msg_queue_t
*sys_q
)
1416 isnslog(LOG_DEBUG
, "setup_mgmt_door", "entered");
1417 /* check if a door is already running. */
1418 if ((fd
= open(ISNS_DOOR_NAME
, O_RDONLY
)) >= 0) {
1419 darg
.data_ptr
= "<?xml version='1.0' encoding='UTF-8'?>"
1420 "<isnsRequest><get><isnsObject>"
1421 "<DiscoveryDomain name=\"default\">"
1422 "</DiscoveryDomain></isnsObject></get>"
1424 darg
.data_size
= xmlStrlen((xmlChar
*)darg
.data_ptr
) + 1;
1425 darg
.desc_ptr
= NULL
;
1430 if (door_call(fd
, &darg
) == 0) {
1431 /* door already running. */
1433 isnslog(LOG_DEBUG
, "setup_mgmt_door",
1434 "management door is already runninng.");
1435 if (darg
.rsize
> darg
.data_size
) {
1436 (void) munmap(darg
.rbuf
, darg
.rsize
);
1438 door_created
= B_FALSE
;
1444 if ((door_id
= door_create(door_server
, (void *)sys_q
, 0)) < 0) {
1445 isnslog(LOG_DEBUG
, "setup_mgmt_door",
1446 "Failed to create managment door");
1450 if (stat(ISNS_DOOR_NAME
, &buf
) < 0) {
1451 if ((fd
= creat(ISNS_DOOR_NAME
, 0666)) < 0) {
1452 isnslog(LOG_DEBUG
, "setup_mgmt_door",
1453 "open failed on %s errno = %d", ISNS_DOOR_NAME
, errno
);
1459 /* make sure the file permission set to general access. */
1460 (void) chmod(ISNS_DOOR_NAME
, 0666);
1461 (void) fdetach(ISNS_DOOR_NAME
);
1463 if (fattach(door_id
, ISNS_DOOR_NAME
) < 0) {
1464 syslog(LOG_DEBUG
, "setup_mgmt_door",
1465 "fattach failed on %s errno=%d",
1466 ISNS_DOOR_NAME
, errno
);
1470 door_created
= B_TRUE
;