1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
8 * Copyright (C) 1998 by the FundsXpress, INC.
10 * All rights reserved.
12 * Export of this software from the United States of America may require
13 * a specific license from the United States Government. It is the
14 * responsibility of any person or organization contemplating export to
15 * obtain such a license before exporting.
17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18 * distribute this software and its documentation for any purpose and
19 * without fee is hereby granted, provided that the above copyright
20 * notice appear in all copies and that both that copyright notice and
21 * this permission notice appear in supporting documentation, and that
22 * the name of FundsXpress. not be used in advertising or publicity pertaining
23 * to distribution of the software without specific, written prior
24 * permission. FundsXpress makes no representations about the suitability of
25 * this software for any purpose. It is provided "as is" without express
26 * or implied warranty.
28 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
30 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
37 #include <sys/types.h>
39 #include <sys/select.h>
42 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h> /* inet_ntoa */
47 #include <gssrpc/rpc.h>
48 #include <gssapi/gssapi.h>
49 #include "gssapiP_krb5.h" /* for kg_get_context */
50 #include <gssrpc/auth_gssapi.h>
51 #include <kadm5/admin.h>
52 #include <kadm5/kadm_rpc.h>
53 #include <kadm5/server_acl.h>
54 #include <adm_proto.h>
55 #include "kdb_kt.h" /* for krb5_ktkdb_set_context */
57 #include "kadm5/server_internal.h" /* XXX for kadm5_server_handle_t */
62 #if defined(NEED_DAEMON_PROTO)
63 extern int daemon(int, int);
68 gss_name_t gss_changepw_name = NULL, gss_oldchangepw_name = NULL;
69 gss_name_t gss_kadmin_name = NULL;
70 void *global_server_handle;
72 extern krb5_keylist_node *master_keylist;
74 char *build_princ_name(char *name, char *realm);
75 void log_badauth(OM_uint32 major, OM_uint32 minor,
76 struct sockaddr_in *addr, char *data);
77 void log_badverf(gss_name_t client_name, gss_name_t server_name,
78 struct svc_req *rqst, struct rpc_msg *msg,
80 void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg, char
82 void log_badauth_display_status(char *msg, OM_uint32 major, OM_uint32 minor);
83 void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
87 void do_schpw(int s, kadm5_config_params *params);
93 #ifdef USE_PASSWORD_SERVER
94 void kadm5_set_use_password_server (void);
100 * Purpose: print out the server usage message
110 fprintf(stderr, _("Usage: kadmind [-x db_args]* [-r realm] [-m] [-nofork] "
111 "[-port port-number]\n"
112 "\t\t[-P pid_file]\n"
113 "\nwhere,\n\t[-x db_args]* - any number of database "
114 "specific arguments.\n"
115 "\t\t\tLook at each database documentation for "
116 "supported arguments\n"));
121 * Function: display_status
123 * Purpose: displays GSS-API messages
127 * msg a string to be displayed with the message
128 * maj_stat the GSS-API major status code
129 * min_stat the GSS-API minor status code
133 * The GSS-API messages associated with maj_stat and min_stat are
134 * displayed on stderr, each preceeded by "GSS-API error <msg>: " and
135 * followed by a newline.
137 static void display_status_1(char *, OM_uint32, int);
139 static void display_status(msg, maj_stat, min_stat)
144 display_status_1(msg, maj_stat, GSS_C_GSS_CODE);
145 display_status_1(msg, min_stat, GSS_C_MECH_CODE);
148 static void display_status_1(m, code, type)
153 OM_uint32 maj_stat, min_stat;
159 maj_stat = gss_display_status(&min_stat, code,
160 type, GSS_C_NULL_OID,
162 fprintf(stderr, _("GSS-API error %s: %s\n"), m, (char *)msg.value);
163 (void) gss_release_buffer(&min_stat, &msg);
171 * Function: write_pid_file
173 * Purpose: writes the current process PID to a file
177 * pid_file path to output file
178 * <return value> 0 on success, error code on failure
182 * The current process PID, obtained from getpid(), is written to the path
183 * given in pid_file, overwriting the existing contents if the file already
184 * exists. The PID will be followed by a newline.
187 write_pid_file(const char *pid_file)
192 file = fopen(pid_file, "w");
195 pid = (unsigned long) getpid();
196 if (fprintf(file, "%ld\n", pid) < 0 || fclose(file) == EOF)
201 /* XXX yuck. the signal handlers need this */
202 static krb5_context context;
204 static krb5_context hctx;
208 int main(int argc, char *argv[])
211 extern int optind, opterr;
213 OM_uint32 OMret, major_status, minor_status;
215 gss_buffer_desc in_buf;
216 auth_gssapi_name names[4];
217 gss_buffer_desc gssbuf;
218 gss_OID nt_krb5_name_oid;
219 kadm5_config_params params;
220 char **db_args = NULL;
221 int db_args_size = 0;
224 int strong_random = 1;
225 const char *pid_file = NULL;
227 kdb_log_context *log_ctx;
231 setlocale(LC_MESSAGES, "");
232 setvbuf(stderr, NULL, _IONBF, 0);
234 /* This is OID value the Krb5_Name NameType */
235 gssbuf.value = "{1 2 840 113554 1 2 2 1}";
236 gssbuf.length = strlen(gssbuf.value);
237 major_status = gss_str_to_oid(&minor_status, &gssbuf, &nt_krb5_name_oid);
238 if (major_status != GSS_S_COMPLETE) {
239 fprintf(stderr, _("Couldn't create KRB5 Name NameType OID\n"));
240 display_status("str_to_oid", major_status, minor_status);
244 names[0].name = names[1].name = names[2].name = names[3].name = NULL;
245 names[0].type = names[1].type = names[2].type = names[3].type =
248 whoami = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
252 memset(¶ms, 0, sizeof(params));
256 if (strcmp(*argv, "-x") == 0) {
262 char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
265 fprintf(stderr, _("%s: cannot initialize. Not enough "
266 "memory\n"), whoami);
271 db_args[db_args_size-1] = *argv;
272 db_args[db_args_size] = NULL;
273 }else if (strcmp(*argv, "-r") == 0) {
277 params.realm = *argv;
278 params.mask |= KADM5_CONFIG_REALM;
281 } else if (strcmp(*argv, "-m") == 0) {
282 params.mkey_from_kbd = 1;
283 params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
284 } else if (strcmp(*argv, "-nofork") == 0) {
286 #ifdef USE_PASSWORD_SERVER
287 } else if (strcmp(*argv, "-passwordserver") == 0) {
288 kadm5_set_use_password_server ();
290 } else if(strcmp(*argv, "-port") == 0) {
294 params.kadmind_port = atoi(*argv);
295 params.mask |= KADM5_CONFIG_KADMIND_PORT;
296 } else if (strcmp(*argv, "-P") == 0) {
301 } else if (strcmp(*argv, "-W") == 0) {
311 if ((ret = kadm5_init_krb5_context(&context))) {
312 fprintf(stderr, _("%s: %s while initializing context, aborting\n"),
313 whoami, error_message(ret));
317 krb5_klog_init(context, "admin_server", whoami, 1);
319 if((ret = kadm5_init(context, "kadmind", NULL,
321 KADM5_STRUCT_VERSION,
324 &global_server_handle)) != KADM5_OK) {
325 const char *e_txt = krb5_get_error_message (context, ret);
326 krb5_klog_syslog(LOG_ERR, _("%s while initializing, aborting"), e_txt);
327 fprintf(stderr, _("%s: %s while initializing, aborting\n"),
329 krb5_klog_close(context);
333 if ((ret = kadm5_get_config_params(context, 1, ¶ms,
335 const char *e_txt = krb5_get_error_message (context, ret);
336 krb5_klog_syslog(LOG_ERR, _("%s: %s while initializing, aborting"),
338 fprintf(stderr, _("%s: %s while initializing, aborting\n"),
340 kadm5_destroy(global_server_handle);
341 krb5_klog_close(context);
345 #define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_ACL_FILE)
347 if ((params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
348 krb5_klog_syslog(LOG_ERR,
349 _("%s: Missing required configuration values "
350 "(%lx) while initializing, aborting"), whoami,
351 (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
352 fprintf(stderr, _("%s: Missing required configuration values "
353 "(%lx) while initializing, aborting\n"), whoami,
354 (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
355 krb5_klog_close(context);
356 kadm5_destroy(global_server_handle);
360 ctx = loop_init(VERTO_EV_TYPE_SIGNAL);
362 krb5_klog_syslog(LOG_ERR,
363 _("%s: could not initialize loop, aborting"),
365 fprintf(stderr, _("%s: could not initialize loop, aborting\n"),
367 kadm5_destroy(global_server_handle);
368 krb5_klog_close(context);
372 if ((ret = loop_setup_signals(ctx, global_server_handle, NULL))) {
373 const char *e_txt = krb5_get_error_message (context, ret);
374 krb5_klog_syslog(LOG_ERR, _("%s: %s while initializing signal "
375 "handlers, aborting"), whoami, e_txt);
376 fprintf(stderr, _("%s: %s while initializing signal "
377 "handlers, aborting\n"), whoami, e_txt);
379 kadm5_destroy(global_server_handle);
380 krb5_klog_close(context);
384 #define server_handle ((kadm5_server_handle_t)global_server_handle)
385 if ((ret = loop_add_udp_port(server_handle->params.kpasswd_port))
386 || (ret = loop_add_tcp_port(server_handle->params.kpasswd_port))
387 || (ret = loop_add_rpc_service(server_handle->params.kadmind_port,
388 KADM, KADMVERS, kadm_1))
389 #ifndef DISABLE_IPROP
390 || (server_handle->params.iprop_enabled
391 ? (ret = loop_add_rpc_service(server_handle->params.iprop_port,
392 KRB5_IPROP_PROG, KRB5_IPROP_VERS,
397 || (ret = loop_setup_routing_socket(ctx, global_server_handle, whoami))
398 || (ret = loop_setup_network(ctx, global_server_handle, whoami))) {
399 const char *e_txt = krb5_get_error_message (context, ret);
400 krb5_klog_syslog(LOG_ERR, _("%s: %s while initializing network, "
401 "aborting"), whoami, e_txt);
402 fprintf(stderr, _("%s: %s while initializing network, aborting\n"),
405 kadm5_destroy(global_server_handle);
406 krb5_klog_close(context);
410 names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
411 names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
412 if (names[0].name == NULL || names[1].name == NULL) {
413 krb5_klog_syslog(LOG_ERR, _("Cannot build GSS-API authentication "
415 fprintf(stderr, _("%s: Cannot build GSS-API authentication names.\n"),
418 kadm5_destroy(global_server_handle);
419 krb5_klog_close(context);
424 * Go through some contortions to point gssapi at a kdb keytab.
425 * This prevents kadmind from needing to use an actual file-based
428 /* XXX extract kadm5's krb5_context */
429 hctx = ((kadm5_server_handle_t)global_server_handle)->context;
430 /* Set ktkdb's internal krb5_context. */
431 ret = krb5_ktkdb_set_context(hctx);
433 krb5_klog_syslog(LOG_ERR,
434 _("Can't set kdb keytab's internal context."));
437 ret = krb5_kt_register(context, &krb5_kt_kdb_ops);
439 krb5_klog_syslog(LOG_ERR, _("Can't register kdb keytab."));
442 /* Tell gssapi about the kdb keytab. */
443 ret = krb5_gss_register_acceptor_identity("KDB:");
445 krb5_klog_syslog(LOG_ERR, _("Can't register acceptor keytab."));
450 krb5_klog_syslog(LOG_ERR, "%s", krb5_get_error_message (context, ret));
451 fprintf(stderr, _("%s: Can't set up keytab for RPC.\n"), whoami);
453 kadm5_destroy(global_server_handle);
454 krb5_klog_close(context);
458 if (svcauth_gssapi_set_names(names, 2) == FALSE) {
459 krb5_klog_syslog(LOG_ERR, _("Cannot set GSS-API authentication names "
460 "(keytab not present?), failing."));
461 fprintf(stderr, _("%s: Cannot set GSS-API authentication names.\n"),
463 svcauth_gssapi_unset_names();
465 kadm5_destroy(global_server_handle);
466 krb5_klog_close(context);
470 /* if set_names succeeded, this will too */
471 in_buf.value = names[1].name;
472 in_buf.length = strlen(names[1].name) + 1;
473 (void) gss_import_name(&OMret, &in_buf, nt_krb5_name_oid,
476 svcauth_gssapi_set_log_badauth_func(log_badauth, NULL);
477 svcauth_gssapi_set_log_badverf_func(log_badverf, NULL);
478 svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL);
480 svcauth_gss_set_log_badauth_func(log_badauth, NULL);
481 svcauth_gss_set_log_badverf_func(log_badverf, NULL);
482 svcauth_gss_set_log_miscerr_func(log_miscerr, NULL);
484 if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE) {
485 fprintf(stderr, _("%s: Cannot initialize RPCSEC_GSS service name.\n"),
491 if ((ret = kadm5int_acl_init(context, 0, params.acl_file))) {
492 errmsg = krb5_get_error_message (context, ret);
493 krb5_klog_syslog(LOG_ERR, _("Cannot initialize acl file: %s"), errmsg);
494 fprintf(stderr, _("%s: Cannot initialize acl file: %s\n"),
496 svcauth_gssapi_unset_names();
498 kadm5_destroy(global_server_handle);
499 krb5_klog_close(context);
503 if (!nofork && (ret = daemon(0, 0))) {
505 errmsg = krb5_get_error_message (context, ret);
506 krb5_klog_syslog(LOG_ERR, _("Cannot detach from tty: %s"), errmsg);
507 fprintf(stderr, _("%s: Cannot detach from tty: %s\n"), whoami, errmsg);
508 svcauth_gssapi_unset_names();
510 kadm5_destroy(global_server_handle);
511 krb5_klog_close(context);
514 if (pid_file != NULL) {
515 ret = write_pid_file(pid_file);
517 errmsg = krb5_get_error_message(context, ret);
518 krb5_klog_syslog(LOG_ERR, _("Cannot create PID file %s: %s"),
520 svcauth_gssapi_unset_names();
522 kadm5_destroy(global_server_handle);
523 krb5_klog_close(context);
528 krb5_klog_syslog(LOG_INFO, _("Seeding random number generator"));
529 ret = krb5_c_random_os_entropy(context, strong_random, NULL);
531 krb5_klog_syslog(LOG_ERR, _("Error getting random seed: %s, aborting"),
532 krb5_get_error_message(context, ret));
533 svcauth_gssapi_unset_names();
535 kadm5_destroy(global_server_handle);
536 krb5_klog_close(context);
540 if (params.iprop_enabled == TRUE)
541 ulog_set_role(hctx, IPROP_MASTER);
543 ulog_set_role(hctx, IPROP_NULL);
545 log_ctx = hctx->kdblog_context;
547 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
549 * IProp is enabled, so let's map in the update log
550 * and setup the service.
552 if ((ret = ulog_map(hctx, params.iprop_logfile,
553 params.iprop_ulogsize, FKADMIND, db_args)) != 0) {
555 _("%s: %s while mapping update log (`%s.ulog')\n"),
556 whoami, error_message(ret), params.dbname);
557 krb5_klog_syslog(LOG_ERR,
558 _("%s while mapping update log (`%s.ulog')"),
559 error_message(ret), params.dbname);
561 krb5_klog_close(context);
568 _("%s: create IPROP svc (PROG=%d, VERS=%d)\n"),
569 whoami, KRB5_IPROP_PROG, KRB5_IPROP_VERS);
572 if (!svc_create(krb5_iprop_prog_1,
573 KRB5_IPROP_PROG, KRB5_IPROP_VERS,
576 _("%s: Cannot create IProp RPC service (PROG=%d, VERS=%d)\n"),
578 KRB5_IPROP_PROG, KRB5_IPROP_VERS);
579 krb5_klog_syslog(LOG_ERR,
580 _("Cannot create IProp RPC service (PROG=%d, VERS=%d), failing."),
581 KRB5_IPROP_PROG, KRB5_IPROP_VERS);
583 krb5_klog_close(context);
588 #if 0 /* authgss only? */
589 if ((ret = kiprop_get_adm_host_srv_name(context,
591 &kiprop_name)) != 0) {
592 krb5_klog_syslog(LOG_ERR,
593 _("%s while getting IProp svc name, failing"),
596 _("%s: %s while getting IProp svc name, failing\n"),
597 whoami, error_message(ret));
599 krb5_klog_close(context);
603 auth_gssapi_name iprop_name;
604 iprop_name.name = build_princ_name(foo, bar);
605 if (iprop_name.name == NULL) {
608 iprop_name.type = nt_krb5_name_oid;
609 if (svcauth_gssapi_set_names(&iprop_name, 1) == FALSE) {
612 if (!rpc_gss_set_svc_name(kiprop_name, "kerberos_v5", 0,
613 KRB5_IPROP_PROG, KRB5_IPROP_VERS)) {
615 (void) rpc_gss_get_error(&err);
617 krb5_klog_syslog(LOG_ERR,
618 _("Unable to set RPCSEC_GSS service name (`%s'), failing."),
619 kiprop_name ? kiprop_name : "<null>");
622 _("%s: Unable to set RPCSEC_GSS service name (`%s'), failing.\n"),
624 kiprop_name ? kiprop_name : "<null>");
628 "%s: set svc name (rpcsec err=%d, sys err=%d)\n",
641 krb5_klog_syslog(LOG_INFO, _("starting"));
643 fprintf(stderr, _("%s: starting...\n"), whoami);
646 krb5_klog_syslog(LOG_INFO, _("finished, exiting"));
648 /* Clean up memory, etc */
649 svcauth_gssapi_unset_names();
650 kadm5_destroy(global_server_handle);
652 kadm5int_acl_finish(context, 0);
653 if(gss_changepw_name) {
654 (void) gss_release_name(&OMret, &gss_changepw_name);
656 if(gss_oldchangepw_name) {
657 (void) gss_release_name(&OMret, &gss_oldchangepw_name);
659 for(i = 0 ; i < 4; i++) {
665 krb5_klog_close(context);
666 krb5_free_context(context);
671 * Function: build_princ_name
673 * Purpose: takes a name and a realm and builds a string that can be
674 * consumed by krb5_parse_name.
677 * name (input) name to be part of principal
678 * realm (input) realm part of principal
679 * <return value> char * pointing to "name@realm"
688 char *build_princ_name(char *name, char *realm)
693 if (asprintf(&fullname, "%s@%s", name, realm) < 0)
696 fullname = strdup(name);
702 * Function: log_badverf
704 * Purpose: Call from GSS-API Sun RPC for garbled/forged/replayed/etc
708 * client_name (r) GSS-API client name
709 * server_name (r) GSS-API server name
710 * rqst (r) RPC service request
711 * msg (r) RPC message
712 * data (r) arbitrary data (NULL), not used
716 * Logs the invalid request via krb5_klog_syslog(); see functional spec for
719 void log_badverf(gss_name_t client_name, gss_name_t server_name,
720 struct svc_req *rqst, struct rpc_msg *msg, char
725 const char *proc_name;
727 static const struct procnames proc_names[] = {
728 {1, "CREATE_PRINCIPAL"},
729 {2, "DELETE_PRINCIPAL"},
730 {3, "MODIFY_PRINCIPAL"},
731 {4, "RENAME_PRINCIPAL"},
732 {5, "GET_PRINCIPAL"},
733 {6, "CHPASS_PRINCIPAL"},
734 {7, "CHRAND_PRINCIPAL"},
735 {8, "CREATE_POLICY"},
736 {9, "DELETE_POLICY"},
737 {10, "MODIFY_POLICY"},
743 {16, "SETKEY_PRINCIPAL"},
744 {17, "SETV4KEY_PRINCIPAL"},
745 {18, "CREATE_PRINCIPAL3"},
746 {19, "CHPASS_PRINCIPAL3"},
747 {20, "CHRAND_PRINCIPAL3"},
748 {21, "SETKEY_PRINCIPAL3"},
753 #define NPROCNAMES (sizeof (proc_names) / sizeof (struct procnames))
755 gss_buffer_desc client, server;
760 const char *procname;
769 (void) gss_display_name(&minor, client_name, &client, &gss_type);
770 (void) gss_display_name(&minor, server_name, &server, &gss_type);
771 if (client.value == NULL) {
772 client.value = "(null)";
773 clen = sizeof("(null)") -1;
775 clen = client.length;
777 trunc_name(&clen, &cdots);
778 if (server.value == NULL) {
779 server.value = "(null)";
780 slen = sizeof("(null)") - 1;
782 slen = server.length;
784 trunc_name(&slen, &sdots);
785 a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
787 proc = msg->rm_call.cb_proc;
789 for (i = 0; i < NPROCNAMES; i++) {
790 if (proc_names[i].proc == proc) {
791 procname = proc_names[i].proc_name;
795 if (procname != NULL)
796 krb5_klog_syslog(LOG_NOTICE,
797 _("WARNING! Forged/garbled request: %s, claimed "
798 "client = %.*s%s, server = %.*s%s, addr = %s"),
799 procname, (int) clen, (char *) client.value, cdots,
800 (int) slen, (char *) server.value, sdots, a);
802 krb5_klog_syslog(LOG_NOTICE,
803 _("WARNING! Forged/garbled request: %d, claimed "
804 "client = %.*s%s, server = %.*s%s, addr = %s"),
805 proc, (int) clen, (char *) client.value, cdots,
806 (int) slen, (char *) server.value, sdots, a);
808 (void) gss_release_buffer(&minor, &client);
809 (void) gss_release_buffer(&minor, &server);
813 * Function: log_miscerr
815 * Purpose: Callback from GSS-API Sun RPC for miscellaneous errors
818 * rqst (r) RPC service request
819 * msg (r) RPC message
820 * error (r) error message from RPC
821 * data (r) arbitrary data (NULL), not used
825 * Logs the error via krb5_klog_syslog(); see functional spec for
828 void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
829 char *error, char *data)
833 a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
834 krb5_klog_syslog(LOG_NOTICE, _("Miscellaneous RPC error: %s, %s"), a,
841 * Function: log_badauth
843 * Purpose: Callback from GSS-API Sun RPC for authentication
847 * major (r) GSS-API major status
848 * minor (r) GSS-API minor status
849 * addr (r) originating address
850 * data (r) arbitrary data (NULL), not used
854 * Logs the GSS-API error via krb5_klog_syslog(); see functional spec for
857 void log_badauth(OM_uint32 major, OM_uint32 minor,
858 struct sockaddr_in *addr, char *data)
862 /* Authentication attempt failed: <IP address>, <GSS-API error */
865 a = inet_ntoa(addr->sin_addr);
867 krb5_klog_syslog(LOG_NOTICE, _("Authentication attempt failed: %s, "
868 "GSS-API error strings are:"), a);
869 log_badauth_display_status(" ", major, minor);
870 krb5_klog_syslog(LOG_NOTICE, _(" GSS-API error strings complete."));
873 void log_badauth_display_status(char *msg, OM_uint32 major, OM_uint32 minor)
875 log_badauth_display_status_1(msg, major, GSS_C_GSS_CODE, 0);
876 log_badauth_display_status_1(msg, minor, GSS_C_MECH_CODE, 0);
879 void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
882 OM_uint32 gssstat, minor_stat;
888 gssstat = gss_display_status(&minor_stat, code,
889 type, GSS_C_NULL_OID,
891 if (gssstat != GSS_S_COMPLETE) {
893 log_badauth_display_status_1(m,gssstat,GSS_C_GSS_CODE,1);
894 log_badauth_display_status_1(m, minor_stat,
897 krb5_klog_syslog(LOG_ERR,
898 _("GSS-API authentication error %.*s: "
899 "recursive failure!"), (int) msg.length,
904 krb5_klog_syslog(LOG_NOTICE, "%s %.*s", m, (int)msg.length,
906 (void) gss_release_buffer(&minor_stat, &msg);