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 <sys/types.h>
28 #include <ipsec_util.h>
37 static char *preamble
=
38 "# /etc/inet/ipsecalgs output from ipsecalgs(1m)\n"
40 "# DO NOT EDIT OR PARSE THIS FILE!\n"
42 "# Use the ipsecalgs(1m) command to change the contents of this file.\n"
43 "# The algorithm descriptions contained in this file are synchronised to the\n"
44 "# kernel with ipsecalgs -s, the kernel validates the entries at this point."
46 "# PROTO|protocol-id|protocol-name|exec-mode\n"
47 "## NOTE: Some protocol numbers are well-known and defined in <netdb.h>\n\n"
48 "# ALG|protocol-id|alg-id|name,name,...|ef-id| \n"
49 "# {default/}{key,key..}or{key-key,inc}|block_size or MAC-size|\n"
50 "# [parameter,parameter..]|[flags]\n\n"
52 "## Note: Parameters and flags only apply to certain algorithms.\n\n";
54 #define CFG_PERMS S_IRUSR | S_IRGRP | S_IROTH /* Perms 0444. */
55 #define CFG_OWNER 0 /* root */
56 #define CFG_GROUP 1 /* "other" */
59 * write_new_algfile() helper macros to check for write errors.
62 #define FPRINTF_ERR(fcall) if ((fcall) < 0) { \
63 rc = LIBIPSEC_ALGS_DIAG_ALGSFILEWRITE; \
67 #define FPUT_ERR(fcall) if ((fcall) == EOF) { \
68 rc = LIBIPSEC_ALGS_DIAG_ALGSFILEWRITE; \
73 * Helper macros to start and finish a list of entries that were added
74 * as part of a package installation.
77 #define PKG_SEC_START(pkgname, doing_pkg, cur_pkg) { \
78 (void) strcpy((cur_pkg), (pkgname)); \
79 FPRINTF_ERR(fprintf(f, "%s%s\n", \
80 LIBIPSEC_ALGS_LINE_PKGSTART, (cur_pkg))); \
81 (doing_pkg) = B_TRUE; \
84 #define PKG_SEC_END(doing_pkg, cur_pkg) { \
86 FPRINTF_ERR(fprintf(f, "%s%s\n", \
87 LIBIPSEC_ALGS_LINE_PKGEND, (cur_pkg))); \
88 (doing_pkg) = B_FALSE; \
93 * Take a zero-terminated int array and print int1,int2...,intN.
94 * If zero-only, then print a single '0'.
95 * Returns 0 on success, -1 if an error occurred while writing to
99 list_ints(FILE *f
, int *floater
)
101 boolean_t executed
= B_FALSE
;
103 while (*floater
!= 0) {
105 if (fprintf(f
, "%d", *floater
) < 0)
107 if (*(++floater
) != 0)
108 if (fputc(',', f
) == EOF
)
113 if (fputc('0', f
) == EOF
)
120 * If the specified algorithm was defined within a package section, i.e.
121 * between the lines "# Start <pkgname>" and "# End <pkgname>", returns
122 * the value of <pkgname>.
125 alg_has_pkg(ipsec_proto_t
*proto
, struct ipsecalgent
*alg
)
129 if (proto
->proto_algs_pkgs
== NULL
)
132 for (i
= 0; i
< proto
->proto_algs_npkgs
; i
++)
133 if (proto
->proto_algs_pkgs
[i
].alg_num
== alg
->a_alg_num
)
134 return (proto
->proto_algs_pkgs
[i
].pkg_name
);
140 * Writes the package start/end delimiters according to the package
141 * name associated with the current protocol or algorithm, and
142 * the state of the packaging information already written to the file.
143 * Called by write_new_algfile(). Returns 0 on success, one of the
144 * LIBIPSEC_DIAG codes on failure.
147 pkg_section(FILE *f
, char *pkg_name
, boolean_t
*doing_pkg
, char *cur_pkg
)
151 if (pkg_name
!= NULL
) {
152 /* protocol or algorithm is associated with a package */
154 /* start of a new package section */
155 PKG_SEC_START(pkg_name
, *doing_pkg
, cur_pkg
);
157 /* already in a package section */
158 if (strcmp(pkg_name
, cur_pkg
) != 0) {
159 /* different package name */
160 PKG_SEC_END(*doing_pkg
, cur_pkg
);
161 PKG_SEC_START(pkg_name
, *doing_pkg
, cur_pkg
);
164 } else if (*doing_pkg
) {
165 /* in a package section when the entry isn't */
166 PKG_SEC_END(*doing_pkg
, cur_pkg
);
173 * Given a list of protocols and number, write them to a new algorithm file.
174 * This function takes num_protos + num_protos * dois-per-alg operations.
175 * Also free the protocol structure.
177 * Note that no locking spans the read/update/write phases that can be
178 * used by callers of this routine. This could cause this function to suffer
179 * from the "lost update" problem. Since updates to the IPsec protocols
180 * and algorithm tables are very infrequent, this should not be a issue in
184 write_new_algfile(ipsec_proto_t
*protos
, int num_protos
)
189 struct ipsecalgent
*alg
;
191 boolean_t doing_pkg
= B_FALSE
;
193 char tmp_name_template
[] = INET_IPSECALGSPATH
"ipsecalgsXXXXXX";
197 * In order to avoid potentially corrupting the configuration
198 * file on file system failure, write the new configuration info
199 * to a temporary file which is then renamed to the configuration
200 * file (INET_IPSECALGSFILE.)
202 tmp_name
= mktemp(tmp_name_template
);
204 fd
= open(tmp_name
, O_WRONLY
|O_CREAT
|O_EXCL
, CFG_PERMS
);
206 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILEOPEN
;
213 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILEFDOPEN
;
217 FPUT_ERR(fputs(preamble
, f
));
219 /* Write protocol entries. */
220 for (i
= 0; i
< num_protos
; i
++) {
222 /* add package section delimiters if needed */
223 rc
= pkg_section(f
, protos
[i
].proto_pkg
, &doing_pkg
, cur_pkg
);
227 FPRINTF_ERR(fprintf(f
, "%s%d|%s|",
228 LIBIPSEC_ALGS_LINE_PROTO
,
229 protos
[i
].proto_num
, protos
[i
].proto_name
));
230 switch (protos
[i
].proto_exec_mode
) {
231 case LIBIPSEC_ALGS_EXEC_SYNC
:
232 FPRINTF_ERR(fprintf(f
, "sync\n"));
234 case LIBIPSEC_ALGS_EXEC_ASYNC
:
235 FPRINTF_ERR(fprintf(f
, "async\n"));
240 /* terminate the package section for the protocols if needed */
241 PKG_SEC_END(doing_pkg
, cur_pkg
);
243 FPUT_ERR(fputs("\n", f
));
245 /* Write algorithm entries. */
247 for (i
= 0; i
< num_protos
; i
++) {
248 for (j
= 0; j
< protos
[i
].proto_numalgs
; j
++) {
249 alg
= protos
[i
].proto_algs
[j
];
251 /* add package section delimiters if needed */
252 alg_pkg
= alg_has_pkg(&protos
[i
], alg
);
253 rc
= pkg_section(f
, alg_pkg
, &doing_pkg
, cur_pkg
);
257 /* protocol and algorithm numbers */
258 FPRINTF_ERR(fprintf(f
, "%s%d|%d|",
259 LIBIPSEC_ALGS_LINE_ALG
,
260 alg
->a_proto_num
, alg
->a_alg_num
));
262 /* algorithm names */
263 for (k
= 0; alg
->a_names
[k
] != NULL
; k
++) {
264 FPRINTF_ERR(fprintf(f
, "%s", alg
->a_names
[k
]));
265 if (alg
->a_names
[k
+1] != NULL
)
266 FPRINTF_ERR(fprintf(f
, ","));
270 FPRINTF_ERR(fprintf(f
, "|%s|", alg
->a_mech_name
));
273 if (alg
->a_key_increment
== 0) {
274 /* key sizes defined by enumeration */
275 if (list_ints(f
, alg
->a_key_sizes
) == -1) {
276 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILEWRITE
;
280 /* key sizes defined by range */
281 FPRINTF_ERR(fprintf(f
, "%d/%d-%d,%d",
282 alg
->a_key_sizes
[0], alg
->a_key_sizes
[1],
283 alg
->a_key_sizes
[2], alg
->a_key_increment
));
285 FPUT_ERR(fputc('|', f
));
288 if (list_ints(f
, alg
->a_block_sizes
) == -1) {
289 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILEWRITE
;
292 FPUT_ERR(fputc('|', f
));
295 * Some algorithms require extra parameters, these
296 * are stored in an array. For algorithms that don't
297 * need these parameters, or flags (below), these
298 * extra fields in the ipsecalgs file must contain a
299 * zero. This fuction will get called if a algorithm
300 * entry is added, at this point the extra fields will
301 * be added to the file.
303 if (list_ints(f
, alg
->a_mech_params
) == -1) {
304 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILEWRITE
;
308 FPRINTF_ERR(fprintf(f
, "|%d\n", alg
->a_alg_flags
));
312 /* terminate the package section for the algorithms if needed */
313 PKG_SEC_END(doing_pkg
, cur_pkg
);
315 if (fchmod(fd
, CFG_PERMS
) == -1) {
316 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILECHMOD
;
319 if (fchown(fd
, CFG_OWNER
, CFG_GROUP
) == -1) {
320 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILECHOWN
;
323 if (fclose(f
) == EOF
) {
324 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILECLOSE
;
328 if (rename(tmp_name
, INET_IPSECALGSFILE
) == -1)
329 rc
= LIBIPSEC_ALGS_DIAG_ALGSFILERENAME
;
332 _clean_trash(protos
, num_protos
);
337 * Return a pointer to the protocol entry corresponding to the specified
338 * protocol num proto_num. Also builds the list of currently defined
341 static ipsec_proto_t
*
342 proto_setup(ipsec_proto_t
**protos
, int *num_protos
, int proto_num
,
346 ipsec_proto_t
*current_proto
, *ret_proto
= NULL
;
348 _build_internal_algs(protos
, num_protos
);
353 for (i
= 0; i
< *num_protos
; i
++) {
354 current_proto
= (*protos
) + i
;
355 if (current_proto
->proto_num
== proto_num
) {
356 ret_proto
= current_proto
;
361 if (ret_proto
== NULL
) {
363 _clean_trash(*protos
, *num_protos
);
364 /* else caller wants parsed /etc/inet/ipsecalgs anyway */
371 * Delete the first found algorithm of the specified protocol which
372 * has the same name as the one specified by alg_name. Deletion of
373 * the entry takes place only if the delete_it flag is set. If an
374 * entry was found, return B_TRUE, otherwise return B_FALSE.
377 delipsecalgbyname_common(const char *name
, ipsec_proto_t
*proto
,
382 boolean_t found_match
= B_FALSE
;
384 for (i
= 0; i
< proto
->proto_numalgs
; i
++) {
387 proto
->proto_algs
[i
]->a_names
;
388 *name_check
!= NULL
; name_check
++) {
390 * Can use strcmp because the algorithm names
393 if (strcmp(*name_check
, name
) == 0) {
394 found_match
= B_TRUE
;
396 return (found_match
);
397 freeipsecalgent(proto
->proto_algs
[i
]);
402 proto
->proto_algs
[i
- 1] = proto
->proto_algs
[i
];
407 proto
->proto_numalgs
--;
409 return (found_match
);
413 * Returns B_TRUE if the specified 0-terminated lists of key or
414 * block sizes match, B_FALSE otherwise.
417 sizes_match(int *a1
, int *a2
)
421 for (i
= 0; (a1
[i
] != 0) && (a2
[i
] != 0); i
++) {
425 if ((a1
[i
] != 0) || (a2
[i
] != 0))
432 * Returns B_TRUE if an _exact_ equivalent of the specified algorithm
433 * already exists, B_FALSE otherwise.
436 ipsecalg_exists(struct ipsecalgent
*newbie
, ipsec_proto_t
*proto
)
438 struct ipsecalgent
*curalg
;
439 char **curname
, **newbiename
;
443 for (i
= 0; i
< proto
->proto_numalgs
; i
++) {
444 curalg
= proto
->proto_algs
[i
];
446 if (curalg
->a_alg_num
!= newbie
->a_alg_num
)
449 if (curalg
->a_key_increment
!= newbie
->a_key_increment
)
452 if (strcmp(curalg
->a_mech_name
, newbie
->a_mech_name
) != 0)
455 curname
= curalg
->a_names
;
456 newbiename
= newbie
->a_names
;
458 while ((*curname
!= NULL
) && (*newbiename
!= NULL
) && match
) {
459 match
= (strcmp(*curname
, *newbiename
) == 0);
463 if (!match
|| (*curname
!= NULL
) || (*newbiename
!= NULL
))
466 if (!sizes_match(curalg
->a_block_sizes
, newbie
->a_block_sizes
))
469 if (!sizes_match(curalg
->a_key_sizes
, newbie
->a_key_sizes
))
472 /* we found an exact match */
480 * Add a new algorithm to the /etc/inet/ipsecalgs file. Caller must free
481 * or otherwise address "newbie".
484 addipsecalg(struct ipsecalgent
*newbie
, uint_t flags
)
486 ipsec_proto_t
*protos
, *current_proto
;
487 struct ipsecalgent
*clone
, **holder
;
490 boolean_t forced_add
= (flags
& LIBIPSEC_ALGS_ADD_FORCE
) != 0;
491 boolean_t found_match
;
493 if ((current_proto
= proto_setup(&protos
, &num_protos
,
494 newbie
->a_proto_num
, B_TRUE
)) == NULL
)
495 return (LIBIPSEC_ALGS_DIAG_UNKN_PROTO
);
498 * If an algorithm that matches _exactly_ the new algorithm
499 * already exists, we're done.
501 if (ipsecalg_exists(newbie
, current_proto
))
505 * We don't allow a new algorithm to be created if one of
506 * its names is already defined for an existing algorithm,
507 * unless the operation is forced, in which case existing
508 * algorithm entries that conflict with the new one are
511 for (name_check
= newbie
->a_names
; *name_check
!= NULL
; name_check
++) {
512 found_match
= delipsecalgbyname_common(*name_check
,
513 current_proto
, forced_add
);
514 if (found_match
&& !forced_add
) {
516 * Duplicate entry found, but the addition was
519 _clean_trash(protos
, num_protos
);
520 return (LIBIPSEC_ALGS_DIAG_ALG_EXISTS
);
524 for (i
= 0; i
< current_proto
->proto_numalgs
; i
++) {
525 if (current_proto
->proto_algs
[i
]->a_alg_num
==
528 * An algorithm with the same protocol number
529 * and algorithm number already exists. Fail
530 * addition unless the operation is forced.
532 if (flags
& LIBIPSEC_ALGS_ADD_FORCE
) {
533 clone
= _duplicate_alg(newbie
);
536 current_proto
->proto_algs
[i
]);
537 current_proto
->proto_algs
[i
] = clone
;
538 return (write_new_algfile(protos
,
541 _clean_trash(protos
, num_protos
);
542 return (LIBIPSEC_ALGS_DIAG_NOMEM
);
545 _clean_trash(protos
, num_protos
);
546 return (LIBIPSEC_ALGS_DIAG_ALG_EXISTS
);
551 /* append the new algorithm */
552 holder
= reallocarray(current_proto
->proto_algs
, i
+ 1,
553 sizeof (struct ipsecalgent
*));
554 if (holder
== NULL
) {
555 _clean_trash(protos
, num_protos
);
556 return (LIBIPSEC_ALGS_DIAG_NOMEM
);
558 clone
= _duplicate_alg(newbie
);
561 _clean_trash(protos
, num_protos
);
562 return (LIBIPSEC_ALGS_DIAG_NOMEM
);
564 current_proto
->proto_numalgs
++;
565 current_proto
->proto_algs
= holder
;
566 current_proto
->proto_algs
[i
] = clone
;
567 return (write_new_algfile(protos
, num_protos
));
571 * Delete an algorithm by name & protocol number from /etc/inet/ipsecalgs.
572 * Only deletes the first encountered instance.
575 delipsecalgbyname(const char *name
, int proto_num
)
577 ipsec_proto_t
*protos
, *current_proto
;
580 if ((current_proto
= proto_setup(&protos
, &num_protos
, proto_num
,
582 return (LIBIPSEC_ALGS_DIAG_UNKN_PROTO
);
584 if (delipsecalgbyname_common(name
, current_proto
, B_TRUE
))
585 return (write_new_algfile(protos
, num_protos
));
587 _clean_trash(protos
, num_protos
);
588 return (LIBIPSEC_ALGS_DIAG_UNKN_ALG
);
592 * Delete an algorithm by num + protocol num from /etc/inet/ipsecalgs.
595 delipsecalgbynum(int alg_num
, int proto_num
)
597 ipsec_proto_t
*protos
, *current_proto
;
599 boolean_t found_match
= B_FALSE
;
601 if ((current_proto
= proto_setup(&protos
, &num_protos
, proto_num
,
603 return (LIBIPSEC_ALGS_DIAG_UNKN_PROTO
);
605 for (i
= 0; i
< current_proto
->proto_numalgs
; i
++) {
607 if (current_proto
->proto_algs
[i
]->a_alg_num
==
609 found_match
= B_TRUE
;
610 freeipsecalgent(current_proto
->proto_algs
[i
]);
613 current_proto
->proto_algs
[i
- 1] =
614 current_proto
->proto_algs
[i
];
619 current_proto
->proto_numalgs
--;
620 return (write_new_algfile(protos
, num_protos
));
623 _clean_trash(protos
, num_protos
);
624 return (LIBIPSEC_ALGS_DIAG_UNKN_ALG
);
628 * Remove the specified protocol entry from the list of protocols.
631 delipsecproto_common(ipsec_proto_t
*protos
, int num_protos
,
632 ipsec_proto_t
*proto
)
636 /* free protocol storage */
637 free(proto
->proto_name
);
638 for (i
= 0; i
< proto
->proto_numalgs
; i
++)
639 freeipsecalgent(proto
->proto_algs
[i
]);
641 /* remove from list of prototocols */
642 for (i
= (proto
- protos
+ 1); i
< num_protos
; i
++)
643 protos
[i
- 1] = protos
[i
];
647 * Add an IPsec protocol to /etc/inet/ipsecalgs.
650 addipsecproto(const char *proto_name
, int proto_num
,
651 ipsecalgs_exec_mode_t proto_exec_mode
, uint_t flags
)
653 ipsec_proto_t
*protos
, *current_proto
, *new_proto
;
657 * NOTE:If build_internal_algs returns NULL for any
658 * reason, we will end up clobbering /etc/inet/ipsecalgs!
661 current_proto
= proto_setup(&protos
, &num_protos
, proto_num
, B_FALSE
);
663 /* check for protocol with duplicate id */
664 if (current_proto
!= NULL
) {
665 if ((strcmp(proto_name
, current_proto
->proto_name
) == 0) &&
666 (proto_exec_mode
== current_proto
->proto_exec_mode
)) {
668 * The current protocol being added matches
669 * exactly an existing protocol, we're done.
673 if (!(flags
& LIBIPSEC_ALGS_ADD_FORCE
))
674 return (LIBIPSEC_ALGS_DIAG_PROTO_EXISTS
);
675 delipsecproto_common(protos
, num_protos
--, current_proto
);
678 /* check for protocol with duplicate name */
679 for (i
= 0; i
< num_protos
; i
++) {
680 if (strcmp(protos
[i
].proto_name
, proto_name
) == 0) {
681 if (!(flags
& LIBIPSEC_ALGS_ADD_FORCE
))
682 return (LIBIPSEC_ALGS_DIAG_PROTO_EXISTS
);
683 delipsecproto_common(protos
, num_protos
--, &protos
[i
]);
688 /* add new protocol */
690 new_proto
= reallocarray(protos
, num_protos
, sizeof (ipsec_proto_t
));
691 if (new_proto
== NULL
) {
692 _clean_trash(protos
, num_protos
- 1);
693 return (LIBIPSEC_ALGS_DIAG_NOMEM
);
696 new_proto
+= (num_protos
- 1);
698 /* initialize protocol entry */
699 new_proto
->proto_num
= proto_num
;
700 new_proto
->proto_numalgs
= 0;
701 new_proto
->proto_algs
= NULL
;
702 new_proto
->proto_name
= strdup(proto_name
);
703 if (new_proto
->proto_name
== NULL
) {
704 _clean_trash(protos
, num_protos
);
705 return (LIBIPSEC_ALGS_DIAG_NOMEM
);
707 new_proto
->proto_pkg
= NULL
;
708 new_proto
->proto_algs_pkgs
= NULL
;
709 new_proto
->proto_algs_npkgs
= 0;
710 new_proto
->proto_exec_mode
= proto_exec_mode
;
712 return (write_new_algfile(protos
, num_protos
));
716 * Delete an IPsec protocol entry from /etc/inet/ipsecalgs. This also
717 * nukes the associated algorithms.
720 delipsecprotobynum(int proto_num
)
722 ipsec_proto_t
*protos
, *current_proto
;
725 if ((current_proto
= proto_setup(&protos
, &num_protos
, proto_num
,
727 return (LIBIPSEC_ALGS_DIAG_UNKN_PROTO
);
729 delipsecproto_common(protos
, num_protos
--, current_proto
);
731 return (write_new_algfile(protos
, num_protos
));
735 delipsecprotobyname(const char *proto_name
)
739 proto_num
= getipsecprotobyname(proto_name
);
741 return (LIBIPSEC_ALGS_DIAG_UNKN_PROTO
);
743 return (delipsecprotobynum(proto_num
));
747 * Implement these in libnsl since these are read-only operations.
750 getipsecprotos(int *nentries
)
752 return (_real_getipsecprotos(nentries
));
756 getipsecalgs(int *nentries
, int proto_num
)
758 return (_real_getipsecalgs(nentries
, proto_num
));
762 ipsecalgs_diag(int diag
)
765 case LIBIPSEC_ALGS_DIAG_ALG_EXISTS
:
766 return (dgettext(TEXT_DOMAIN
, "Algorithm already exists"));
767 case LIBIPSEC_ALGS_DIAG_PROTO_EXISTS
:
768 return (dgettext(TEXT_DOMAIN
, "Protocol already exists"));
769 case LIBIPSEC_ALGS_DIAG_UNKN_PROTO
:
770 return (dgettext(TEXT_DOMAIN
, "Unknown protocol"));
771 case LIBIPSEC_ALGS_DIAG_UNKN_ALG
:
772 return (dgettext(TEXT_DOMAIN
, "Unknown algorithm"));
773 case LIBIPSEC_ALGS_DIAG_NOMEM
:
774 return (dgettext(TEXT_DOMAIN
, "Out of memory"));
775 case LIBIPSEC_ALGS_DIAG_ALGSFILEOPEN
:
776 return (dgettext(TEXT_DOMAIN
, "open() failed"));
777 case LIBIPSEC_ALGS_DIAG_ALGSFILEFDOPEN
:
778 return (dgettext(TEXT_DOMAIN
, "fdopen() failed"));
779 case LIBIPSEC_ALGS_DIAG_ALGSFILELOCK
:
780 return (dgettext(TEXT_DOMAIN
, "lockf() failed"));
781 case LIBIPSEC_ALGS_DIAG_ALGSFILERENAME
:
782 return (dgettext(TEXT_DOMAIN
, "rename() failed"));
783 case LIBIPSEC_ALGS_DIAG_ALGSFILEWRITE
:
784 return (dgettext(TEXT_DOMAIN
, "write to file failed"));
785 case LIBIPSEC_ALGS_DIAG_ALGSFILECHMOD
:
786 return (dgettext(TEXT_DOMAIN
, "chmod() failed"));
787 case LIBIPSEC_ALGS_DIAG_ALGSFILECHOWN
:
788 return (dgettext(TEXT_DOMAIN
, "chown() failed"));
789 case LIBIPSEC_ALGS_DIAG_ALGSFILECLOSE
:
790 return (dgettext(TEXT_DOMAIN
, "close() failed"));
792 return (dgettext(TEXT_DOMAIN
, "failed"));
797 * Get the execution mode corresponding to the specified protocol.
798 * Returns 0 on success, one of the LIBIPSEC_ALGS_DIAG_* values on
802 ipsecproto_get_exec_mode(int proto_num
, ipsecalgs_exec_mode_t
*exec_mode
)
804 ipsec_proto_t
*protos
, *current_proto
;
807 if ((current_proto
= proto_setup(&protos
, &num_protos
, proto_num
,
809 return (LIBIPSEC_ALGS_DIAG_UNKN_PROTO
);
811 *exec_mode
= current_proto
->proto_exec_mode
;
813 _clean_trash(protos
, num_protos
);
818 * Set the execution mode of the specified protocol. Returns 0 on success,
819 * or one of the LIBIPSEC_ALGS_DIAG_* values on failure.
822 ipsecproto_set_exec_mode(int proto_num
, ipsecalgs_exec_mode_t exec_mode
)
824 ipsec_proto_t
*protos
, *current_proto
;
827 if ((current_proto
= proto_setup(&protos
, &num_protos
, proto_num
,
829 return (LIBIPSEC_ALGS_DIAG_UNKN_PROTO
);
831 current_proto
->proto_exec_mode
= exec_mode
;
833 return (write_new_algfile(protos
, num_protos
));