2
* isnsadm - helper utility
4
* Copyright (C) 2007 Olaf Kirch <olaf.kirch@oracle.com>
23
#define ISNS_DEFAULT_PORT_INITIATOR 860
24
#define ISNS_DEFAULT_PORT_TARGET 3260
40
static struct option options[] = {
41
{ "help", no_argument, NULL, 'h' },
42
{ "config", required_argument, NULL, 'c' },
43
{ "debug", required_argument, NULL, 'd' },
44
{ "keyfile", required_argument, NULL, 'K', },
45
{ "key", required_argument, NULL, 'k', },
46
{ "local", no_argument, NULL, 'l' },
47
{ "control", no_argument, NULL, 'C' },
48
{ "replace", no_argument, NULL, 'r' },
49
{ "query", no_argument, NULL, DO_QUERY },
50
{ "query-eid", no_argument, NULL, DO_QUERY_EID },
51
{ "list", no_argument, NULL, DO_LIST },
52
{ "register", no_argument, NULL, DO_REGISTER },
53
{ "deregister", no_argument, NULL, DO_DEREGISTER },
54
{ "dd-register", no_argument, NULL, DO_DD_REGISTER },
55
{ "dd-deregister", no_argument, NULL, DO_DD_DEREGISTER},
57
{ "enroll", no_argument, NULL, DO_ENROLL },
58
{ "edit-policy", no_argument, NULL, DO_EDIT_POLICY },
59
{ "delete-policy", no_argument, NULL, DO_DELETE_POLICY },
61
{ "version", no_argument, NULL, 'V' },
66
static const char * opt_configfile = ISNS_DEFAULT_ISNSADM_CONFIG;
67
static int opt_af = AF_UNSPEC;
68
static int opt_action = 0;
69
static int opt_local = 0;
70
static int opt_control = 0;
71
static int opt_replace = 0;
72
static const char * opt_keyfile = NULL;
73
static char * opt_key = NULL;
74
static struct sockaddr_storage opt_myaddr;
76
static void usage(int, const char *);
78
static int register_objects(isns_client_t *, int, char **);
79
static int query_objects(isns_client_t *, int, char **);
80
static int query_entity_id(isns_client_t *, int, char **);
81
static int list_objects(isns_client_t *, int, char **);
82
static int deregister_objects(isns_client_t *, int, char **);
83
static int register_domain(isns_client_t *, int, char **);
84
static int deregister_domain(isns_client_t *, int, char **);
85
static int enroll_client(isns_client_t *, int, char **);
86
static int edit_policy(isns_client_t *, int, char **);
88
static isns_attr_t * load_key_callback(const char *);
89
static isns_attr_t * generate_key_callback(void);
92
main(int argc, char **argv)
95
isns_security_t *security = NULL;
98
while ((c = getopt_long(argc, argv, "46Cc:d:hK:k:l", options, NULL)) != -1) {
113
opt_configfile = optarg;
117
isns_enable_debugging(optarg);
125
opt_keyfile = optarg;
141
printf("Open-iSNS version %s\n"
142
"Copyright (C) 2007, Olaf Kirch <olaf.kirch@oracle.com>\n",
143
OPENISNS_VERSION_STRING);
152
case DO_DD_DEREGISTER:
155
case DO_DELETE_POLICY:
157
usage(1, "You cannot specify more than one mode\n");
162
usage(1, "Unknown option");
166
isns_read_config(opt_configfile);
168
if (!isns_config.ic_source_name)
169
usage(1, "Please specify an iSNS source name");
170
if (!isns_config.ic_server_name)
171
usage(1, "Please specify an iSNS server name");
173
usage(1, "Please specify an operating mode");
176
if (!isns_config.ic_security)
177
isns_fatal("Cannot use control mode, security disabled\n");
178
security = isns_control_security_context(0);
180
isns_fatal("Unable to create control security context\n");
182
/* Create a networked client, using isns.control as
184
clnt = isns_create_client(security, isns_config.ic_control_name);
185
} else if (opt_local) {
186
/* Create a local client, using isns.control as
188
clnt = isns_create_local_client(security,
189
isns_config.ic_control_name);
191
/* Create a networked client, using the configured
193
clnt = isns_create_default_client(security);
199
/* We're an interactive app, and don't want to retry
200
* forever if the server refuses us. */
201
isns_socket_set_disconnect_fatal(clnt->ic_socket);
203
/* Get the IP address we use to talk to the iSNS server */
204
if (opt_myaddr.ss_family == AF_UNSPEC && !opt_local) {
205
if (!isns_socket_get_local_addr(clnt->ic_socket, &opt_myaddr))
206
isns_fatal("Unable to obtain my IP address\n");
207
isns_addr_set_port((struct sockaddr *) &opt_myaddr, 860);
210
argv += optind; argc -= optind;
211
switch (opt_action) {
213
status = register_objects(clnt, argc, argv);
217
status = query_objects(clnt, argc, argv);
221
status = query_entity_id(clnt, argc, argv);
225
status = list_objects(clnt, argc, argv);
229
status = deregister_objects(clnt, argc, argv);
233
status = register_domain(clnt, argc, argv);
236
case DO_DD_DEREGISTER:
237
status = deregister_domain(clnt, argc, argv);
242
status = enroll_client(clnt, argc, argv);
246
status = edit_policy(clnt, argc, argv);
249
// case DO_DELETE_POLICY:
252
isns_fatal("Not yet implemented\n");
253
status = 1; /* compiler food */
256
return status != ISNS_SUCCESS;
260
usage(int exval, const char *msg)
263
fprintf(stderr, "Error: %s\n", msg);
265
"Usage: isnsadm [options] --action ...\n"
266
" --config Specify alternative config fille\n"
267
" --debug Enable debugging (list of debug flags)\n"
268
" --keyfile Where to store newly generated private key\n"
269
" --local Use local Unix socket to talk to isnsd\n"
270
" --control Assume control node identity for authentication\n"
271
" --replace Use replace mode (--register only)\n"
272
"\nThe following actions are supported:\n"
273
" --register Register one or more objects\n"
274
" --deregister Deregister an object (and children)\n"
275
" --query Query iSNS server for objects\n"
276
" --list List all objects of a given type\n"
277
" --enroll Create a new policy object for a client\n"
278
" --edit-policy Edit a policy object\n"
279
" --delete-policy Edit a policy object\n"
280
" --help Display this message\n"
281
"\nUse \"--query help\" to get help on e.g. the query action\n"
287
parse_registration(char **argv, int argc, isns_object_list_t *objs, isns_object_t *key_obj)
289
struct sockaddr_storage def_addr;
290
isns_object_t *entity = NULL, *last_portal = NULL, *last_node = NULL;
291
const char *def_port = NULL;
294
if (argc == 1 && !strcmp(argv[0], "help")) {
295
printf("Object registration:\n"
296
" isnsadm [-key attr=value] --register type,attr=value,... type,attr=value,...\n"
297
"Where type can be one of:\n"
298
" entity create/update network entity\n"
299
" initiator create iSCSI initiator storage node\n"
300
" target create iSCSI target storage node\n"
301
" control create control node\n"
302
" portal create portal\n"
303
" pg create portal group\n"
304
"\nThe following attributes are recognized:\n");
306
isns_attr_list_parser_help(NULL);
311
usage(1, "Missing object list\n");
314
//isns_object_list_append(objs, key_obj);
315
if (isns_object_is_entity(key_obj))
319
def_addr = opt_myaddr;
321
for (i = 0; i < argc; ++i) {
322
isns_attr_list_t attrlist = ISNS_ATTR_LIST_INIT;
323
struct isns_attr_list_parser state;
325
char *type, *name, *value, *next_attr;
327
unsigned int nattrs = 0;
331
if ((next_attr = strchr(name, ',')) != NULL)
334
while (next_attr && *next_attr) {
336
isns_fatal("Too many attributes\n");
338
/* Show mercy with fat fingered
339
* people,,,,who,cannot,,,type,properly */
340
if (next_attr[0] != ',')
341
attrs[nattrs++] = next_attr;
342
if ((next_attr = strchr(next_attr, ',')) != NULL)
346
if ((value = strchr(name, '=')) != NULL)
350
if (!strcmp(name, "entity")) {
351
if (entity == NULL) {
352
isns_error("Cannot create entity object "
353
"within this key object\n");
358
isns_object_set_string(entity,
359
ISNS_TAG_ENTITY_IDENTIFIER,
361
obj = isns_object_get(entity);
362
goto handle_attributes;
364
if (!strcmp(name, "node")
365
|| !strcmp(name, "initiator")) {
366
const char *node_name;
368
node_name = isns_config.ic_source_name;
372
obj = isns_create_storage_node(node_name,
373
ISNS_ISCSI_INITIATOR_MASK,
377
isns_addr_set_port((struct sockaddr *) &def_addr,
378
ISNS_DEFAULT_PORT_INITIATOR);
381
if (!strcmp(name, "target")) {
382
const char *node_name;
384
node_name = isns_config.ic_source_name;
387
obj = isns_create_storage_node(node_name,
388
ISNS_ISCSI_TARGET_MASK,
392
isns_addr_set_port((struct sockaddr *) &def_addr,
393
ISNS_DEFAULT_PORT_TARGET);
394
def_port = "iscsi-target";
396
if (!strcmp(name, "control")) {
397
const char *node_name;
399
node_name = isns_config.ic_control_name;
402
obj = isns_create_storage_node(node_name,
403
ISNS_ISCSI_CONTROL_MASK,
409
if (!strcmp(name, "portal")) {
410
isns_portal_info_t portal_info;
413
if (def_port == NULL)
414
isns_fatal("portal must follow initiator or target\n");
415
isns_portal_init(&portal_info,
416
(struct sockaddr *) &def_addr,
419
if (!isns_portal_parse(&portal_info, value, def_port))
420
isns_fatal("Unable to parse portal=%s\n", value);
421
obj = isns_create_portal(&portal_info, entity);
424
if (!strcmp(name, "pg")) {
426
isns_fatal("Unexpected value for portal group\n");
427
if (!last_portal || !last_node)
428
isns_fatal("Portal group registration must follow portal and node\n");
429
obj = isns_create_portal_group(last_portal, last_node, 10);
431
isns_error("Unknown object type \"%s\"\n", name);
436
isns_error("Failure to create %s object\n", name);
439
isns_object_list_append(objs, obj);
442
isns_attr_list_parser_init(&state, obj->ie_template);
443
state.default_port = def_port;
445
if (!isns_parse_attrs(nattrs, attrs, &attrlist, &state)
446
|| !isns_object_set_attrlist(obj, &attrlist)) {
447
isns_error("Failure to set all %s attributes\n", name);
448
isns_attr_list_destroy(&attrlist);
452
isns_attr_list_destroy(&attrlist);
453
isns_object_release(obj);
460
__register_objects(isns_client_t *clnt,
461
isns_object_t *key_obj,
462
const isns_object_list_t *objects)
464
isns_source_t *source = NULL;
469
for (i = 0; i < objects->iol_count && !source; ++i) {
470
isns_object_t *obj = objects->iol_data[i];
472
if (!isns_object_is_iscsi_node(obj))
474
source = isns_source_from_object(obj);
477
reg = isns_create_registration2(clnt, key_obj, source);
478
isns_registration_set_replace(reg, opt_replace);
480
/* Add all objects to be registered */
481
for (i = 0; i < objects->iol_count; ++i)
482
isns_registration_add_object(reg, objects->iol_data[i]);
484
status = isns_client_call(clnt, ®);
485
isns_simple_free(reg);
487
if (status == ISNS_SUCCESS)
488
printf("Successfully registered object(s)\n");
490
isns_error("Failed to register object(s): %s\n",
491
isns_strerror(status));
494
isns_source_release(source);
499
register_objects(isns_client_t *clnt,
500
int argc, char **argv)
502
isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
503
isns_object_t *key_obj = NULL;
506
if (opt_key != NULL) {
507
isns_attr_list_t key_attrs = ISNS_ATTR_LIST_INIT;
508
struct isns_attr_list_parser state;
510
isns_attr_list_parser_init(&state, NULL);
512
if (!isns_parse_attrs(1, &opt_key, &key_attrs, &state)) {
513
isns_error("Cannot parse registration key \"%s\"\n",
518
key_obj = isns_create_object(isns_attr_list_parser_context(&state),
520
isns_attr_list_destroy(&key_attrs);
523
isns_error("Cannot create registration key object\n");
527
/* If the user does not provide a key object,
528
* create/update an entity.
530
key_obj = isns_create_entity(ISNS_ENTITY_PROTOCOL_ISCSI, NULL);
533
if (!parse_registration(argv, argc, &objects, key_obj))
534
isns_fatal("Unable to parse registration\n");
536
status = __register_objects(clnt, key_obj, &objects);
537
isns_object_list_destroy(&objects);
539
isns_object_release(key_obj);
544
* Parse the query string given by the user
547
* The Message Key may contain key or non-key attributes or no
548
* attributes at all. If multiple attributes are used as the
549
* Message Key, then they MUST all be from the same object type
550
* (e.g., IP address and TCP/UDP Port are attributes of the
551
* Portal object type).
554
parse_query(char **argv, int argc, isns_attr_list_t *keys, isns_attr_list_t *query)
556
struct isns_attr_list_parser state;
558
isns_attr_list_parser_init(&state, NULL);
559
state.nil_permitted = 1;
561
if (argc == 1 && !strcmp(argv[0], "help")) {
562
printf("Object query:\n"
563
" isnsadm --query attr=value attr=value ... ?query-attr ?query-attr ...\n"
564
"All key attributes must refer to a common object type.\n"
565
"Query attributes specify the attributes the server should return,"
566
"and can refer to any object type.\n"
567
"The following attributes are recognized:\n");
568
isns_attr_list_parser_help(&state);
573
isns_fatal("Missing query attributes\n");
575
return isns_parse_query_attrs(argc, argv, keys, query, &state);
579
query_objects(isns_client_t *clnt, int argc, char **argv)
581
isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
582
isns_attr_list_t oper_attrs = ISNS_ATTR_LIST_INIT;
583
isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
588
if (!parse_query(argv, argc, &query_key, &oper_attrs))
589
isns_fatal("Unable to parse query\n");
591
qry = isns_create_query(clnt, &query_key);
592
isns_attr_list_destroy(&query_key);
594
/* Add the list of attributes we request */
595
for (i = 0; i < oper_attrs.ial_count; ++i)
596
isns_query_request_attr(qry, oper_attrs.ial_data[i]);
597
isns_attr_list_destroy(&oper_attrs);
599
status = isns_client_call(clnt, &qry);
600
if (status != ISNS_SUCCESS) {
601
isns_error("Query failed: %s\n", isns_strerror(status));
605
status = isns_query_response_get_objects(qry, &objects);
607
isns_error("Unable to extract object list from query response: %s\n",
608
isns_strerror(status), status);
612
isns_object_list_print(&objects, isns_print_stdout);
613
isns_object_list_destroy(&objects);
614
isns_simple_free(qry);
620
query_entity_id(isns_client_t *clnt, int argc, char **argv)
622
isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
623
isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
628
if (argc == 1 && !strcmp(argv[0], "help")) {
629
printf("Query iSNS for own entity ID.\n"
630
"No arguments allowed\n");
634
isns_fatal("EID query - no arguments accepted\n");
636
isns_attr_list_append_string(&query_key,
638
isns_config.ic_source_name);
639
qry = isns_create_query(clnt, &query_key);
640
isns_attr_list_destroy(&query_key);
642
isns_query_request_attr_tag(qry, ISNS_TAG_ENTITY_IDENTIFIER);
644
status = isns_client_call(clnt, &qry);
645
if (status != ISNS_SUCCESS) {
646
isns_error("Query failed: %s\n", isns_strerror(status));
650
status = isns_query_response_get_objects(qry, &objects);
652
isns_error("Unable to extract object list from query response: %s\n",
653
isns_strerror(status), status);
657
status = ISNS_NO_SUCH_ENTRY;
658
if (objects.iol_count == 0) {
659
isns_error("Node %s not registered with iSNS\n",
660
isns_config.ic_source_name);
662
if (!isns_object_get_string(objects.iol_data[0],
663
ISNS_TAG_ENTITY_IDENTIFIER, &eid)) {
664
isns_error("Query for %s returned an object without EID\n",
665
isns_config.ic_source_name);
668
status = ISNS_SUCCESS;
671
isns_object_list_destroy(&objects);
672
isns_simple_free(qry);
678
* Parse the list query string given by the user
681
parse_list(int argc, char **argv, isns_object_template_t **type_p, isns_attr_list_t *keys)
683
struct isns_attr_list_parser state;
684
isns_object_template_t *query_type = NULL;
688
usage(1, "Missing object type");
690
if (argc == 1 && !strcmp(argv[0], "help")) {
691
printf("Object query:\n"
692
" isnsadm --list type attr=value attr=value ...\n"
693
"Possible value for <type>:\n"
694
" entities - list all network entites\n"
695
" nodes - list all storage nodes\n"
696
" portals - list all portals\n"
697
" portal-groups - list all portal groups\n"
698
" dds - list all discovery domains\n"
699
" ddsets - list all discovery domains sets\n"
700
" policies - list all policies (privileged)\n"
701
"Additional attributes can be specified to scope the\n"
702
"search. They must match the specified object type.\n"
703
"\nThe following attributes are recognized:\n");
704
isns_attr_list_parser_help(NULL);
708
type_name = *argv++; --argc;
709
if (!strcasecmp(type_name, "entities"))
710
query_type = &isns_entity_template;
712
if (!strcasecmp(type_name, "nodes"))
713
query_type = &isns_iscsi_node_template;
715
if (!strcasecmp(type_name, "portals"))
716
query_type = &isns_portal_template;
718
if (!strcasecmp(type_name, "portal-groups"))
719
query_type = &isns_iscsi_pg_template;
721
if (!strcasecmp(type_name, "dds"))
722
query_type = &isns_dd_template;
724
if (!strcasecmp(type_name, "ddsets"))
725
query_type = &isns_ddset_template;
727
if (!strcasecmp(type_name, "policies"))
728
query_type = &isns_policy_template;
730
isns_error("Unknown object type \"%s\"\n",
735
*type_p = query_type;
737
isns_attr_list_parser_init(&state, query_type);
738
state.nil_permitted = 1;
740
return isns_parse_attrs(argc, argv, keys, &state);
744
list_objects(isns_client_t *clnt, int argc, char **argv)
746
isns_attr_list_t query_keys = ISNS_ATTR_LIST_INIT;
747
isns_object_template_t *query_type = NULL;
749
int status, count = 0;
751
if (!parse_list(argc, argv, &query_type, &query_keys))
752
isns_fatal("Unable to parse parameters\n");
754
simp = isns_create_getnext(clnt, query_type, &query_keys);
756
isns_object_t *obj = NULL;
757
isns_simple_t *followup;
759
status = isns_client_call(clnt, &simp);
763
status = isns_getnext_response_get_object(simp, &obj);
767
printf("Object %u:\n", count++);
768
isns_object_print(obj, isns_print_stdout);
769
isns_object_release(obj);
771
followup = isns_create_getnext_followup(clnt,
773
isns_simple_free(simp);
777
if (status == ISNS_SOURCE_UNAUTHORIZED
778
&& query_type == &isns_policy_template
780
isns_warning("Please use --local trying to list policies\n");
782
if (status != ISNS_NO_SUCH_ENTRY) {
783
isns_error("GetNext call failed: %s\n",
784
isns_strerror(status));
791
* Parse the deregistration string given by the user
794
* The Message Key may contain key or non-key attributes or no
795
* attributes at all. If multiple attributes are used as the
796
* Message Key, then they MUST all be from the same object type
797
* (e.g., IP address and TCP/UDP Port are attributes of the
798
* Portal object type).
801
parse_deregistration(char **argv, int argc, isns_attr_list_t *keys)
803
struct isns_attr_list_parser state;
805
isns_attr_list_parser_init(&state, NULL);
806
state.multi_type_permitted = 1;
807
state.nil_permitted = 1;
809
if (argc == 1 && !strcmp(argv[0], "help")) {
810
printf("Object deregistration:\n"
811
" isnsadm --deregister attr=value attr=value ...\n"
812
"All attributes must refer to a common object type.\n"
813
"\nThe following attributes are recognized:\n");
814
isns_attr_list_parser_help(&state);
818
return isns_parse_attrs(argc, argv, keys, &state);
822
deregister_objects(isns_client_t *clnt, int argc, char **argv)
824
isns_attr_list_t query_key = ISNS_ATTR_LIST_INIT;
825
isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
826
isns_simple_t *dereg;
829
if (!parse_deregistration(argv, argc, &query_key))
830
isns_fatal("Unable to parse unregistration\n");
832
dereg = isns_create_deregistration(clnt, &query_key);
833
isns_attr_list_destroy(&query_key);
835
status = isns_client_call(clnt, &dereg);
836
if (status != ISNS_SUCCESS) {
837
isns_error("Deregistration failed: %s\n",
838
isns_strerror(status));
843
status = isns_dereg_msg_response_get_objects(dereg, &objects);
845
isns_error("Unable to extract object list from deregistration response: %s\n",
846
isns_strerror(status), status);
849
isns_object_list_print(&objects, isns_print_stdout);
852
isns_object_list_destroy(&objects);
853
isns_simple_free(dereg);
859
* Handle discovery domain registration/deregistration
862
parse_dd_registration(char **argv, int argc, isns_attr_list_t *keys)
864
struct isns_attr_list_parser state;
866
isns_attr_list_parser_init(&state, &isns_dd_template);
867
if (argc == 1 && !strcmp(argv[0], "help")) {
868
printf("Object query:\n"
869
" isnsadm --dd-register attr=value attr=value ...\n"
870
"You cannot specify more than one domain.\n"
871
"If you want to modify an existing domain, you must specify its ID.\n"
872
"The following attributes are recognized:\n");
873
isns_attr_list_parser_help(&state);
877
return isns_parse_attrs(argc, argv, keys, &state);
881
register_domain(isns_client_t *clnt, int argc, char **argv)
883
isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT;
887
if (!parse_dd_registration(argv, argc, &attrs))
888
isns_fatal("Unable to parse DD registration\n");
890
msg = isns_create_dd_registration(clnt, &attrs);
891
isns_attr_list_destroy(&attrs);
894
isns_error("Cannot create message\n");
895
return ISNS_INTERNAL_ERROR;
898
status = isns_client_call(clnt, &msg);
899
if (status != ISNS_SUCCESS) {
900
isns_error("Registration failed: %s\n",
901
isns_strerror(status));
905
if (status == ISNS_SUCCESS) {
906
printf("Registered DD:\n");
907
isns_attr_list_print(
908
isns_simple_get_attrs(msg),
911
isns_simple_free(msg);
917
parse_dd_deregistration(char **argv, int argc,
918
uint32_t *dd_id, isns_attr_list_t *keys)
920
struct isns_attr_list_parser state;
922
isns_attr_list_parser_init(&state, &isns_dd_template);
923
if (argc == 0 || (argc == 1 && !strcmp(argv[0], "help"))) {
924
printf("DD deregistration:\n"
925
" isnsadm --dd-deregister dd-id attr=value attr=value ...\n"
926
"You cannot specify more than one domain.\n"
927
"The following attributes are recognized:\n");
928
isns_attr_list_parser_help(&state);
932
*dd_id = parse_count(argv[0]);
934
return isns_parse_attrs(argc - 1, argv + 1, keys, &state);
938
deregister_domain(isns_client_t *clnt, int argc, char **argv)
940
isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT;
942
uint32_t dd_id, status;
944
if (!parse_dd_deregistration(argv, argc, &dd_id, &attrs))
945
isns_fatal("Unable to parse DD registration\n");
947
msg = isns_create_dd_deregistration(clnt, dd_id, &attrs);
948
isns_attr_list_destroy(&attrs);
951
isns_error("Cannot create message\n");
952
return ISNS_INTERNAL_ERROR;
955
status = isns_client_call(clnt, &msg);
956
if (status != ISNS_SUCCESS) {
957
isns_error("Deregistration failed: %s\n",
958
isns_strerror(status));
962
isns_simple_free(msg);
970
parse_policy(int argc, char **argv, isns_attr_list_t *attrs,
971
const char *help_title, const char *help_action)
973
struct isns_attr_list_parser state;
975
isns_attr_list_parser_init(&state, &isns_policy_template);
976
state.nil_permitted = 0;
977
state.load_key = load_key_callback;
978
state.generate_key = generate_key_callback;
980
if (argc == 1 && !strcmp(argv[0], "help")) {
982
" isnsadm %s attr=value attr=value ...\n"
983
"Specifying a Security Policy Index is mandatory.\n"
984
"\nThe following attributes are recognized:\n",
985
help_title, help_action);
986
isns_attr_list_parser_help(&state);
990
return isns_parse_attrs(argc, argv, attrs, &state);
994
__create_policy(isns_client_t *clnt, const isns_attr_list_t *attrs)
996
isns_object_list_t objects = ISNS_OBJECT_LIST_INIT;
1000
obj = isns_create_object(&isns_policy_template, attrs, NULL);
1002
isns_fatal("Cannot create policy object\n");
1003
isns_object_list_append(&objects, obj);
1005
status = __register_objects(clnt, NULL, &objects);
1006
isns_object_list_destroy(&objects);
1011
* Enroll a new client
1014
enroll_client(isns_client_t *clnt, int argc, char **argv)
1016
isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT;
1017
const char *client_name;
1021
usage(1, "Missing client name");
1023
client_name = *argv++; --argc;
1025
isns_attr_list_append_string(&attrs,
1026
OPENISNS_TAG_POLICY_SPI,
1029
isns_attr_list_append_string(&attrs,
1030
OPENISNS_TAG_POLICY_SOURCE_NAME,
1035
static char namebuf[PATH_MAX];
1037
snprintf(namebuf, sizeof(namebuf), "%s.key", client_name);
1038
opt_keyfile = namebuf;
1041
if (argc && !parse_policy(argc, argv, &attrs,
1042
"Enroll an iSNS client",
1043
"--enroll hostname"))
1044
isns_fatal("Cannot parse policy\n");
1046
/* If no key is given, generate one */
1047
if (!isns_attr_list_contains(&attrs, OPENISNS_TAG_POLICY_KEY)) {
1048
printf("No key given, generating one\n");
1049
isns_attr_list_append_attr(&attrs,
1050
generate_key_callback());
1053
status = __create_policy(clnt, &attrs);
1054
isns_attr_list_destroy(&attrs);
1060
* Create a new policy
1063
edit_policy(isns_client_t *clnt, int argc, char **argv)
1065
isns_attr_list_t attrs = ISNS_ATTR_LIST_INIT;
1068
if (!parse_policy(argc, argv, &attrs,
1069
"Edit an existing policy",
1071
isns_fatal("Cannot parse policy\n");
1073
status = __create_policy(clnt, &attrs);
1074
isns_attr_list_destroy(&attrs);
1079
#ifdef WITH_SECURITY
1080
static isns_attr_t *
1081
__key_to_attr(EVP_PKEY *pkey)
1083
struct __isns_opaque key;
1085
isns_attr_t *attr = NULL;
1087
if (!isns_dsa_encode_public(pkey, &key.ptr, &key.len))
1090
/* Must pad key. This means we may end up encoding a few
1091
* bytes of trash. Oh well. */
1092
key.len = ISNS_PAD(key.len);
1094
value = ISNS_VALUE_INIT(opaque, key);
1095
attr = isns_attr_alloc(OPENISNS_TAG_POLICY_KEY, NULL, &value);
1100
EVP_PKEY_free(pkey);
1105
generate_key_callback(void)
1109
if (opt_keyfile == NULL)
1110
isns_fatal("Key generation requires --keyfile option\n");
1112
if (!(pkey = isns_dsa_generate_key()))
1113
isns_fatal("Key generation failed\n");
1115
if (!isns_dsa_store_private(opt_keyfile, pkey))
1116
isns_fatal("Unable to write private key to %s\n",
1119
printf("Stored DSA private key in %s\n", opt_keyfile);
1120
return __key_to_attr(pkey);
1124
load_key_callback(const char *pathname)
1128
if (!(pkey = isns_dsa_load_public(pathname)))
1129
isns_fatal("Unable to load public key from file %s\n", pathname);
1131
return __key_to_attr(pkey);
1134
#else /* WITH_SECURITY */
1136
generate_key_callback(void)
1138
isns_fatal("Authentication disabled in this build\n");
1143
load_key_callback(const char *pathname)
1145
isns_fatal("Authentication disabled in this build\n");