copy_addrs.c fwd_tgt.c mk_cred.c sendauth.c: Added FAR declarations
[krb5.git] / src / lib / krb5 / krb / fwd_tgt.c
1 /*
2  * lib/krb5/krb/get_in_tkt.c
3  *
4  * Copyright 1995 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  * 
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  M.I.T. makes no representations about the suitability of
20  * this software for any purpose.  It is provided "as is" without express
21  * or implied warranty.
22  */
23
24 #define NEED_SOCKETS
25 #include "k5-int.h"
26 #include <memory.h>
27
28 /* helper function: convert flags to necessary KDC options */
29 #define flags2options(flags) (flags & KDC_TKT_COMMON_MASK)
30
31 /* Get a TGT for use at the remote host */
32 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
33 krb5_fwd_tgt_creds(context, auth_context, rhost, client, server, cc,
34                    forwardable, outbuf)
35     krb5_context context;
36     krb5_auth_context auth_context;
37     char FAR *rhost;
38     krb5_principal client;
39     krb5_principal server;
40     krb5_ccache cc;
41     int forwardable;      /* Should forwarded TGT also be forwardable? */
42     krb5_data FAR *outbuf;
43 {
44     krb5_replay_data replaydata;
45     krb5_data FAR * scratch = 0;
46     krb5_address FAR * FAR *addrs = 0;
47     krb5_error_code retval;
48     krb5_creds creds, tgt;
49     krb5_creds FAR *pcreds;
50     krb5_flags kdcoptions;
51     int close_cc = 0;
52     int free_rhost = 0;
53
54     memset((char *)&creds, 0, sizeof(creds));
55     memset((char *)&tgt, 0, sizeof(creds));
56
57     if (rhost == NULL) {
58         if (krb5_princ_type(context, server) != KRB5_NT_SRV_HST)
59             return(KRB5_FWD_BAD_PRINCIPAL);
60
61         if (krb5_princ_size(context, server) < 2)
62             return (KRB5_CC_BADNAME);
63         
64         rhost = malloc(server->data[1].length+1);
65         if (!rhost)
66             return ENOMEM;
67         free_rhost = 1;
68         memcpy(rhost, server->data[1].data, server->data[1].length);
69         rhost[server->data[1].length] = '\0';
70     }
71
72     retval = krb5_os_hostaddr(context, rhost, &addrs);
73     if (retval)
74         goto errout;
75
76     if ((retval = krb5_copy_principal(context, client, &creds.client)))
77         goto errout;
78     
79     if ((retval = krb5_build_principal_ext(context, &creds.server,
80                                            server->realm.length,
81                                            server->realm.data,
82                                            KRB5_TGS_NAME_SIZE,
83                                            KRB5_TGS_NAME,
84                                            client->realm.length,
85                                            client->realm.data,
86                                            0)))
87         goto errout;
88         
89     if (cc == 0) {
90         if ((retval = krb5_cc_default(context, &cc)))
91             goto errout;
92         close_cc = 1;
93     }
94
95     /* fetch tgt directly from cache */
96     retval = krb5_cc_retrieve_cred (context, cc, KRB5_TC_MATCH_SRV_NAMEONLY,
97                                     &creds, &tgt);
98     if (retval)
99         goto errout;
100
101     /* tgt->client must be equal to creds.client */
102     if (!krb5_principal_compare(context, tgt.client, creds.client)) {
103         retval = KRB5_PRINC_NOMATCH;
104         goto errout;
105     }
106
107     if (!tgt.ticket.length) {
108         retval = KRB5_NO_TKT_SUPPLIED;
109         goto errout;
110     }
111
112     creds.times = tgt.times;
113     creds.times.starttime = 0;
114     kdcoptions = flags2options(tgt.ticket_flags)|KDC_OPT_FORWARDED;
115
116     if (!forwardable) /* Reset KDC_OPT_FORWARDABLE */
117       kdcoptions &= ~(KDC_OPT_FORWARDABLE);
118
119     if ((retval = krb5_get_cred_via_tkt(context, &tgt, kdcoptions,
120                                         addrs, &creds, &pcreds)))
121         goto errout;
122
123     retval = krb5_mk_1cred(context, auth_context, pcreds,
124                            &scratch, &replaydata);
125     krb5_free_creds(context, pcreds);
126
127     if (retval) {
128         if (scratch)
129             krb5_free_data(context, scratch);
130     } else {
131         *outbuf = *scratch;
132         krb5_xfree(scratch);
133     }
134         
135 errout:
136     if (addrs)
137         krb5_free_addresses(context, addrs);
138     if (close_cc)
139         krb5_cc_close(context, cc);
140     if (free_rhost)
141         free(rhost);
142     krb5_free_cred_contents(context, &creds);
143     krb5_free_cred_contents(context, &tgt);
144     return retval;
145 }