1 /* shishid.c Shishi Key Distribution Center daemon.
2 * Copyright (C) 2002, 2003 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 #if defined HAVE_DECL_H_ERRNO && !HAVE_DECL_H_ERRNO
42 /* extern int h_errno; */
49 #ifdef HAVE_SYS_TYPES_H
50 #include <sys/types.h>
53 #ifdef HAVE_SYS_SELECT_H
54 #include <sys/select.h>
57 #ifdef HAVE_SYS_SOCKET_H
58 #include <sys/socket.h>
61 #ifdef HAVE_SYS_IOCTL_H
62 #include <sys/ioctl.h>
70 # include <inttypes.h>
77 #if TIME_WITH_SYS_TIME
78 # include <sys/time.h>
82 # include <sys/time.h>
89 # if !STDC_HEADERS && HAVE_MEMORY_H
102 #ifdef HAVE_NETINET_IN_H
103 #include <netinet/in.h>
105 #ifdef HAVE_NETINET_IN6_H
106 #include <netinet/in6.h>
109 #ifdef HAVE_ARPA_INET_H
110 #include <arpa/inet.h>
120 #define FAMILY_IPV4 "IPv4"
121 #define FAMILY_IPV6 "IPv6"
124 #define LISTEN_DEFAULT FAMILY_IPV4 ":*:kerberos/udp, " \
125 FAMILY_IPV4 ":*:kerberos/tcp, " \
126 FAMILY_IPV6 ":*:kerberos/udp, " \
127 FAMILY_IPV6 ":*:kerberos/tcp"
129 #define LISTEN_DEFAULT "*:kerberos/udp, *:kerberos/tcp"
132 const char *program_name
= PACKAGE
;
138 struct sockaddr addr
;
152 struct listenspec
*listenspec
;
157 const char *argp_program_version
= PACKAGE_STRING
;
158 const char *argp_program_bug_address
= PACKAGE_BUGREPORT
;
161 parse_opt (int key
, char *arg
, struct argp_state
*state
)
163 struct arguments
*arguments
= state
->input
;
172 arguments
->silent
= 1;
176 arguments
->verbose
= 1;
180 arguments
->cfgfile
= strdup (arg
);
184 arguments
->keyfile
= strdup (arg
);
188 arguments
->setuid
= strdup (arg
);
192 if (arguments
->nlistenspec
> 0)
194 arg
= strdup (LISTEN_DEFAULT
);
198 for (i
= 0; (val
= strtok_r (i
== 0 ? arg
: NULL
, ", \t", &ptrptr
));
201 char *service
, *proto
;
204 struct listenspec
*ls
;
205 struct sockaddr_in
*sin
;
207 struct sockaddr_in6
*sin6
;
210 arguments
->nlistenspec
++;
211 arguments
->listenspec
= realloc (arguments
->listenspec
,
212 sizeof (*arguments
->listenspec
) *
213 arguments
->nlistenspec
);
214 if (arguments
->listenspec
== NULL
)
215 argp_error (state
, "Fatal memory allocation error");
216 ls
= &arguments
->listenspec
[arguments
->nlistenspec
- 1];
217 ls
->str
= strdup (val
);
219 sin
= (struct sockaddr_in
*) &ls
->addr
;
221 sin6
= (struct sockaddr_in6
*) &ls
->addr
;
224 proto
= strrchr (val
, '/');
226 argp_error (state
, "Could not find type in listen spec: `%s'",
231 if (strcmp (proto
, "tcp") == 0)
232 ls
->type
= SOCK_STREAM
;
234 ls
->type
= SOCK_DGRAM
;
236 service
= strrchr (val
, ':');
238 argp_error (state
, "Could not find service in listen spec: `%s'",
243 se
= getservbyname (service
, proto
);
245 ls
->port
= ntohs (se
->s_port
);
246 else if (strcmp (service
, "kerberos") == 0)
248 else if (atoi (service
) != 0)
249 ls
->port
= atoi (service
);
251 argp_error (state
, "Unknown service `%s' in listen spec: `%s'",
255 if (ls
->family
== AF_INET6
)
256 sin6
->sin6_port
= htons (ls
->port
);
259 sin
->sin_port
= htons (ls
->port
);
261 if (strncmp (val
, FAMILY_IPV4
":", strlen (FAMILY_IPV4
":")) == 0)
263 ls
->family
= AF_INET
;
264 val
+= strlen (FAMILY_IPV4
":");
267 else if (strncmp (val
, FAMILY_IPV6
":", strlen (FAMILY_IPV6
":")) ==
270 ls
->family
= AF_INET6
;
271 val
+= strlen (FAMILY_IPV6
":");
275 ls
->family
= AF_INET
;
277 if (strcmp (val
, "*") == 0)
280 if (ls
->family
== AF_INET6
)
281 sin6
->sin6_addr
= in6addr_any
;
284 sin
->sin_addr
.s_addr
= htonl (INADDR_ANY
);
286 else if ((he
= gethostbyname (val
)))
288 if (he
->h_addrtype
== AF_INET
)
290 sin
->sin_family
= AF_INET
;
291 memcpy (&sin
->sin_addr
, he
->h_addr_list
[0], he
->h_length
);
294 else if (he
->h_addrtype
== AF_INET6
)
296 sin6
->sin6_family
= AF_INET6
;
297 memcpy (&sin6
->sin6_addr
, he
->h_addr_list
[0], he
->h_length
);
301 argp_error (state
, "Unknown protocol family (%d) returned "
302 "by gethostbyname(\"%s\"): `%s'", he
->h_addrtype
,
306 argp_error (state
, "Unknown host `%s' in listen spec: `%s'",
313 argp_error (state
, "Too many arguments: `%s'", arg
);
317 return ARGP_ERR_UNKNOWN
;
323 static struct argp_option options
[] = {
325 {"verbose", 'v', 0, 0,
326 "Produce verbose output.", 0},
329 "Don't produce any output.", 0},
331 {"silent", 's', 0, OPTION_ALIAS
,
334 {"configuration-file", 'c', "FILE", 0,
335 "Read configuration from file. Default is " SYSTEMCFGFILE
".", 0},
337 {"listen", 'l', "[FAMILY:]ADDRESS:SERVICE/TYPE,...", 0,
338 "What to listen on. Family is \"IPv4\" or \"IPv6\", if absent the "
339 "family is decided by gethostbyname(ADDRESS). An address of \"*\" "
340 "indicates all addresses on the local host. "
341 "The default is \"" LISTEN_DEFAULT
"\".", 0},
343 {"key-file", 'k', "FILE", 0,
344 "Read keys from file. Default is " KDCKEYFILE
".", 0},
346 {"setuid", 'u', "NAME", 0,
347 "After binding socket, set user identity.", 0},
353 static struct argp argp
= {
357 "Shishid -- Key Distribution Center network daemon",
363 static char *fatal_krberror
;
364 static size_t fatal_krberror_len
;
367 setup_fatal_krberror (Shishi
* handle
)
372 krberr
= shishi_krberror (handle
);
374 return SHISHI_MALLOC_ERROR
;
376 rc
= shishi_krberror_set_etext (handle
, krberr
,
377 "Internal KDC error, contact administrator");
381 rc
= shishi_krberror_der (handle
, krberr
, &fatal_krberror
,
382 &fatal_krberror_len
);
390 asreq1 (Shishi
* handle
, struct arguments
*arg
, Shishi_as
* as
)
393 Shishi_key
*sessionkey
, *userkey
;
398 char *username
, *servername
, *realm
;
400 tkt
= shishi_as_tkt (as
);
402 return SHISHI_MALLOC_ERROR
;
407 err
= shishi_kdcreq_etype (handle
, shishi_as_req (as
), &etype
, i
);
408 if (err
== SHISHI_OK
&& shishi_cipher_supported_p (etype
))
411 while (err
== SHISHI_OK
);
412 if (err
!= SHISHI_OK
)
415 /* XXX use a "preferred server kdc etype" from shishi instead? */
417 err
= shishi_key_random (handle
, etype
, &sessionkey
);
421 err
= shishi_tkt_key_set (tkt
, sessionkey
);
425 buflen
= sizeof (buf
) - 1;
426 err
= shishi_kdcreq_cname_get (handle
, shishi_as_req (as
), buf
, &buflen
);
427 if (err
!= SHISHI_OK
)
430 username
= strdup (buf
);
431 printf ("username %s\n", username
);
433 buflen
= sizeof (buf
) - 1;
434 err
= shishi_kdcreq_sname_get (handle
, shishi_as_req (as
), buf
, &buflen
);
435 if (err
!= SHISHI_OK
)
438 servername
= strdup (buf
);
439 printf ("servername %s\n", servername
);
441 buflen
= sizeof (buf
) - 1;
442 err
= shishi_kdcreq_realm_get (handle
, shishi_as_req (as
), buf
, &buflen
);
443 if (err
!= SHISHI_OK
)
446 realm
= strdup (buf
);
447 printf ("client & server realm %s\n", realm
);
449 err
= shishi_tkt_clientrealm_set (tkt
, realm
, username
);
453 err
= shishi_tkt_serverrealm_set (tkt
, realm
, servername
);
457 userkey
= shishi_keys_for_serverrealm_in_file (handle
,
463 err
= shishi_tkt_build (tkt
, arg
->tgskey
);
467 err
= shishi_as_rep_build (as
, userkey
);
473 shishi_kdcreq_print (handle
, stderr
, shishi_as_req (as
));
474 shishi_encticketpart_print (handle
, stderr
,
475 shishi_tkt_encticketpart (tkt
));
476 shishi_ticket_print (handle
, stderr
, shishi_tkt_ticket (tkt
));
477 shishi_enckdcreppart_print (handle
, stderr
,
478 shishi_tkt_enckdcreppart (tkt
));
479 shishi_kdcrep_print (handle
, stderr
, shishi_as_rep (as
));
486 asreq (Shishi
* handle
, struct arguments
*arg
,
487 Shishi_asn1 kdcreq
, char **out
, size_t *outlen
)
492 rc
= shishi_as (handle
, &as
);
495 syslog (LOG_ERR
, "Incoming request failed: Cannot create AS: %s\n",
496 shishi_strerror (rc
));
497 /* XXX hard coded KRB-ERROR? */
498 *out
= strdup ("foo");
499 *outlen
= strlen (*out
);
503 shishi_as_req_set (as
, kdcreq
);
505 rc
= asreq1 (handle
, arg
, as
);
508 syslog (LOG_NOTICE
, "Could not answer request: %s: %s\n",
509 shishi_strerror (rc
),
510 shishi_krberror_message (handle
, shishi_as_krberror (as
)));
511 rc
= shishi_as_krberror_der (as
, out
, outlen
);
514 rc
= shishi_as_rep_der (as
, out
, outlen
);
518 "Incoming request failed: Cannot DER encode reply: %s\n",
519 shishi_strerror (rc
));
520 /* XXX hard coded KRB-ERROR? */
521 *out
= strdup ("aaaaaa");
522 *outlen
= strlen (*out
);
529 tgsreq1 (Shishi
* handle
, struct arguments
*arg
, Shishi_tgs
* tgs
)
533 Shishi_key
*sessionkey
, *sessiontktkey
, *serverkey
, *subkey
, *keytouse
;
537 char *username
, *servername
, *realm
;
541 tkt
= shishi_tgs_tkt (tgs
);
543 return SHISHI_MALLOC_ERROR
;
548 err
= shishi_kdcreq_etype (handle
, shishi_tgs_req (tgs
), &etype
, i
);
549 if (err
== SHISHI_OK
&& shishi_cipher_supported_p (etype
))
552 while (err
== SHISHI_OK
);
553 if (err
!= SHISHI_OK
)
556 /* XXX use a "preferred server kdc etype" from shishi instead? */
558 err
= shishi_key_random (handle
, etype
, &sessionkey
);
562 err
= shishi_tkt_key_set (tkt
, sessionkey
);
566 /* extract pa-data and populate tgs->ap */
567 rc
= shishi_tgs_req_process (tgs
);
571 /* XXX check if ticket is for our tgt key */
573 /* decrypt ticket with our key, and decrypt authenticator using key in tkt */
574 rc
= shishi_ap_req_process_keyusage
575 (shishi_tgs_ap (tgs
), arg
->tgskey
,
576 SHISHI_KEYUSAGE_TGSREQ_APREQ_AUTHENTICATOR
);
580 /* XXX check that checksum in authenticator match tgsreq.req-body */
582 buflen
= sizeof (buf
) - 1;
583 err
= shishi_encticketpart_cname_get
584 (handle
, shishi_tkt_encticketpart (shishi_ap_tkt (shishi_tgs_ap (tgs
))),
586 if (err
!= SHISHI_OK
)
589 username
= strdup (buf
);
590 printf ("username %s\n", username
);
592 buflen
= sizeof (buf
) - 1;
593 err
= shishi_kdcreq_sname_get (handle
, shishi_tgs_req (tgs
), buf
, &buflen
);
594 if (err
!= SHISHI_OK
)
597 servername
= strdup (buf
);
598 printf ("servername %s\n", servername
);
600 buflen
= sizeof (buf
) - 1;
601 err
= shishi_kdcreq_realm_get (handle
, shishi_tgs_req (tgs
), buf
, &buflen
);
602 if (err
!= SHISHI_OK
)
605 realm
= strdup (buf
);
606 printf ("server realm %s\n", realm
);
608 err
= shishi_tkt_clientrealm_set (tkt
, realm
, username
);
612 err
= shishi_tkt_serverrealm_set (tkt
, realm
, servername
);
616 serverkey
= shishi_keys_for_serverrealm_in_file (handle
,
622 err
= shishi_tkt_build (tkt
, serverkey
);
626 err
= shishi_encticketpart_get_key
628 shishi_tkt_encticketpart (shishi_ap_tkt (shishi_tgs_ap (tgs
))),
631 err
= shishi_authenticator_get_subkey
632 (handle
, shishi_ap_authenticator (shishi_tgs_ap (tgs
)), &subkey
);
633 if (err
!= SHISHI_OK
&& err
!= SHISHI_ASN1_NO_ELEMENT
)
636 if (err
== SHISHI_OK
)
639 keytouse
= sessiontktkey
;
641 err
= shishi_tgs_rep_build (tgs
, keytouse
);
647 puts ("KDC-REQ in:");
648 shishi_kdcreq_print (handle
, stderr
, shishi_tgs_req (tgs
));
649 puts ("AP-REQ in KDC-REQ:");
650 shishi_apreq_print (handle
, stderr
,
651 shishi_ap_req (shishi_tgs_ap (tgs
)));
652 puts ("Authenticator in AP-REQ in KDC-REQ:");
653 shishi_authenticator_print (handle
, stderr
, shishi_ap_authenticator
654 (shishi_tgs_ap (tgs
)));
655 puts ("Ticket in AP-REQ:");
656 shishi_ticket_print (handle
, stdout
,
658 (shishi_ap_tkt (shishi_tgs_ap (tgs
))));
659 puts ("EncTicketPart in AP-REQ:");
660 shishi_encticketpart_print (handle
, stdout
,
661 shishi_tkt_encticketpart
662 (shishi_ap_tkt (shishi_tgs_ap (tgs
))));
663 puts ("Ticket in TGS-REP:");
664 shishi_ticket_print (handle
, stdout
, shishi_tkt_ticket (tkt
));
665 puts ("EncTicketPart in TGS-REP:");
666 shishi_encticketpart_print (handle
, stderr
,
667 shishi_tkt_encticketpart (tkt
));
668 puts ("EncKDCRepPart in TGS-REP:");
669 shishi_enckdcreppart_print (handle
, stderr
,
670 shishi_tkt_enckdcreppart (tkt
));
672 shishi_kdcrep_print (handle
, stderr
, shishi_tgs_rep (tgs
));
679 tgsreq (Shishi
* handle
, struct arguments
*arg
,
680 Shishi_asn1 kdcreq
, char **out
, size_t *outlen
)
685 rc
= shishi_tgs (handle
, &tgs
);
688 syslog (LOG_ERR
, "Incoming request failed: Cannot create TGS: %s\n",
689 shishi_strerror (rc
));
690 /* XXX hard coded KRB-ERROR? */
691 *out
= strdup ("foo");
692 *outlen
= strlen (*out
);
696 shishi_tgs_req_set (tgs
, kdcreq
);
698 rc
= tgsreq1 (handle
, arg
, tgs
);
701 syslog (LOG_NOTICE
, "Could not answer request: %s: %s\n",
702 shishi_strerror (rc
),
703 shishi_krberror_message (handle
, shishi_tgs_krberror (tgs
)));
704 rc
= shishi_tgs_krberror_der (tgs
, out
, outlen
);
707 rc
= shishi_tgs_rep_der (tgs
, out
, outlen
);
711 "Incoming request failed: Cannot DER encode reply: %s\n",
712 shishi_strerror (rc
));
713 /* XXX hard coded KRB-ERROR? */
714 *out
= strdup ("aaaaaa");
715 *outlen
= strlen (*out
);
722 static Shishi_msgtype
723 get_msgtype (Shishi
* handle
, char *in
, size_t inlen
)
725 if (inlen
> 1 && *in
>= 0x60 && (unsigned char) *in
<= 0x7F)
732 process_1 (Shishi
* handle
, struct arguments
*arg
,
733 char *in
, size_t inlen
, char **out
, size_t * outlen
)
736 Shishi_msgtype msgtype
;
740 krberr
= shishi_krberror (handle
);
742 return SHISHI_MALLOC_ERROR
;
744 fprintf (stderr
, "Processing %d bytes...\n", inlen
);
746 msgtype
= get_msgtype (handle
, in
, inlen
);
748 fprintf (stderr
, "ASN.1 msg-type %d (0x%x)...\n", msgtype
, msgtype
);
752 case SHISHI_MSGTYPE_AS_REQ
:
753 kdcreq
= shishi_der2asn1_asreq (handle
, in
, inlen
);
756 asreq (handle
, arg
, kdcreq
, out
, outlen
);
761 rc
= shishi_krberror_set_etext (handle
, krberr
,
762 "Cannot parse AS-REQ");
768 case SHISHI_MSGTYPE_TGS_REQ
:
769 kdcreq
= shishi_der2asn1_tgsreq (handle
, in
, inlen
);
772 tgsreq (handle
, arg
, kdcreq
, out
, outlen
);
777 rc
= shishi_krberror_set_etext (handle
, krberr
,
778 "Cannot parse TGS-REQ");
785 rc
= shishi_krberror_set_etext (handle
, krberr
,
786 "Unsupported message type");
792 rc
= shishi_krberror_der (handle
, krberr
, out
, outlen
);
800 process (Shishi
* handle
, struct arguments
*arg
,
801 char *in
, int inlen
, char **out
, size_t * outlen
)
808 rc
= process_1 (handle
, arg
, in
, inlen
, out
, outlen
);
810 if (rc
!= SHISHI_OK
|| *out
== NULL
|| *outlen
== 0)
812 *out
= fatal_krberror
;
813 *outlen
= fatal_krberror_len
;
826 kdc_listen (struct arguments
*arg
)
828 struct listenspec
*ls
;
833 for (i
= 0; i
< arg
->nlistenspec
; i
++)
835 ls
= &arg
->listenspec
[i
];
838 printf ("Listening on %s...", ls
->str
);
840 ls
->sockfd
= socket (ls
->family
, ls
->type
, 0);
851 if (setsockopt (ls
->sockfd
, SOL_SOCKET
, SO_REUSEADDR
,
852 (char *) &yes
, sizeof (yes
)) < 0)
856 perror ("setsockopt");
862 if (bind (ls
->sockfd
, &ls
->addr
, sizeof (ls
->addr
)) != 0)
872 if (ls
->type
== SOCK_STREAM
&& listen (ls
->sockfd
, 512) != 0)
889 fprintf (stderr
, "Failed to bind any ports.\n");
894 printf ("Listening on %d ports...\n", maxfd
);
900 kdc_loop (Shishi
* handle
, struct arguments
*arg
)
902 struct listenspec
*ls
;
904 struct sockaddr addr
;
905 socklen_t length
= sizeof (addr
);
909 ssize_t sent_bytes
, read_bytes
;
918 for (i
= 0; i
< arg
->nlistenspec
; i
++)
920 if (arg
->listenspec
[i
].sockfd
>= maxfd
)
921 maxfd
= arg
->listenspec
[i
].sockfd
+ 1;
922 FD_SET (arg
->listenspec
[i
].sockfd
, &readfds
);
925 while ((rc
= select (maxfd
, &readfds
, NULL
, NULL
, NULL
)) == 0);
934 for (i
= 0; i
< arg
->nlistenspec
; i
++)
935 if (FD_ISSET (arg
->listenspec
[i
].sockfd
, &readfds
))
937 if (arg
->listenspec
[i
].type
== SOCK_STREAM
&&
938 arg
->listenspec
[i
].family
!= -1)
940 fprintf (stderr
, "New connection on %s...",
941 arg
->listenspec
[i
].str
);
943 /* XXX search for closed fd's before allocating new entry */
944 arg
->listenspec
= realloc (arg
->listenspec
,
945 sizeof (*arg
->listenspec
) *
946 (arg
->nlistenspec
+ 1));
947 if (arg
->listenspec
!= NULL
)
949 struct sockaddr_in
*sin
;
953 ls
= &arg
->listenspec
[arg
->nlistenspec
- 1];
955 ls
->type
= arg
->listenspec
[i
].type
;
957 length
= sizeof (ls
->addr
);
958 ls
->sockfd
= accept (arg
->listenspec
[i
].sockfd
,
960 sin
= (struct sockaddr_in
*) &ls
->addr
;
961 str
= inet_ntoa (sin
->sin_addr
);
962 ls
->str
= malloc (strlen (arg
->listenspec
[i
].str
) +
963 strlen (" peer ") + strlen (str
) + 1);
964 sprintf (ls
->str
, "%s peer %s", arg
->listenspec
[i
].str
,
971 ls
= &arg
->listenspec
[i
];
973 read_bytes
= recvfrom (ls
->sockfd
, ls
->buf
+ ls
->bufpos
,
974 BUFSIZ
- ls
->bufpos
, 0, &addr
,
977 if (arg
->listenspec
[i
].type
== SOCK_STREAM
&&
978 arg
->listenspec
[i
].family
== -1 && read_bytes
== 0)
980 printf ("Peer %s disconnected\n", ls
->str
);
986 ls
->bufpos
+= read_bytes
;
987 ls
->buf
[ls
->bufpos
] = '\0';
990 printf ("Has %d bytes from %s\n", ls
->bufpos
, ls
->str
);
992 if (arg
->listenspec
[i
].type
== SOCK_DGRAM
||
994 ntohl (*(int *) ls
->buf
) + 4 == ls
->bufpos
))
999 if (arg
->listenspec
[i
].type
== SOCK_STREAM
)
1000 process (handle
, arg
, ls
->buf
+ 4, ls
->bufpos
- 4,
1003 process (handle
, arg
, ls
->buf
, ls
->bufpos
, &p
, &plen
);
1008 sent_bytes
= sendto (ls
->sockfd
, p
, plen
,
1010 while (sent_bytes
== -1 && errno
== EAGAIN
);
1014 else if ((size_t) sent_bytes
> plen
)
1015 fprintf (stderr
, "wrote %db but buffer only %db",
1017 else if ((size_t) sent_bytes
< plen
)
1019 "short write (%db) writing %d bytes\n",
1022 if (p
!= fatal_krberror
)
1036 kdc_setuid (struct arguments
*arg
)
1038 struct passwd
*passwd
;
1044 passwd
= getpwnam (arg
->setuid
);
1047 perror ("setuid: getpwnam");
1051 rc
= setuid (passwd
->pw_uid
);
1059 printf ("User identity set to `%s' (%d)...\n",
1060 passwd
->pw_name
, passwd
->pw_uid
);
1066 kdc_unlisten (struct arguments
*arg
)
1071 for (i
= 0; i
< arg
->nlistenspec
; i
++)
1072 if (arg
->listenspec
[i
].sockfd
)
1075 printf ("Closing %s...", arg
->listenspec
[i
].str
);
1076 rc
= close (arg
->listenspec
[i
].sockfd
);
1080 printf ("failed\n");
1083 else if (!arg
->silent
)
1089 launch (Shishi
* handle
, struct arguments
*arg
)
1093 rc
= kdc_listen (arg
);
1097 rc
= kdc_setuid (arg
);
1101 signal (SIGINT
, ctrlc
);
1102 signal (SIGTERM
, ctrlc
);
1104 rc
= kdc_loop (handle
, arg
);
1114 setup (Shishi
* handle
, struct arguments
*arg
)
1119 rc
= setup_fatal_krberror (handle
);
1120 if (rc
!= SHISHI_OK
)
1122 syslog (LOG_ERR
, "Cannot allocate fatal error message\n");
1126 asprintf (&tgtname
, "krbtgt/%s", shishi_realm_default (handle
));
1127 arg
->tgskey
= shishi_keys_for_serverrealm_in_file
1128 (handle
, arg
->keyfile
, tgtname
, shishi_realm_default (handle
));
1132 syslog (LOG_ERR
, "Key for krbtgt/%s not found in %s\n",
1133 shishi_realm_default (handle
), arg
->keyfile
);
1137 rc
= launch (handle
, arg
);
1139 shishi_key_done (arg
->tgskey
);
1145 init (struct arguments
*arg
)
1150 rc
= shishi_init_server_with_paths (&handle
, arg
->cfgfile
);
1151 if (rc
!= SHISHI_OK
)
1153 syslog (LOG_ERR
, "Aborting due to library initialization failure\n");
1157 rc
= setup (handle
, arg
);
1159 shishi_done (handle
);
1165 main (int argc
, char *argv
[])
1167 struct arguments arg
;
1171 openlog (PACKAGE
, LOG_CONS
| LOG_PERROR
, LOG_DAEMON
);
1173 openlog (PACKAGE
, LOG_CONS
, LOG_DAEMON
);
1176 memset ((void *) &arg
, 0, sizeof (arg
));
1177 argp_parse (&argp
, argc
, argv
, ARGP_IN_ORDER
, 0, &arg
);
1180 arg
.keyfile
= strdup (KDCKEYFILE
);
1183 arg
.cfgfile
= strdup (SYSTEMCFGFILE
);