Change __signed to signed.
[dragonfly.git] / crypto / kerberosIV / appl / kauth / kauthd.c
1 /* $FreeBSD: src/crypto/kerberosIV/appl/kauth/kauthd.c,v 1.1.1.3.2.1 2000/07/20 14:04:33 assar Exp $ */
2 /* $DragonFly: src/crypto/kerberosIV/appl/kauth/Attic/kauthd.c,v 1.2 2003/06/17 04:24:36 dillon Exp $ */
3
4 /*
5  * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
6  * (Royal Institute of Technology, Stockholm, Sweden).
7  * All rights reserved.
8  * 
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 
20  * 3. Neither the name of the Institute nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  * 
24  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #include "kauth.h"
38
39 RCSID("$Id: kauthd.c,v 1.25.2.1 2000/06/28 19:07:58 assar Exp $");
40
41 krb_principal princ;
42 static char locuser[SNAME_SZ];
43 static int  lifetime;
44 static char tktfile[MaxPathLen];
45
46 struct remote_args {
47      int sock;
48      des_key_schedule *schedule;
49      des_cblock *session;
50      struct sockaddr_in *me, *her;
51 };
52
53 static int
54 decrypt_remote_tkt (const char *user,
55                     const char *inst,
56                     const char *realm,
57                     const void *varg,
58                     key_proc_t key_proc,
59                     KTEXT *cipp)
60 {
61      char buf[BUFSIZ];
62      void *ptr;
63      int len;
64      KTEXT cip  = *cipp;
65      struct remote_args *args = (struct remote_args *)varg;
66
67      write_encrypted (args->sock, cip->dat, cip->length,
68                       *args->schedule, args->session, args->me,
69                       args->her);
70      len = read_encrypted (args->sock, buf, sizeof(buf), &ptr, *args->schedule,
71                            args->session, args->her, args->me);
72      memcpy(cip->dat, ptr, cip->length);
73           
74      return 0;
75 }
76
77 static int
78 doit(int sock)
79 {
80      int status;
81      KTEXT_ST ticket;
82      AUTH_DAT auth;
83      char instance[INST_SZ];
84      des_key_schedule schedule;
85      struct sockaddr_in thisaddr, thataddr;
86      int addrlen;
87      int len;
88      char buf[BUFSIZ];
89      void *data;
90      struct passwd *passwd;
91      char version[KRB_SENDAUTH_VLEN + 1];
92      char remotehost[MaxHostNameLen];
93
94      addrlen = sizeof(thisaddr);
95      if (getsockname (sock, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
96          addrlen != sizeof(thisaddr)) {
97           return 1;
98      }
99      addrlen = sizeof(thataddr);
100      if (getpeername (sock, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
101          addrlen != sizeof(thataddr)) {
102           return 1;
103      }
104
105      inaddr2str (thataddr.sin_addr, remotehost, sizeof(remotehost));
106
107      k_getsockinst (sock, instance, sizeof(instance));
108      status = krb_recvauth (KOPT_DO_MUTUAL, sock, &ticket, "rcmd", instance,
109                             &thataddr, &thisaddr, &auth, "", schedule,
110                             version);
111      if (status != KSUCCESS ||
112          strncmp(version, KAUTH_VERSION, KRB_SENDAUTH_VLEN) != 0) {
113           return 1;
114      }
115      len = read_encrypted (sock, buf, sizeof(buf), &data, schedule,
116                            &auth.session, &thataddr, &thisaddr);
117      if (len < 0) {
118           write_encrypted (sock, "read_enc failed",
119                            sizeof("read_enc failed") - 1, schedule,
120                            &auth.session, &thisaddr, &thataddr);
121           return 1;
122      }
123      if (unpack_args(data, &princ, &lifetime, locuser,
124                      tktfile)) {
125           write_encrypted (sock, "unpack_args failed",
126                            sizeof("unpack_args failed") - 1, schedule,
127                            &auth.session, &thisaddr, &thataddr);
128           return 1;
129      }
130
131      if( kuserok(&auth, locuser) != 0) {
132          snprintf(buf, sizeof(buf), "%s cannot get tickets for %s",
133                   locuser, krb_unparse_name(&princ));
134          syslog (LOG_ERR, "%s", buf);
135          write_encrypted (sock, buf, strlen(buf), schedule,
136                           &auth.session, &thisaddr, &thataddr);
137          return 1;
138      }
139      passwd = k_getpwnam (locuser);
140      if (passwd == NULL) {
141           snprintf (buf, sizeof(buf), "No user '%s'", locuser);
142           syslog (LOG_ERR, "%s", buf);
143           write_encrypted (sock, buf, strlen(buf), schedule,
144                            &auth.session, &thisaddr, &thataddr);
145           return 1;
146      }
147      if (setgid (passwd->pw_gid) ||
148          initgroups(passwd->pw_name, passwd->pw_gid) ||
149          setuid(passwd->pw_uid)) {
150           snprintf (buf, sizeof(buf), "Could not change user");
151           syslog (LOG_ERR, "%s", buf);
152           write_encrypted (sock, buf, strlen(buf), schedule,
153                            &auth.session, &thisaddr, &thataddr);
154           return 1;
155      }
156      write_encrypted (sock, "ok", sizeof("ok") - 1, schedule,
157                       &auth.session, &thisaddr, &thataddr);
158
159      if (*tktfile == 0)
160          snprintf(tktfile, sizeof(tktfile), "%s%u", TKT_ROOT, (unsigned)getuid());
161      krb_set_tkt_string (tktfile);
162
163      {
164           struct remote_args arg;
165
166           arg.sock     = sock;
167           arg.schedule = &schedule;
168           arg.session  = &auth.session;
169           arg.me       = &thisaddr;
170           arg.her      = &thataddr;
171
172           status = krb_get_in_tkt (princ.name, princ.instance, princ.realm,
173                                    KRB_TICKET_GRANTING_TICKET,
174                                    princ.realm,
175                                    lifetime, NULL, decrypt_remote_tkt, &arg);
176      }
177      if (status == KSUCCESS) {
178          syslog (LOG_INFO, "from %s(%s): %s -> %s",
179                  remotehost,
180                  inet_ntoa(thataddr.sin_addr),
181                  locuser,
182                  krb_unparse_name (&princ));
183           write_encrypted (sock, "ok", sizeof("ok") - 1, schedule,
184                            &auth.session, &thisaddr, &thataddr);
185           return 0;
186      } else {
187           snprintf (buf, sizeof(buf), "TGT failed: %s", krb_get_err_text(status));
188           syslog (LOG_NOTICE, "%s", buf);
189           write_encrypted (sock, buf, strlen(buf), schedule,
190                            &auth.session, &thisaddr, &thataddr);
191           return 1;
192      }
193 }
194
195 int
196 main (int argc, char **argv)
197 {
198     openlog ("kauthd", LOG_ODELAY, LOG_AUTH);
199
200     if(argc > 1 && strcmp(argv[1], "-i") == 0)
201         mini_inetd (k_getportbyname("kauth", "tcp", htons(KAUTH_PORT)));
202     return doit(STDIN_FILENO);
203 }