2 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
7 * Copyright (C) 1998 by the FundsXpress, INC.
11 * Export of this software from the United States of America may require
12 * a specific license from the United States Government. It is the
13 * responsibility of any person or organization contemplating export to
14 * obtain such a license before exporting.
16 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
17 * distribute this software and its documentation for any purpose and
18 * without fee is hereby granted, provided that the above copyright
19 * notice appear in all copies and that both that copyright notice and
20 * this permission notice appear in supporting documentation, and that
21 * the name of FundsXpress. not be used in advertising or publicity pertaining
22 * to distribution of the software without specific, written prior
23 * permission. FundsXpress makes no representations about the suitability of
24 * this software for any purpose. It is provided "as is" without express
25 * or implied warranty.
27 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
28 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
29 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
35 #include <sys/types.h>
37 #include <sys/select.h>
40 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h> /* inet_ntoa */
45 #include <gssrpc/rpc.h>
46 #include <gssapi/gssapi.h>
47 #include "gssapiP_krb5.h" /* for kg_get_context */
48 #include <gssrpc/auth_gssapi.h>
49 #include <kadm5/admin.h>
50 #include <kadm5/kadm_rpc.h>
51 #include <kadm5/server_acl.h>
52 #include <adm_proto.h>
53 #include "kdb_kt.h" /* for krb5_ktkdb_set_context */
55 #include "kadm5/server_internal.h" /* XXX for kadm5_server_handle_t */
63 int signal_pure_report = 0;
64 int signal_pure_clear = 0;
65 void request_pure_report(int);
66 void request_pure_clear(int);
69 #if defined(NEED_DAEMON_PROTO)
70 extern int daemon(int, int);
73 volatile int signal_request_exit = 0;
74 volatile int signal_request_hup = 0;
75 void setup_signal_handlers(iprop_role iproprole);
76 void request_exit(int);
77 void request_hup(int);
82 static struct sigaction s_action;
83 #endif /* POSIX_SIGNALS */
88 gss_name_t gss_changepw_name = NULL, gss_oldchangepw_name = NULL;
89 gss_name_t gss_kadmin_name = NULL;
90 void *global_server_handle;
92 extern krb5_keyblock master_keyblock;
93 extern krb5_keylist_node *master_keylist;
95 char *build_princ_name(char *name, char *realm);
96 void log_badauth(OM_uint32 major, OM_uint32 minor,
97 struct sockaddr_in *addr, char *data);
98 void log_badverf(gss_name_t client_name, gss_name_t server_name,
99 struct svc_req *rqst, struct rpc_msg *msg,
101 void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg, char
103 void log_badauth_display_status(char *msg, OM_uint32 major, OM_uint32 minor);
104 void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
108 void do_schpw(int s, kadm5_config_params *params);
110 #ifndef DISABLE_IPROP
114 #ifdef USE_PASSWORD_SERVER
115 void kadm5_set_use_password_server (void);
121 * Purpose: print out the server usage message
131 fprintf(stderr, "Usage: kadmind [-x db_args]* [-r realm] [-m] [-nofork] "
132 #ifdef USE_PASSWORD_SERVER
135 "[-port port-number]\n"
136 "\nwhere,\n\t[-x db_args]* - any number of database specific arguments.\n"
137 "\t\t\tLook at each database documentation for supported arguments\n"
143 * Function: display_status
145 * Purpose: displays GSS-API messages
149 * msg a string to be displayed with the message
150 * maj_stat the GSS-API major status code
151 * min_stat the GSS-API minor status code
155 * The GSS-API messages associated with maj_stat and min_stat are
156 * displayed on stderr, each preceeded by "GSS-API error <msg>: " and
157 * followed by a newline.
159 static void display_status_1(char *, OM_uint32, int);
161 static void display_status(msg, maj_stat, min_stat)
166 display_status_1(msg, maj_stat, GSS_C_GSS_CODE);
167 display_status_1(msg, min_stat, GSS_C_MECH_CODE);
170 static void display_status_1(m, code, type)
175 OM_uint32 maj_stat, min_stat;
181 maj_stat = gss_display_status(&min_stat, code,
182 type, GSS_C_NULL_OID,
184 fprintf(stderr, "GSS-API error %s: %s\n", m,
186 (void) gss_release_buffer(&min_stat, &msg);
194 /* XXX yuck. the signal handlers need this */
195 static krb5_context context;
197 static krb5_context hctx;
201 int main(int argc, char *argv[])
204 extern int optind, opterr;
206 OM_uint32 OMret, major_status, minor_status;
208 gss_buffer_desc in_buf;
209 auth_gssapi_name names[4];
210 gss_buffer_desc gssbuf;
211 gss_OID nt_krb5_name_oid;
212 kadm5_config_params params;
213 char **db_args = NULL;
214 int db_args_size = 0;
217 int strong_random = 1;
219 kdb_log_context *log_ctx;
221 setvbuf(stderr, NULL, _IONBF, 0);
223 /* This is OID value the Krb5_Name NameType */
224 gssbuf.value = "{1 2 840 113554 1 2 2 1}";
225 gssbuf.length = strlen(gssbuf.value);
226 major_status = gss_str_to_oid(&minor_status, &gssbuf, &nt_krb5_name_oid);
227 if (major_status != GSS_S_COMPLETE) {
228 fprintf(stderr, "Couldn't create KRB5 Name NameType OID\n");
229 display_status("str_to_oid", major_status, minor_status);
233 names[0].name = names[1].name = names[2].name = names[3].name = NULL;
234 names[0].type = names[1].type = names[2].type = names[3].type =
238 purify_start_batch();
240 whoami = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
244 memset(¶ms, 0, sizeof(params));
248 if (strcmp(*argv, "-x") == 0) {
254 char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
257 fprintf(stderr,"%s: cannot initialize. Not enough memory\n",
263 db_args[db_args_size-1] = *argv;
264 db_args[db_args_size] = NULL;
265 }else if (strcmp(*argv, "-r") == 0) {
269 params.realm = *argv;
270 params.mask |= KADM5_CONFIG_REALM;
273 } else if (strcmp(*argv, "-m") == 0) {
274 params.mkey_from_kbd = 1;
275 params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
276 } else if (strcmp(*argv, "-nofork") == 0) {
278 #ifdef USE_PASSWORD_SERVER
279 } else if (strcmp(*argv, "-passwordserver") == 0) {
280 kadm5_set_use_password_server ();
282 } else if(strcmp(*argv, "-port") == 0) {
286 params.kadmind_port = atoi(*argv);
287 params.mask |= KADM5_CONFIG_KADMIND_PORT;
288 } else if (strcmp(*argv, "-W") == 0) {
298 if ((ret = kadm5_init_krb5_context(&context))) {
299 fprintf(stderr, "%s: %s while initializing context, aborting\n",
300 whoami, error_message(ret));
304 krb5_klog_init(context, "admin_server", whoami, 1);
306 if((ret = kadm5_init(context, "kadmind", NULL,
308 KADM5_STRUCT_VERSION,
311 &global_server_handle)) != KADM5_OK) {
312 const char *e_txt = krb5_get_error_message (context, ret);
313 krb5_klog_syslog(LOG_ERR, "%s while initializing, aborting",
315 fprintf(stderr, "%s: %s while initializing, aborting\n",
317 krb5_klog_close(context);
321 if ((ret = kadm5_get_config_params(context, 1, ¶ms,
323 const char *e_txt = krb5_get_error_message (context, ret);
324 krb5_klog_syslog(LOG_ERR, "%s: %s while initializing, aborting",
326 fprintf(stderr, "%s: %s while initializing, aborting\n",
328 kadm5_destroy(global_server_handle);
329 krb5_klog_close(context);
333 #define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_ACL_FILE)
335 if ((params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
336 krb5_klog_syslog(LOG_ERR, "%s: Missing required configuration values "
337 "(%lx) while initializing, aborting", whoami,
338 (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
339 fprintf(stderr, "%s: Missing required configuration values "
340 "(%lx) while initializing, aborting\n", whoami,
341 (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
342 krb5_klog_close(context);
343 kadm5_destroy(global_server_handle);
347 if ((ret = setup_network(global_server_handle, whoami))) {
348 const char *e_txt = krb5_get_error_message (context, ret);
349 krb5_klog_syslog(LOG_ERR, "%s: %s while initializing network, aborting",
351 fprintf(stderr, "%s: %s while initializing network, aborting\n",
353 kadm5_destroy(global_server_handle);
354 krb5_klog_close(context);
358 names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
359 names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
360 if (names[0].name == NULL || names[1].name == NULL) {
361 krb5_klog_syslog(LOG_ERR,
362 "Cannot build GSS-API authentication names, "
364 fprintf(stderr, "%s: Cannot build GSS-API authentication names.\n",
366 kadm5_destroy(global_server_handle);
367 krb5_klog_close(context);
372 * Go through some contortions to point gssapi at a kdb keytab.
373 * This prevents kadmind from needing to use an actual file-based
376 /* XXX extract kadm5's krb5_context */
377 hctx = ((kadm5_server_handle_t)global_server_handle)->context;
378 /* Set ktkdb's internal krb5_context. */
379 ret = krb5_ktkdb_set_context(hctx);
381 krb5_klog_syslog(LOG_ERR, "Can't set kdb keytab's internal context.");
384 /* XXX master_keyblock is in guts of lib/kadm5/server_kdb.c */
385 ret = krb5_db_set_mkey(hctx, &master_keyblock);
387 krb5_klog_syslog(LOG_ERR, "Can't set master key for kdb keytab.");
390 ret = krb5_db_set_mkey_list(hctx, master_keylist);
392 krb5_klog_syslog(LOG_ERR, "Can't set master key list for kdb keytab.");
395 ret = krb5_kt_register(context, &krb5_kt_kdb_ops);
397 krb5_klog_syslog(LOG_ERR, "Can't register kdb keytab.");
400 /* Tell gssapi about the kdb keytab. */
401 ret = krb5_gss_register_acceptor_identity("KDB:");
403 krb5_klog_syslog(LOG_ERR, "Can't register acceptor keytab.");
408 krb5_klog_syslog(LOG_ERR, "%s", krb5_get_error_message (context, ret));
409 fprintf(stderr, "%s: Can't set up keytab for RPC.\n", whoami);
410 kadm5_destroy(global_server_handle);
411 krb5_klog_close(context);
415 if (svcauth_gssapi_set_names(names, 2) == FALSE) {
416 krb5_klog_syslog(LOG_ERR,
417 "Cannot set GSS-API authentication names (keytab not present?), "
419 fprintf(stderr, "%s: Cannot set GSS-API authentication names.\n",
421 svcauth_gssapi_unset_names();
422 kadm5_destroy(global_server_handle);
423 krb5_klog_close(context);
427 /* if set_names succeeded, this will too */
428 in_buf.value = names[1].name;
429 in_buf.length = strlen(names[1].name) + 1;
430 (void) gss_import_name(&OMret, &in_buf, nt_krb5_name_oid,
433 svcauth_gssapi_set_log_badauth_func(log_badauth, NULL);
434 svcauth_gssapi_set_log_badverf_func(log_badverf, NULL);
435 svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL);
437 svcauth_gss_set_log_badauth_func(log_badauth, NULL);
438 svcauth_gss_set_log_badverf_func(log_badverf, NULL);
439 svcauth_gss_set_log_miscerr_func(log_miscerr, NULL);
441 if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE) {
442 fprintf(stderr, "%s: Cannot initialize RPCSEC_GSS service name.\n",
447 if ((ret = kadm5int_acl_init(context, 0, params.acl_file))) {
448 errmsg = krb5_get_error_message (context, ret);
449 krb5_klog_syslog(LOG_ERR, "Cannot initialize acl file: %s",
451 fprintf(stderr, "%s: Cannot initialize acl file: %s\n",
453 svcauth_gssapi_unset_names();
454 kadm5_destroy(global_server_handle);
455 krb5_klog_close(context);
459 if (!nofork && (ret = daemon(0, 0))) {
461 errmsg = krb5_get_error_message (context, ret);
462 krb5_klog_syslog(LOG_ERR, "Cannot detach from tty: %s", errmsg);
463 fprintf(stderr, "%s: Cannot detach from tty: %s\n",
465 svcauth_gssapi_unset_names();
466 kadm5_destroy(global_server_handle);
467 krb5_klog_close(context);
471 krb5_klog_syslog(LOG_INFO, "Seeding random number generator");
472 ret = krb5_c_random_os_entropy(context, strong_random, NULL);
474 krb5_klog_syslog(LOG_ERR, "Error getting random seed: %s, aborting",
475 krb5_get_error_message(context, ret));
476 svcauth_gssapi_unset_names();
477 kadm5_destroy(global_server_handle);
478 krb5_klog_close(context);
482 if (params.iprop_enabled == TRUE)
483 ulog_set_role(hctx, IPROP_MASTER);
485 ulog_set_role(hctx, IPROP_NULL);
487 log_ctx = hctx->kdblog_context;
489 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
491 * IProp is enabled, so let's map in the update log
492 * and setup the service.
494 if ((ret = ulog_map(hctx, params.iprop_logfile,
495 params.iprop_ulogsize, FKADMIND, db_args)) != 0) {
497 _("%s: %s while mapping update log (`%s.ulog')\n"),
498 whoami, error_message(ret), params.dbname);
499 krb5_klog_syslog(LOG_ERR,
500 _("%s while mapping update log (`%s.ulog')"),
501 error_message(ret), params.dbname);
502 krb5_klog_close(context);
509 "%s: create IPROP svc (PROG=%d, VERS=%d)\n",
510 whoami, KRB5_IPROP_PROG, KRB5_IPROP_VERS);
513 if (!svc_create(krb5_iprop_prog_1,
514 KRB5_IPROP_PROG, KRB5_IPROP_VERS,
517 _("%s: Cannot create IProp RPC service (PROG=%d, VERS=%d)\n"),
519 KRB5_IPROP_PROG, KRB5_IPROP_VERS);
520 krb5_klog_syslog(LOG_ERR,
521 _("Cannot create IProp RPC service (PROG=%d, VERS=%d), failing."),
522 KRB5_IPROP_PROG, KRB5_IPROP_VERS);
523 krb5_klog_close(context);
528 #if 0 /* authgss only? */
529 if ((ret = kiprop_get_adm_host_srv_name(context,
531 &kiprop_name)) != 0) {
532 krb5_klog_syslog(LOG_ERR,
533 _("%s while getting IProp svc name, failing"),
536 _("%s: %s while getting IProp svc name, failing\n"),
537 whoami, error_message(ret));
538 krb5_klog_close(context);
542 auth_gssapi_name iprop_name;
543 iprop_name.name = build_princ_name(foo, bar);
544 if (iprop_name.name == NULL) {
547 iprop_name.type = nt_krb5_name_oid;
548 if (svcauth_gssapi_set_names(&iprop_name, 1) == FALSE) {
551 if (!rpc_gss_set_svc_name(kiprop_name, "kerberos_v5", 0,
552 KRB5_IPROP_PROG, KRB5_IPROP_VERS)) {
554 (void) rpc_gss_get_error(&err);
556 krb5_klog_syslog(LOG_ERR,
557 _("Unable to set RPCSEC_GSS service name (`%s'), failing."),
558 kiprop_name ? kiprop_name : "<null>");
561 _("%s: Unable to set RPCSEC_GSS service name (`%s'), failing.\n"),
563 kiprop_name ? kiprop_name : "<null>");
567 "%s: set svc name (rpcsec err=%d, sys err=%d)\n",
579 setup_signal_handlers(log_ctx->iproprole);
580 krb5_klog_syslog(LOG_INFO, _("starting"));
582 fprintf(stderr, "%s: starting...\n", whoami);
584 listen_and_process(global_server_handle, whoami);
585 krb5_klog_syslog(LOG_INFO, "finished, exiting");
587 /* Clean up memory, etc */
588 svcauth_gssapi_unset_names();
589 kadm5_destroy(global_server_handle);
590 closedown_network(global_server_handle, whoami);
591 kadm5int_acl_finish(context, 0);
592 if(gss_changepw_name) {
593 (void) gss_release_name(&OMret, &gss_changepw_name);
595 if(gss_oldchangepw_name) {
596 (void) gss_release_name(&OMret, &gss_oldchangepw_name);
598 for(i = 0 ; i < 4; i++) {
604 krb5_klog_close(context);
605 krb5_free_context(context);
610 * Function: setup_signal_handlers
612 * Purpose: Setup signal handling functions using POSIX's sigaction()
613 * if possible, otherwise with System V's signal().
616 void setup_signal_handlers(iprop_role iproprole) {
618 (void) sigemptyset(&s_action.sa_mask);
619 s_action.sa_handler = request_exit;
620 (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
621 (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
622 (void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
623 s_action.sa_handler = request_hup;
624 (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
625 s_action.sa_handler = sig_pipe;
626 (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
628 s_action.sa_handler = request_pure_report;
629 (void) sigaction(SIGUSR1, &s_action, (struct sigaction *) NULL);
630 s_action.sa_handler = request_pure_clear;
631 (void) sigaction(SIGUSR2, &s_action, (struct sigaction *) NULL);
635 * IProp will fork for a full-resync, we don't want to
636 * wait on it and we don't want the living dead procs either.
638 if (iproprole == IPROP_MASTER) {
639 s_action.sa_handler = SIG_IGN;
640 (void) sigaction(SIGCHLD, &s_action, (struct sigaction *) NULL);
642 #else /* POSIX_SIGNALS */
643 signal(SIGINT, request_exit);
644 signal(SIGTERM, request_exit);
645 signal(SIGQUIT, request_exit);
646 signal(SIGHUP, request_hup);
647 signal(SIGPIPE, sig_pipe);
649 signal(SIGUSR1, request_pure_report);
650 signal(SIGUSR2, request_pure_clear);
654 * IProp will fork for a full-resync, we don't want to
655 * wait on it and we don't want the living dead procs either.
657 if (iproprole == IPROP_MASTER)
658 (void) signal(SIGCHLD, SIG_IGN);
659 #endif /* POSIX_SIGNALS */
664 * Function: request_pure_report
666 * Purpose: sets flag saying the server got a signal and that it should
667 * dump a purify report when convenient.
673 * sets signal_pure_report to one
676 void request_pure_report(int signum)
678 krb5_klog_syslog(LOG_DEBUG, "Got signal to request a Purify report");
679 signal_pure_report = 1;
684 * Function: request_pure_clear
686 * Purpose: sets flag saying the server got a signal and that it should
687 * dump a purify report when convenient, then clear the
694 * sets signal_pure_report to one
695 * sets signal_pure_clear to one
698 void request_pure_clear(int signum)
700 krb5_klog_syslog(LOG_DEBUG, "Got signal to request a Purify report and clear the old Purify info");
701 signal_pure_report = 1;
702 signal_pure_clear = 1;
708 * Function: request_hup
710 * Purpose: sets flag saying the server got a signal and that it should
711 * reset the database files when convenient.
717 * sets signal_request_hup to one
720 void request_hup(int signum)
722 signal_request_hup = 1;
729 * Purpose: flushes the currently opened database files to disk.
735 * Currently, just sets signal_request_reset to 0. The kdb and adb
736 * libraries used to be sufficiently broken that it was prudent to
737 * close and reopen the databases periodically. They are no longer
738 * that broken, so this function is not necessary.
746 if (ret = kadm5_flush(global_server_handle)) {
747 krb5_klog_syslog(LOG_ERR, "FATAL ERROR! %s while flushing databases. "
748 "Databases may be corrupt! Aborting.",
749 krb5_get_error_message (context, ret));
750 krb5_klog_close(context);
759 * Function: request_exit
761 * Purpose: sets flags saying the server got a signal and that it
762 * should exit when convient.
767 * modifies signal_request_exit which ideally makes the server exit
771 * signal_request_exit
774 void request_exit(int signum)
776 krb5_klog_syslog(LOG_DEBUG, "Got signal to request exit");
777 signal_request_exit = 1;
784 * Purpose: SIGPIPE handler
786 * Effects: krb5_klog_syslogs a message that a SIGPIPE occurred and returns,
787 * thus causing the read() or write() to fail and, presumable, the RPC
788 * to recover. Otherwise, the process aborts.
790 void sig_pipe(int unused)
792 krb5_klog_syslog(LOG_NOTICE, "Warning: Received a SIGPIPE; probably a "
793 "client aborted. Continuing.");
798 * Function: build_princ_name
800 * Purpose: takes a name and a realm and builds a string that can be
801 * consumed by krb5_parse_name.
804 * name (input) name to be part of principal
805 * realm (input) realm part of principal
806 * <return value> char * pointing to "name@realm"
815 char *build_princ_name(char *name, char *realm)
820 if (asprintf(&fullname, "%s@%s", name, realm) < 0)
823 fullname = strdup(name);
829 * Function: log_badverf
831 * Purpose: Call from GSS-API Sun RPC for garbled/forged/replayed/etc
835 * client_name (r) GSS-API client name
836 * server_name (r) GSS-API server name
837 * rqst (r) RPC service request
838 * msg (r) RPC message
839 * data (r) arbitrary data (NULL), not used
843 * Logs the invalid request via krb5_klog_syslog(); see functional spec for
846 void log_badverf(gss_name_t client_name, gss_name_t server_name,
847 struct svc_req *rqst, struct rpc_msg *msg, char
852 const char *proc_name;
854 static const struct procnames proc_names[] = {
855 {1, "CREATE_PRINCIPAL"},
856 {2, "DELETE_PRINCIPAL"},
857 {3, "MODIFY_PRINCIPAL"},
858 {4, "RENAME_PRINCIPAL"},
859 {5, "GET_PRINCIPAL"},
860 {6, "CHPASS_PRINCIPAL"},
861 {7, "CHRAND_PRINCIPAL"},
862 {8, "CREATE_POLICY"},
863 {9, "DELETE_POLICY"},
864 {10, "MODIFY_POLICY"},
870 {16, "SETKEY_PRINCIPAL"},
871 {17, "SETV4KEY_PRINCIPAL"},
872 {18, "CREATE_PRINCIPAL3"},
873 {19, "CHPASS_PRINCIPAL3"},
874 {20, "CHRAND_PRINCIPAL3"},
875 {21, "SETKEY_PRINCIPAL3"}
877 #define NPROCNAMES (sizeof (proc_names) / sizeof (struct procnames))
879 gss_buffer_desc client, server;
884 const char *procname;
893 (void) gss_display_name(&minor, client_name, &client, &gss_type);
894 (void) gss_display_name(&minor, server_name, &server, &gss_type);
895 if (client.value == NULL) {
896 client.value = "(null)";
897 clen = sizeof("(null)") -1;
899 clen = client.length;
901 trunc_name(&clen, &cdots);
902 if (server.value == NULL) {
903 server.value = "(null)";
904 slen = sizeof("(null)") - 1;
906 slen = server.length;
908 trunc_name(&slen, &sdots);
909 a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
911 proc = msg->rm_call.cb_proc;
913 for (i = 0; i < NPROCNAMES; i++) {
914 if (proc_names[i].proc == proc) {
915 procname = proc_names[i].proc_name;
919 if (procname != NULL)
920 krb5_klog_syslog(LOG_NOTICE, "WARNING! Forged/garbled request: %s, "
921 "claimed client = %.*s%s, server = %.*s%s, addr = %s",
922 procname, (int) clen, (char *) client.value, cdots,
923 (int) slen, (char *) server.value, sdots, a);
925 krb5_klog_syslog(LOG_NOTICE, "WARNING! Forged/garbled request: %d, "
926 "claimed client = %.*s%s, server = %.*s%s, addr = %s",
927 proc, (int) clen, (char *) client.value, cdots,
928 (int) slen, (char *) server.value, sdots, a);
930 (void) gss_release_buffer(&minor, &client);
931 (void) gss_release_buffer(&minor, &server);
935 * Function: log_miscerr
937 * Purpose: Callback from GSS-API Sun RPC for miscellaneous errors
940 * rqst (r) RPC service request
941 * msg (r) RPC message
942 * error (r) error message from RPC
943 * data (r) arbitrary data (NULL), not used
947 * Logs the error via krb5_klog_syslog(); see functional spec for
950 void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
951 char *error, char *data)
955 a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
956 krb5_klog_syslog(LOG_NOTICE, "Miscellaneous RPC error: %s, %s", a, error);
962 * Function: log_badauth
964 * Purpose: Callback from GSS-API Sun RPC for authentication
968 * major (r) GSS-API major status
969 * minor (r) GSS-API minor status
970 * addr (r) originating address
971 * data (r) arbitrary data (NULL), not used
975 * Logs the GSS-API error via krb5_klog_syslog(); see functional spec for
978 void log_badauth(OM_uint32 major, OM_uint32 minor,
979 struct sockaddr_in *addr, char *data)
983 /* Authentication attempt failed: <IP address>, <GSS-API error */
986 a = inet_ntoa(addr->sin_addr);
988 krb5_klog_syslog(LOG_NOTICE, "Authentication attempt failed: %s, GSS-API "
989 "error strings are:", a);
990 log_badauth_display_status(" ", major, minor);
991 krb5_klog_syslog(LOG_NOTICE, " GSS-API error strings complete.");
994 void log_badauth_display_status(char *msg, OM_uint32 major, OM_uint32 minor)
996 log_badauth_display_status_1(msg, major, GSS_C_GSS_CODE, 0);
997 log_badauth_display_status_1(msg, minor, GSS_C_MECH_CODE, 0);
1000 void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
1003 OM_uint32 gssstat, minor_stat;
1004 gss_buffer_desc msg;
1009 gssstat = gss_display_status(&minor_stat, code,
1010 type, GSS_C_NULL_OID,
1012 if (gssstat != GSS_S_COMPLETE) {
1014 log_badauth_display_status_1(m,gssstat,GSS_C_GSS_CODE,1);
1015 log_badauth_display_status_1(m, minor_stat,
1016 GSS_C_MECH_CODE, 1);
1018 krb5_klog_syslog(LOG_ERR, "GSS-API authentication error %.*s: "
1019 "recursive failure!", (int) msg.length,
1020 (char *) msg.value);
1024 krb5_klog_syslog(LOG_NOTICE, "%s %.*s", m, (int)msg.length,
1026 (void) gss_release_buffer(&minor_stat, &msg);