r9415: Remove old kerberos code (including salt guessing code) that has only
[ira/wip.git] / source4 / auth / kerberos / kerberos.c
1 /* 
2    Unix SMB/CIFS implementation.
3    kerberos utility library
4    Copyright (C) Andrew Tridgell 2001
5    Copyright (C) Remus Koos 2001
6    Copyright (C) Nalin Dahyabhai 2004.
7    Copyright (C) Jeremy Allison 2004.
8    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26 #include "system/network.h"
27 #include "system/kerberos.h"
28 #include "system/time.h"
29 #include "auth/kerberos/kerberos.h"
30 #include "secrets.h"
31 #include "pstring.h"
32 #include "ads.h"
33
34 #ifdef HAVE_KRB5
35
36 #define LIBADS_CCACHE_NAME "MEMORY:libads"
37
38 /*
39   we use a prompter to avoid a crash bug in the kerberos libs when 
40   dealing with empty passwords
41   this prompter is just a string copy ...
42 */
43 static krb5_error_code 
44 kerb_prompter(krb5_context ctx, void *data,
45                const char *name,
46                const char *banner,
47                int num_prompts,
48                krb5_prompt prompts[])
49 {
50         if (num_prompts == 0) return 0;
51
52         memset(prompts[0].reply->data, '\0', prompts[0].reply->length);
53         if (prompts[0].reply->length > 0) {
54                 if (data) {
55                         strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1);
56                         prompts[0].reply->length = strlen(prompts[0].reply->data);
57                 } else {
58                         prompts[0].reply->length = 0;
59                 }
60         }
61         return 0;
62 }
63
64 /*
65   simulate a kinit, putting the tgt in the given credentials cache. 
66   Orignally by remus@snapserver.com
67  
68   This version is built to use a keyblock, rather than needing the
69   original password.
70 */
71  int kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, 
72                                 const char *principal, krb5_keyblock *keyblock,
73                                 time_t *expire_time, time_t *kdc_time)
74 {
75         krb5_error_code code = 0;
76         krb5_principal me;
77         krb5_creds my_creds;
78         krb5_get_init_creds_opt options;
79
80         if ((code = krb5_parse_name(ctx, principal, &me))) {
81                 return code;
82         }
83
84         krb5_get_init_creds_opt_init(&options);
85
86         if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, me, keyblock,
87                                                  0, NULL, &options))) {
88                 krb5_free_principal(ctx, me);
89                 return code;
90         }
91         
92         if ((code = krb5_cc_initialize(ctx, cc, me))) {
93                 krb5_free_cred_contents(ctx, &my_creds);
94                 krb5_free_principal(ctx, me);
95                 return code;
96         }
97         
98         if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
99                 krb5_free_cred_contents(ctx, &my_creds);
100                 krb5_free_principal(ctx, me);
101                 return code;
102         }
103         
104         if (expire_time) {
105                 *expire_time = (time_t) my_creds.times.endtime;
106         }
107
108         if (kdc_time) {
109                 *kdc_time = (time_t) my_creds.times.starttime;
110         }
111
112         krb5_free_cred_contents(ctx, &my_creds);
113         krb5_free_principal(ctx, me);
114         
115         return 0;
116 }
117
118 /*
119   simulate a kinit, putting the tgt in the given credentials cache. 
120   Orignally by remus@snapserver.com
121 */
122  int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, 
123                                const char *principal, const char *password, 
124                                time_t *expire_time, time_t *kdc_time)
125 {
126         krb5_error_code code = 0;
127         krb5_principal me;
128         krb5_creds my_creds;
129         krb5_get_init_creds_opt options;
130
131         if ((code = krb5_parse_name(ctx, principal, &me))) {
132                 return code;
133         }
134
135         krb5_get_init_creds_opt_init(&options);
136
137         if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, password, 
138                                                  kerb_prompter, 
139                                                  NULL, 0, NULL, &options))) {
140                 krb5_free_principal(ctx, me);
141                 return code;
142         }
143         
144         if ((code = krb5_cc_initialize(ctx, cc, me))) {
145                 krb5_free_cred_contents(ctx, &my_creds);
146                 krb5_free_principal(ctx, me);
147                 return code;
148         }
149         
150         if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
151                 krb5_free_cred_contents(ctx, &my_creds);
152                 krb5_free_principal(ctx, me);
153                 return code;
154         }
155         
156         if (expire_time) {
157                 *expire_time = (time_t) my_creds.times.endtime;
158         }
159
160         if (kdc_time) {
161                 *kdc_time = (time_t) my_creds.times.starttime;
162         }
163
164         krb5_free_cred_contents(ctx, &my_creds);
165         krb5_free_principal(ctx, me);
166         
167         return 0;
168 }
169
170
171 #endif