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 */
65 int signal_pure_report = 0;
66 int signal_pure_clear = 0;
67 void request_pure_report(int);
68 void request_pure_clear(int);
71 #if defined(NEED_DAEMON_PROTO)
72 extern int daemon(int, int);
75 void setup_signal_handlers(iprop_role iproprole);
76 void request_exit(int);
77 void request_hup(int);
81 static struct sigaction s_action;
82 #endif /* POSIX_SIGNALS */
87 gss_name_t gss_changepw_name = NULL, gss_oldchangepw_name = NULL;
88 gss_name_t gss_kadmin_name = NULL;
89 void *global_server_handle;
91 extern krb5_keylist_node *master_keylist;
93 char *build_princ_name(char *name, char *realm);
94 void log_badauth(OM_uint32 major, OM_uint32 minor,
95 struct sockaddr_in *addr, char *data);
96 void log_badverf(gss_name_t client_name, gss_name_t server_name,
97 struct svc_req *rqst, struct rpc_msg *msg,
99 void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg, char
101 void log_badauth_display_status(char *msg, OM_uint32 major, OM_uint32 minor);
102 void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
106 void do_schpw(int s, kadm5_config_params *params);
108 #ifndef DISABLE_IPROP
112 #ifdef USE_PASSWORD_SERVER
113 void kadm5_set_use_password_server (void);
119 * Purpose: print out the server usage message
129 fprintf(stderr, _("Usage: kadmind [-x db_args]* [-r realm] [-m] [-nofork] "
130 "[-port port-number]\n"
131 "\t\t[-P pid_file]\n"
132 "\nwhere,\n\t[-x db_args]* - any number of database "
133 "specific arguments.\n"
134 "\t\t\tLook at each database documentation for "
135 "supported arguments\n"));
140 * Function: display_status
142 * Purpose: displays GSS-API messages
146 * msg a string to be displayed with the message
147 * maj_stat the GSS-API major status code
148 * min_stat the GSS-API minor status code
152 * The GSS-API messages associated with maj_stat and min_stat are
153 * displayed on stderr, each preceeded by "GSS-API error <msg>: " and
154 * followed by a newline.
156 static void display_status_1(char *, OM_uint32, int);
158 static void display_status(msg, maj_stat, min_stat)
163 display_status_1(msg, maj_stat, GSS_C_GSS_CODE);
164 display_status_1(msg, min_stat, GSS_C_MECH_CODE);
167 static void display_status_1(m, code, type)
172 OM_uint32 maj_stat, min_stat;
178 maj_stat = gss_display_status(&min_stat, code,
179 type, GSS_C_NULL_OID,
181 fprintf(stderr, _("GSS-API error %s: %s\n"), m, (char *)msg.value);
182 (void) gss_release_buffer(&min_stat, &msg);
190 * Function: write_pid_file
192 * Purpose: writes the current process PID to a file
196 * pid_file path to output file
197 * <return value> 0 on success, error code on failure
201 * The current process PID, obtained from getpid(), is written to the path
202 * given in pid_file, overwriting the existing contents if the file already
203 * exists. The PID will be followed by a newline.
206 write_pid_file(const char *pid_file)
211 file = fopen(pid_file, "w");
214 pid = (unsigned long) getpid();
215 if (fprintf(file, "%ld\n", pid) < 0 || fclose(file) == EOF)
220 /* XXX yuck. the signal handlers need this */
221 static krb5_context context;
223 static krb5_context hctx;
227 int main(int argc, char *argv[])
230 extern int optind, opterr;
232 OM_uint32 OMret, major_status, minor_status;
234 gss_buffer_desc in_buf;
235 auth_gssapi_name names[4];
236 gss_buffer_desc gssbuf;
237 gss_OID nt_krb5_name_oid;
238 kadm5_config_params params;
239 char **db_args = NULL;
240 int db_args_size = 0;
243 int strong_random = 1;
244 const char *pid_file = NULL;
246 kdb_log_context *log_ctx;
248 setlocale(LC_MESSAGES, "");
249 setvbuf(stderr, NULL, _IONBF, 0);
251 /* This is OID value the Krb5_Name NameType */
252 gssbuf.value = "{1 2 840 113554 1 2 2 1}";
253 gssbuf.length = strlen(gssbuf.value);
254 major_status = gss_str_to_oid(&minor_status, &gssbuf, &nt_krb5_name_oid);
255 if (major_status != GSS_S_COMPLETE) {
256 fprintf(stderr, _("Couldn't create KRB5 Name NameType OID\n"));
257 display_status("str_to_oid", major_status, minor_status);
261 names[0].name = names[1].name = names[2].name = names[3].name = NULL;
262 names[0].type = names[1].type = names[2].type = names[3].type =
266 purify_start_batch();
268 whoami = (strrchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);
272 memset(¶ms, 0, sizeof(params));
276 if (strcmp(*argv, "-x") == 0) {
282 char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
285 fprintf(stderr, _("%s: cannot initialize. Not enough "
286 "memory\n"), whoami);
291 db_args[db_args_size-1] = *argv;
292 db_args[db_args_size] = NULL;
293 }else if (strcmp(*argv, "-r") == 0) {
297 params.realm = *argv;
298 params.mask |= KADM5_CONFIG_REALM;
301 } else if (strcmp(*argv, "-m") == 0) {
302 params.mkey_from_kbd = 1;
303 params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
304 } else if (strcmp(*argv, "-nofork") == 0) {
306 #ifdef USE_PASSWORD_SERVER
307 } else if (strcmp(*argv, "-passwordserver") == 0) {
308 kadm5_set_use_password_server ();
310 } else if(strcmp(*argv, "-port") == 0) {
314 params.kadmind_port = atoi(*argv);
315 params.mask |= KADM5_CONFIG_KADMIND_PORT;
316 } else if (strcmp(*argv, "-P") == 0) {
321 } else if (strcmp(*argv, "-W") == 0) {
331 if ((ret = kadm5_init_krb5_context(&context))) {
332 fprintf(stderr, _("%s: %s while initializing context, aborting\n"),
333 whoami, error_message(ret));
337 krb5_klog_init(context, "admin_server", whoami, 1);
339 if((ret = kadm5_init(context, "kadmind", NULL,
341 KADM5_STRUCT_VERSION,
344 &global_server_handle)) != KADM5_OK) {
345 const char *e_txt = krb5_get_error_message (context, ret);
346 krb5_klog_syslog(LOG_ERR, _("%s while initializing, aborting"), e_txt);
347 fprintf(stderr, _("%s: %s while initializing, aborting\n"),
349 krb5_klog_close(context);
353 if ((ret = kadm5_get_config_params(context, 1, ¶ms,
355 const char *e_txt = krb5_get_error_message (context, ret);
356 krb5_klog_syslog(LOG_ERR, _("%s: %s while initializing, aborting"),
358 fprintf(stderr, _("%s: %s while initializing, aborting\n"),
360 kadm5_destroy(global_server_handle);
361 krb5_klog_close(context);
365 #define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_ACL_FILE)
367 if ((params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
368 krb5_klog_syslog(LOG_ERR,
369 _("%s: Missing required configuration values "
370 "(%lx) while initializing, aborting"), whoami,
371 (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
372 fprintf(stderr, _("%s: Missing required configuration values "
373 "(%lx) while initializing, aborting\n"), whoami,
374 (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS);
375 krb5_klog_close(context);
376 kadm5_destroy(global_server_handle);
380 #define server_handle ((kadm5_server_handle_t)global_server_handle)
381 if ((ret = loop_add_udp_port(server_handle->params.kpasswd_port))
382 || (ret = loop_add_tcp_port(server_handle->params.kpasswd_port))
383 || (ret = loop_add_rpc_service(server_handle->params.kadmind_port,
384 KADM, KADMVERS, kadm_1))
385 #ifndef DISABLE_IPROP
386 || (server_handle->params.iprop_enabled
387 ? (ret = loop_add_rpc_service(server_handle->params.iprop_port,
388 KRB5_IPROP_PROG, KRB5_IPROP_VERS,
393 || (ret = loop_setup_network(global_server_handle, whoami, 0))) {
394 const char *e_txt = krb5_get_error_message (context, ret);
395 krb5_klog_syslog(LOG_ERR, _("%s: %s while initializing network, "
396 "aborting"), whoami, e_txt);
397 fprintf(stderr, _("%s: %s while initializing network, aborting\n"),
399 kadm5_destroy(global_server_handle);
400 krb5_klog_close(context);
404 names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
405 names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
406 if (names[0].name == NULL || names[1].name == NULL) {
407 krb5_klog_syslog(LOG_ERR, _("Cannot build GSS-API authentication "
409 fprintf(stderr, _("%s: Cannot build GSS-API authentication names.\n"),
411 kadm5_destroy(global_server_handle);
412 krb5_klog_close(context);
417 * Go through some contortions to point gssapi at a kdb keytab.
418 * This prevents kadmind from needing to use an actual file-based
421 /* XXX extract kadm5's krb5_context */
422 hctx = ((kadm5_server_handle_t)global_server_handle)->context;
423 /* Set ktkdb's internal krb5_context. */
424 ret = krb5_ktkdb_set_context(hctx);
426 krb5_klog_syslog(LOG_ERR,
427 _("Can't set kdb keytab's internal context."));
430 ret = krb5_kt_register(context, &krb5_kt_kdb_ops);
432 krb5_klog_syslog(LOG_ERR, _("Can't register kdb keytab."));
435 /* Tell gssapi about the kdb keytab. */
436 ret = krb5_gss_register_acceptor_identity("KDB:");
438 krb5_klog_syslog(LOG_ERR, _("Can't register acceptor keytab."));
443 krb5_klog_syslog(LOG_ERR, "%s", krb5_get_error_message (context, ret));
444 fprintf(stderr, _("%s: Can't set up keytab for RPC.\n"), whoami);
445 kadm5_destroy(global_server_handle);
446 krb5_klog_close(context);
450 if (svcauth_gssapi_set_names(names, 2) == FALSE) {
451 krb5_klog_syslog(LOG_ERR, _("Cannot set GSS-API authentication names "
452 "(keytab not present?), failing."));
453 fprintf(stderr, _("%s: Cannot set GSS-API authentication names.\n"),
455 svcauth_gssapi_unset_names();
456 kadm5_destroy(global_server_handle);
457 krb5_klog_close(context);
461 /* if set_names succeeded, this will too */
462 in_buf.value = names[1].name;
463 in_buf.length = strlen(names[1].name) + 1;
464 (void) gss_import_name(&OMret, &in_buf, nt_krb5_name_oid,
467 svcauth_gssapi_set_log_badauth_func(log_badauth, NULL);
468 svcauth_gssapi_set_log_badverf_func(log_badverf, NULL);
469 svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL);
471 svcauth_gss_set_log_badauth_func(log_badauth, NULL);
472 svcauth_gss_set_log_badverf_func(log_badverf, NULL);
473 svcauth_gss_set_log_miscerr_func(log_miscerr, NULL);
475 if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE) {
476 fprintf(stderr, _("%s: Cannot initialize RPCSEC_GSS service name.\n"),
481 if ((ret = kadm5int_acl_init(context, 0, params.acl_file))) {
482 errmsg = krb5_get_error_message (context, ret);
483 krb5_klog_syslog(LOG_ERR, _("Cannot initialize acl file: %s"), errmsg);
484 fprintf(stderr, _("%s: Cannot initialize acl file: %s\n"),
486 svcauth_gssapi_unset_names();
487 kadm5_destroy(global_server_handle);
488 krb5_klog_close(context);
492 if (!nofork && (ret = daemon(0, 0))) {
494 errmsg = krb5_get_error_message (context, ret);
495 krb5_klog_syslog(LOG_ERR, _("Cannot detach from tty: %s"), errmsg);
496 fprintf(stderr, _("%s: Cannot detach from tty: %s\n"), whoami, errmsg);
497 svcauth_gssapi_unset_names();
498 kadm5_destroy(global_server_handle);
499 krb5_klog_close(context);
502 if (pid_file != NULL) {
503 ret = write_pid_file(pid_file);
505 errmsg = krb5_get_error_message(context, ret);
506 krb5_klog_syslog(LOG_ERR, _("Cannot create PID file %s: %s"),
508 svcauth_gssapi_unset_names();
509 kadm5_destroy(global_server_handle);
510 krb5_klog_close(context);
515 krb5_klog_syslog(LOG_INFO, _("Seeding random number generator"));
516 ret = krb5_c_random_os_entropy(context, strong_random, NULL);
518 krb5_klog_syslog(LOG_ERR, _("Error getting random seed: %s, aborting"),
519 krb5_get_error_message(context, ret));
520 svcauth_gssapi_unset_names();
521 kadm5_destroy(global_server_handle);
522 krb5_klog_close(context);
526 if (params.iprop_enabled == TRUE)
527 ulog_set_role(hctx, IPROP_MASTER);
529 ulog_set_role(hctx, IPROP_NULL);
531 log_ctx = hctx->kdblog_context;
533 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
535 * IProp is enabled, so let's map in the update log
536 * and setup the service.
538 if ((ret = ulog_map(hctx, params.iprop_logfile,
539 params.iprop_ulogsize, FKADMIND, db_args)) != 0) {
541 _("%s: %s while mapping update log (`%s.ulog')\n"),
542 whoami, error_message(ret), params.dbname);
543 krb5_klog_syslog(LOG_ERR,
544 _("%s while mapping update log (`%s.ulog')"),
545 error_message(ret), params.dbname);
546 krb5_klog_close(context);
553 _("%s: create IPROP svc (PROG=%d, VERS=%d)\n"),
554 whoami, KRB5_IPROP_PROG, KRB5_IPROP_VERS);
557 if (!svc_create(krb5_iprop_prog_1,
558 KRB5_IPROP_PROG, KRB5_IPROP_VERS,
561 _("%s: Cannot create IProp RPC service (PROG=%d, VERS=%d)\n"),
563 KRB5_IPROP_PROG, KRB5_IPROP_VERS);
564 krb5_klog_syslog(LOG_ERR,
565 _("Cannot create IProp RPC service (PROG=%d, VERS=%d), failing."),
566 KRB5_IPROP_PROG, KRB5_IPROP_VERS);
567 krb5_klog_close(context);
572 #if 0 /* authgss only? */
573 if ((ret = kiprop_get_adm_host_srv_name(context,
575 &kiprop_name)) != 0) {
576 krb5_klog_syslog(LOG_ERR,
577 _("%s while getting IProp svc name, failing"),
580 _("%s: %s while getting IProp svc name, failing\n"),
581 whoami, error_message(ret));
582 krb5_klog_close(context);
586 auth_gssapi_name iprop_name;
587 iprop_name.name = build_princ_name(foo, bar);
588 if (iprop_name.name == NULL) {
591 iprop_name.type = nt_krb5_name_oid;
592 if (svcauth_gssapi_set_names(&iprop_name, 1) == FALSE) {
595 if (!rpc_gss_set_svc_name(kiprop_name, "kerberos_v5", 0,
596 KRB5_IPROP_PROG, KRB5_IPROP_VERS)) {
598 (void) rpc_gss_get_error(&err);
600 krb5_klog_syslog(LOG_ERR,
601 _("Unable to set RPCSEC_GSS service name (`%s'), failing."),
602 kiprop_name ? kiprop_name : "<null>");
605 _("%s: Unable to set RPCSEC_GSS service name (`%s'), failing.\n"),
607 kiprop_name ? kiprop_name : "<null>");
611 "%s: set svc name (rpcsec err=%d, sys err=%d)\n",
623 setup_signal_handlers(log_ctx->iproprole);
624 krb5_klog_syslog(LOG_INFO, _("starting"));
626 fprintf(stderr, _("%s: starting...\n"), whoami);
628 loop_listen_and_process(global_server_handle, whoami, reset_db);
629 krb5_klog_syslog(LOG_INFO, _("finished, exiting"));
631 /* Clean up memory, etc */
632 svcauth_gssapi_unset_names();
633 kadm5_destroy(global_server_handle);
634 loop_closedown_network();
635 kadm5int_acl_finish(context, 0);
636 if(gss_changepw_name) {
637 (void) gss_release_name(&OMret, &gss_changepw_name);
639 if(gss_oldchangepw_name) {
640 (void) gss_release_name(&OMret, &gss_oldchangepw_name);
642 for(i = 0 ; i < 4; i++) {
648 krb5_klog_close(context);
649 krb5_free_context(context);
654 * Function: setup_signal_handlers
656 * Purpose: Setup signal handling functions using POSIX's sigaction()
657 * if possible, otherwise with System V's signal().
660 void setup_signal_handlers(iprop_role iproprole) {
662 (void) sigemptyset(&s_action.sa_mask);
663 s_action.sa_handler = request_exit;
664 (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
665 (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
666 (void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
667 s_action.sa_handler = request_hup;
668 (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
669 s_action.sa_handler = SIG_IGN;
670 (void) sigaction(SIGPIPE, &s_action, (struct sigaction *) NULL);
672 s_action.sa_handler = request_pure_report;
673 (void) sigaction(SIGUSR1, &s_action, (struct sigaction *) NULL);
674 s_action.sa_handler = request_pure_clear;
675 (void) sigaction(SIGUSR2, &s_action, (struct sigaction *) NULL);
679 * IProp will fork for a full-resync, we don't want to
680 * wait on it and we don't want the living dead procs either.
682 if (iproprole == IPROP_MASTER) {
683 s_action.sa_handler = SIG_IGN;
684 (void) sigaction(SIGCHLD, &s_action, (struct sigaction *) NULL);
686 #else /* POSIX_SIGNALS */
687 signal(SIGINT, request_exit);
688 signal(SIGTERM, request_exit);
689 signal(SIGQUIT, request_exit);
690 signal(SIGHUP, request_hup);
691 signal(SIGPIPE, SIG_IGN);
693 signal(SIGUSR1, request_pure_report);
694 signal(SIGUSR2, request_pure_clear);
698 * IProp will fork for a full-resync, we don't want to
699 * wait on it and we don't want the living dead procs either.
701 if (iproprole == IPROP_MASTER)
702 (void) signal(SIGCHLD, SIG_IGN);
703 #endif /* POSIX_SIGNALS */
708 * Function: request_pure_report
710 * Purpose: sets flag saying the server got a signal and that it should
711 * dump a purify report when convenient.
717 * sets signal_pure_report to one
720 void request_pure_report(int signum)
722 krb5_klog_syslog(LOG_DEBUG, "Got signal to request a Purify report");
723 signal_pure_report = 1;
728 * Function: request_pure_clear
730 * Purpose: sets flag saying the server got a signal and that it should
731 * dump a purify report when convenient, then clear the
738 * sets signal_pure_report to one
739 * sets signal_pure_clear to one
742 void request_pure_clear(int signum)
744 krb5_klog_syslog(LOG_DEBUG, "Got signal to request a Purify report and clear the old Purify info");
745 signal_pure_report = 1;
746 signal_pure_clear = 1;
752 * Function: request_hup
754 * Purpose: sets flag saying the server got a signal and that it should
755 * reset the database files when convenient.
761 * sets signal_requests_reset to one
764 void request_hup(int signum)
766 signal_requests_reset = 1;
773 * Purpose: flushes the currently opened database files to disk.
779 * Currently, just sets signal_requests_reset to 0. The kdb and adb
780 * libraries used to be sufficiently broken that it was prudent to
781 * close and reopen the databases periodically. They are no longer
782 * that broken, so this function is not necessary.
790 if (ret = kadm5_flush(global_server_handle)) {
791 krb5_klog_syslog(LOG_ERR, "FATAL ERROR! %s while flushing databases. "
792 "Databases may be corrupt! Aborting.",
793 krb5_get_error_message (context, ret));
794 krb5_klog_close(context);
803 * Function: request_exit
805 * Purpose: sets flags saying the server got a signal and that it
806 * should exit when convient.
811 * modifies signal_requests_exit which ideally makes the server exit
815 * signal_requests_exit
818 void request_exit(int signum)
820 krb5_klog_syslog(LOG_DEBUG, _("Got signal to request exit"));
821 signal_requests_exit = 1;
826 * Function: build_princ_name
828 * Purpose: takes a name and a realm and builds a string that can be
829 * consumed by krb5_parse_name.
832 * name (input) name to be part of principal
833 * realm (input) realm part of principal
834 * <return value> char * pointing to "name@realm"
843 char *build_princ_name(char *name, char *realm)
848 if (asprintf(&fullname, "%s@%s", name, realm) < 0)
851 fullname = strdup(name);
857 * Function: log_badverf
859 * Purpose: Call from GSS-API Sun RPC for garbled/forged/replayed/etc
863 * client_name (r) GSS-API client name
864 * server_name (r) GSS-API server name
865 * rqst (r) RPC service request
866 * msg (r) RPC message
867 * data (r) arbitrary data (NULL), not used
871 * Logs the invalid request via krb5_klog_syslog(); see functional spec for
874 void log_badverf(gss_name_t client_name, gss_name_t server_name,
875 struct svc_req *rqst, struct rpc_msg *msg, char
880 const char *proc_name;
882 static const struct procnames proc_names[] = {
883 {1, "CREATE_PRINCIPAL"},
884 {2, "DELETE_PRINCIPAL"},
885 {3, "MODIFY_PRINCIPAL"},
886 {4, "RENAME_PRINCIPAL"},
887 {5, "GET_PRINCIPAL"},
888 {6, "CHPASS_PRINCIPAL"},
889 {7, "CHRAND_PRINCIPAL"},
890 {8, "CREATE_POLICY"},
891 {9, "DELETE_POLICY"},
892 {10, "MODIFY_POLICY"},
898 {16, "SETKEY_PRINCIPAL"},
899 {17, "SETV4KEY_PRINCIPAL"},
900 {18, "CREATE_PRINCIPAL3"},
901 {19, "CHPASS_PRINCIPAL3"},
902 {20, "CHRAND_PRINCIPAL3"},
903 {21, "SETKEY_PRINCIPAL3"},
906 #define NPROCNAMES (sizeof (proc_names) / sizeof (struct procnames))
908 gss_buffer_desc client, server;
913 const char *procname;
922 (void) gss_display_name(&minor, client_name, &client, &gss_type);
923 (void) gss_display_name(&minor, server_name, &server, &gss_type);
924 if (client.value == NULL) {
925 client.value = "(null)";
926 clen = sizeof("(null)") -1;
928 clen = client.length;
930 trunc_name(&clen, &cdots);
931 if (server.value == NULL) {
932 server.value = "(null)";
933 slen = sizeof("(null)") - 1;
935 slen = server.length;
937 trunc_name(&slen, &sdots);
938 a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
940 proc = msg->rm_call.cb_proc;
942 for (i = 0; i < NPROCNAMES; i++) {
943 if (proc_names[i].proc == proc) {
944 procname = proc_names[i].proc_name;
948 if (procname != NULL)
949 krb5_klog_syslog(LOG_NOTICE,
950 _("WARNING! Forged/garbled request: %s, claimed "
951 "client = %.*s%s, server = %.*s%s, addr = %s"),
952 procname, (int) clen, (char *) client.value, cdots,
953 (int) slen, (char *) server.value, sdots, a);
955 krb5_klog_syslog(LOG_NOTICE,
956 _("WARNING! Forged/garbled request: %d, claimed "
957 "client = %.*s%s, server = %.*s%s, addr = %s"),
958 proc, (int) clen, (char *) client.value, cdots,
959 (int) slen, (char *) server.value, sdots, a);
961 (void) gss_release_buffer(&minor, &client);
962 (void) gss_release_buffer(&minor, &server);
966 * Function: log_miscerr
968 * Purpose: Callback from GSS-API Sun RPC for miscellaneous errors
971 * rqst (r) RPC service request
972 * msg (r) RPC message
973 * error (r) error message from RPC
974 * data (r) arbitrary data (NULL), not used
978 * Logs the error via krb5_klog_syslog(); see functional spec for
981 void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
982 char *error, char *data)
986 a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
987 krb5_klog_syslog(LOG_NOTICE, _("Miscellaneous RPC error: %s, %s"), a,
994 * Function: log_badauth
996 * Purpose: Callback from GSS-API Sun RPC for authentication
1000 * major (r) GSS-API major status
1001 * minor (r) GSS-API minor status
1002 * addr (r) originating address
1003 * data (r) arbitrary data (NULL), not used
1007 * Logs the GSS-API error via krb5_klog_syslog(); see functional spec for
1010 void log_badauth(OM_uint32 major, OM_uint32 minor,
1011 struct sockaddr_in *addr, char *data)
1015 /* Authentication attempt failed: <IP address>, <GSS-API error */
1018 a = inet_ntoa(addr->sin_addr);
1020 krb5_klog_syslog(LOG_NOTICE, _("Authentication attempt failed: %s, "
1021 "GSS-API error strings are:"), a);
1022 log_badauth_display_status(" ", major, minor);
1023 krb5_klog_syslog(LOG_NOTICE, _(" GSS-API error strings complete."));
1026 void log_badauth_display_status(char *msg, OM_uint32 major, OM_uint32 minor)
1028 log_badauth_display_status_1(msg, major, GSS_C_GSS_CODE, 0);
1029 log_badauth_display_status_1(msg, minor, GSS_C_MECH_CODE, 0);
1032 void log_badauth_display_status_1(char *m, OM_uint32 code, int type,
1035 OM_uint32 gssstat, minor_stat;
1036 gss_buffer_desc msg;
1041 gssstat = gss_display_status(&minor_stat, code,
1042 type, GSS_C_NULL_OID,
1044 if (gssstat != GSS_S_COMPLETE) {
1046 log_badauth_display_status_1(m,gssstat,GSS_C_GSS_CODE,1);
1047 log_badauth_display_status_1(m, minor_stat,
1048 GSS_C_MECH_CODE, 1);
1050 krb5_klog_syslog(LOG_ERR,
1051 _("GSS-API authentication error %.*s: "
1052 "recursive failure!"), (int) msg.length,
1053 (char *) msg.value);
1057 krb5_klog_syslog(LOG_NOTICE, "%s %.*s", m, (int)msg.length,
1059 (void) gss_release_buffer(&minor_stat, &msg);