350
memset(&addr, 0, sizeof(addr));
351
addr.sin_family = AF_INET;
352
addr.sin_addr.s_addr = INADDR_ANY;
353
addr.sin_port = htons(params.kadmind_port);
355
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
352
if ((ret = setup_network(global_server_handle, whoami))) {
356
353
const char *e_txt = krb5_get_error_message (context, ret);
357
krb5_klog_syslog(LOG_ERR, "Cannot create TCP socket: %s",
359
fprintf(stderr, "Cannot create TCP socket: %s",
361
kadm5_destroy(global_server_handle);
362
krb5_klog_close(context);
366
if ((schpw = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
367
const char *e_txt = krb5_get_error_message (context, ret);
368
krb5_klog_syslog(LOG_ERR,
369
"cannot create simple chpw socket: %s",
371
fprintf(stderr, "Cannot create simple chpw socket: %s",
373
kadm5_destroy(global_server_handle);
374
krb5_klog_close(context);
379
/* the old admin server turned on SO_REUSEADDR for non-default
380
port numbers. this was necessary, on solaris, for the tests
381
to work. jhawk argues that the debug and production modes
382
should be the same. I think I agree, so I'm always going to set
383
SO_REUSEADDR. The other option is to have the unit tests wait
384
until the port is useable, or use a different port each time.
395
sizeof(allowed)) < 0) {
396
const char *e_txt = krb5_get_error_message (context, ret);
397
krb5_klog_syslog(LOG_ERR, "Cannot set SO_REUSEADDR: %s",
399
fprintf(stderr, "Cannot set SO_REUSEADDR: %s", e_txt);
400
kadm5_destroy(global_server_handle);
401
krb5_klog_close(context);
404
if (setsockopt(schpw, SOL_SOCKET, SO_REUSEADDR,
405
(char *) &allowed, sizeof(allowed)) < 0) {
406
const char *e_txt = krb5_get_error_message (context, ret);
407
krb5_klog_syslog(LOG_ERR, "main",
408
"cannot set SO_REUSEADDR on simple chpw socket: %s",
411
"Cannot set SO_REUSEADDR on simple chpw socket: %s",
413
kadm5_destroy(global_server_handle);
414
krb5_klog_close(context);
418
#endif /* SO_REUSEADDR */
419
memset(&addr, 0, sizeof(addr));
420
addr.sin_family = AF_INET;
421
addr.sin_addr.s_addr = INADDR_ANY;
422
addr.sin_port = htons(params.kadmind_port);
424
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
426
const char *e_txt = krb5_get_error_message (context, errno);
427
fprintf(stderr, "%s: Cannot bind socket.\n", whoami);
428
fprintf(stderr, "bind: %s\n", e_txt);
430
krb5_klog_syslog(LOG_ERR, "Cannot bind socket: %s", e_txt);
431
if(oerrno == EADDRINUSE) {
432
char *w = strrchr(whoami, '/');
440
"This probably means that another %s process is already\n"
441
"running, or that another program is using the server port (number %d)\n"
442
"after being assigned it by the RPC portmap daemon. If another\n"
443
"%s is already running, you should kill it before\n"
444
"restarting the server. If, on the other hand, another program is\n"
445
"using the server port, you should kill it before running\n"
446
"%s, and ensure that the conflict does not occur in the\n"
447
"future by making sure that %s is started on reboot\n"
448
"before portmap.\n", w, ntohs(addr.sin_port), w, w, w);
449
krb5_klog_syslog(LOG_ERR, "Check for already-running %s or for "
450
"another process using port %d", w,
451
htons(addr.sin_port));
354
krb5_klog_syslog(LOG_ERR, "%s: %s while initializing network, aborting",
356
fprintf(stderr, "%s: %s while initializing network, aborting\n",
453
358
kadm5_destroy(global_server_handle);
454
359
krb5_klog_close(context);
457
memset(&addr, 0, sizeof(addr));
458
addr.sin_family = AF_INET;
459
addr.sin_addr.s_addr = INADDR_ANY;
461
addr.sin_port = htons(params.kpasswd_port);
463
if (bind(schpw, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
466
const char *e_txt = krb5_get_error_message (context, errno);
467
fprintf(stderr, "%s: Cannot bind socket.\n", whoami);
468
fprintf(stderr, "bind: %s\n", e_txt);
470
sprintf(portbuf, "%d", ntohs(addr.sin_port));
471
krb5_klog_syslog(LOG_ERR, "cannot bind simple chpw socket: %s",
473
if(oerrno == EADDRINUSE) {
474
char *w = strrchr(whoami, '/');
482
"This probably means that another %s process is already\n"
483
"running, or that another program is using the server port (number %d).\n"
484
"If another %s is already running, you should kill it before\n"
485
"restarting the server.\n",
486
w, ntohs(addr.sin_port), w);
488
kadm5_destroy(global_server_handle);
489
krb5_klog_close(context);
493
transp = svctcp_create(s, 0, 0);
495
fprintf(stderr, "%s: Cannot create RPC service.\n", whoami);
496
krb5_klog_syslog(LOG_ERR, "Cannot create RPC service: %m");
497
kadm5_destroy(global_server_handle);
498
krb5_klog_close(context);
501
if(!svc_register(transp, KADM, KADMVERS, kadm_1, 0)) {
502
fprintf(stderr, "%s: Cannot register RPC service.\n", whoami);
503
krb5_klog_syslog(LOG_ERR, "Cannot register RPC service, failing.");
504
kadm5_destroy(global_server_handle);
505
krb5_klog_close(context);
509
363
names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
510
364
names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
644
setup_signal_handlers();
645
krb5_klog_syslog(LOG_INFO, "starting");
646
kadm_svc_run(¶ms);
503
if (params.iprop_enabled == TRUE)
504
ulog_set_role(hctx, IPROP_MASTER);
506
ulog_set_role(hctx, IPROP_NULL);
508
log_ctx = hctx->kdblog_context;
510
if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
512
* IProp is enabled, so let's map in the update log
513
* and setup the service.
515
if ((ret = ulog_map(hctx, params.iprop_logfile,
516
params.iprop_ulogsize, FKADMIND, db_args)) != 0) {
518
_("%s: %s while mapping update log (`%s.ulog')\n"),
519
whoami, error_message(ret), params.dbname);
520
krb5_klog_syslog(LOG_ERR,
521
_("%s while mapping update log (`%s.ulog')"),
522
error_message(ret), params.dbname);
523
krb5_klog_close(context);
530
"%s: create IPROP svc (PROG=%d, VERS=%d)\n",
531
whoami, KRB5_IPROP_PROG, KRB5_IPROP_VERS);
534
if (!svc_create(krb5_iprop_prog_1,
535
KRB5_IPROP_PROG, KRB5_IPROP_VERS,
538
_("%s: Cannot create IProp RPC service (PROG=%d, VERS=%d)\n"),
540
KRB5_IPROP_PROG, KRB5_IPROP_VERS);
541
krb5_klog_syslog(LOG_ERR,
542
_("Cannot create IProp RPC service (PROG=%d, VERS=%d), failing."),
543
KRB5_IPROP_PROG, KRB5_IPROP_VERS);
544
krb5_klog_close(context);
549
#if 0 /* authgss only? */
550
if ((ret = kiprop_get_adm_host_srv_name(context,
552
&kiprop_name)) != 0) {
553
krb5_klog_syslog(LOG_ERR,
554
_("%s while getting IProp svc name, failing"),
557
_("%s: %s while getting IProp svc name, failing\n"),
558
whoami, error_message(ret));
559
krb5_klog_close(context);
563
auth_gssapi_name iprop_name;
564
iprop_name.name = build_princ_name(foo, bar);
565
if (iprop_name.name == NULL) {
568
iprop_name.type = nt_krb5_name_oid;
569
if (svcauth_gssapi_set_names(&iprop_name, 1) == FALSE) {
572
if (!rpc_gss_set_svc_name(kiprop_name, "kerberos_v5", 0,
573
KRB5_IPROP_PROG, KRB5_IPROP_VERS)) {
575
(void) rpc_gss_get_error(&err);
577
krb5_klog_syslog(LOG_ERR,
578
_("Unable to set RPCSEC_GSS service name (`%s'), failing."),
579
kiprop_name ? kiprop_name : "<null>");
582
_("%s: Unable to set RPCSEC_GSS service name (`%s'), failing.\n"),
584
kiprop_name ? kiprop_name : "<null>");
588
"%s: set svc name (rpcsec err=%d, sys err=%d)\n",
600
setup_signal_handlers(log_ctx->iproprole);
601
krb5_klog_syslog(LOG_INFO, _("starting"));
603
fprintf(stderr, "%s: starting...\n", whoami);
605
listen_and_process(global_server_handle, whoami);
647
606
krb5_klog_syslog(LOG_INFO, "finished, exiting");
649
608
/* Clean up memory, etc */
650
609
svcauth_gssapi_unset_names();
651
610
kadm5_destroy(global_server_handle);
611
closedown_network(global_server_handle, whoami);
653
612
kadm5int_acl_finish(context, 0);
654
613
if(gss_changepw_name) {
655
614
(void) gss_release_name(&OMret, &gss_changepw_name);
702
670
signal(SIGUSR1, request_pure_report);
703
671
signal(SIGUSR2, request_pure_clear);
704
672
#endif /* PURIFY */
675
* IProp will fork for a full-resync, we don't want to
676
* wait on it and we don't want the living dead procs either.
678
if (iproprole == IPROP_MASTER)
679
(void) signal(SIGCHLD, SIG_IGN);
705
680
#endif /* POSIX_SIGNALS */
709
* Function: kadm_svc_run
711
* Purpose: modified version of sunrpc svc_run.
712
* which closes the database every TIMEOUT seconds.
720
void kadm_svc_run(params)
721
kadm5_config_params *params;
724
struct timeval timeout;
726
while(signal_request_exit == 0) {
727
if (signal_request_hup) {
729
krb5_klog_reopen(context);
730
signal_request_hup = 0;
733
if (signal_pure_report) /* check to see if a report */
734
/* should be dumped... */
736
purify_new_reports();
737
signal_pure_report = 0;
739
if (signal_pure_clear) /* ...before checking whether */
740
/* the info should be cleared. */
742
purify_clear_new_reports();
743
signal_pure_clear = 0;
746
timeout.tv_sec = TIMEOUT;
750
#define max(a, b) (((a) > (b)) ? (a) : (b))
751
switch(select(max(schpw, svc_maxfd) + 1,
752
(fd_set *) &rfd, NULL, NULL, &timeout)) {
762
if (FD_ISSET(schpw, &rfd))
763
do_schpw(schpw, params);
772
685
* Function: request_pure_report
1029
940
if (procname != NULL)
1030
941
krb5_klog_syslog(LOG_NOTICE, "WARNING! Forged/garbled request: %s, "
1031
942
"claimed client = %.*s%s, server = %.*s%s, addr = %s",
1032
procname, clen, client.value, cdots,
1033
slen, server.value, sdots, a);
943
procname, (int) clen, (char *) client.value, cdots,
944
(int) slen, (char *) server.value, sdots, a);
1035
946
krb5_klog_syslog(LOG_NOTICE, "WARNING! Forged/garbled request: %d, "
1036
947
"claimed client = %.*s%s, server = %.*s%s, addr = %s",
1037
proc, clen, client.value, cdots,
1038
slen, server.value, sdots, a);
948
proc, (int) clen, (char *) client.value, cdots,
949
(int) slen, (char *) server.value, sdots, a);
1040
951
(void) gss_release_buffer(&minor, &client);
1041
952
(void) gss_release_buffer(&minor, &server);
1141
void do_schpw(int s1, kadm5_config_params *params)
1143
krb5_error_code ret;
1144
/* XXX buffer = ethernet mtu */
1147
struct sockaddr_in from;
1150
krb5_data reqdata, repdata;
1153
fromlen = sizeof(from);
1154
if ((len = recvfrom(s1, req, sizeof(req), 0, (struct sockaddr *)&from,
1156
krb5_klog_syslog(LOG_ERR, "chpw: Couldn't receive request: %s",
1157
krb5_get_error_message (context, errno));
1161
if ((ret = krb5_kt_resolve(context, "KDB:", &kt))) {
1162
krb5_klog_syslog(LOG_ERR, "chpw: Couldn't open admin keytab %s",
1163
krb5_get_error_message (context, ret));
1167
reqdata.length = len;
1170
/* this is really obscure. s1 is used for all communications. it
1171
is left unconnected in case the server is multihomed and routes
1172
are asymmetric. s2 is connected to resolve routes and get
1173
addresses. this is the *only* way to get proper addresses for
1174
multihomed hosts if routing is asymmetric.
1176
A related problem in the server, but not the client, is that
1177
many os's have no way to disconnect a connected udp socket, so
1178
the s2 socket needs to be closed and recreated for each
1179
request. The s1 socket must not be closed, or else queued
1180
requests will be lost.
1182
A "naive" client implementation (one socket, no connect,
1183
hostname resolution to get the local ip addr) will work and
1184
interoperate if the client is single-homed. */
1186
if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
1187
const char *errmsg = krb5_get_error_message (context, errno);
1188
krb5_klog_syslog(LOG_ERR, "cannot create connecting socket: %s",
1190
fprintf(stderr, "Cannot create connecting socket: %s",
1192
svcauth_gssapi_unset_names();
1193
kadm5_destroy(global_server_handle);
1194
krb5_klog_close(context);
1198
if (connect(s2, (struct sockaddr *) &from, sizeof(from)) < 0) {
1199
krb5_klog_syslog(LOG_ERR, "chpw: Couldn't connect to client: %s",
1200
krb5_get_error_message (context, errno));
1204
if ((ret = process_chpw_request(context, global_server_handle,
1205
params->realm, s2, kt, &from,
1206
&reqdata, &repdata))) {
1207
krb5_klog_syslog(LOG_ERR, "chpw: Error processing request: %s",
1208
krb5_get_error_message (context, ret));
1213
if (repdata.length == 0) {
1214
/* just return. This means something really bad happened */
1218
len = sendto(s1, repdata.data, (int) repdata.length, 0,
1219
(struct sockaddr *) &from, sizeof(from));
1221
if (len < (int) repdata.length) {
1222
krb5_xfree(repdata.data);
1224
krb5_klog_syslog(LOG_ERR, "chpw: Error sending reply: %s",
1225
krb5_get_error_message (context, errno));
1229
krb5_xfree(repdata.data);
1232
krb5_kt_close(context, kt);