not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / kdm / backend / krb5auth.c
blob1c732dd22c47d5cafa78beebfe45cf0bd45ad137
1 /*
3 Copyright 1994, 1998 The Open Group
4 Copyright 2003 Oswald Buddenhagen <ossi@kde.org>
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 OTHER DEALINGS IN THE SOFTWARE.
23 Except as contained in this notice, the name of a copyright holder shall
24 not be used in advertising or otherwise to promote the sale, use or
25 other dealings in this Software without prior written authorization
26 from the copyright holder.
31 * xdm - display manager daemon
32 * Author: Stephen Gildea, The Open Group
34 * generate Kerberos Version 5 authorization records
37 #include "dm.h"
38 #include "dm_auth.h"
39 #include "dm_error.h"
41 #include <sys/types.h>
42 #include <sys/stat.h>
44 #include <krb5/krb5.h>
46 static krb5_context ctx;
48 /*ARGSUSED*/
49 void
50 krb5InitAuth( unsigned short name_len ATTR_UNUSED, const char *name ATTR_UNUSED )
52 if (krb5_init_context( &ctx ))
53 logError( "Error while initializing Krb5 context\n" );
57 * Returns malloc'ed string that is the credentials cache name.
58 * name should be freed by caller.
60 static char *
61 krb5CCacheName( const char *dname )
63 char *name;
64 const char *tmpdir;
65 int dnl, nl;
67 tmpdir = getenv( "TMPDIR" );
68 if (!tmpdir)
69 tmpdir = "/tmp";
70 dnl = strlen( dname );
71 name = Malloc( strlen( tmpdir ) + dnl + 20 );
72 if (!name)
73 return NULL;
74 nl = sprintf( name, "FILE:%s/K5C", tmpdir );
75 cleanUpFileName( dname, name + nl, dnl + 1 );
76 return name;
79 Xauth *
80 krb5GetAuthFor( unsigned short namelen, const char *name, const char *dname )
82 Xauth *new;
83 char *filename;
85 if (!(new = (Xauth *)Malloc( sizeof(*new) )))
86 return (Xauth *)0;
87 new->family = FamilyWild;
88 new->address_length = 0;
89 new->address = 0;
90 new->number_length = 0;
91 new->number = 0;
93 if (dname) {
94 if (!(filename = krb5CCacheName( dname ))) {
95 free( (char *)new );
96 return (Xauth *)0;
98 new->data = 0;
99 if (!strApp( &new->data, "UU:", filename, (char *)0 )) {
100 free( filename );
101 free( (char *)new );
102 return (Xauth *)0;
104 free( filename );
105 new->data_length = strlen( new->data );
106 } else {
107 new->data = NULL;
108 new->data_length = 0;
111 if (!(new->name = (char *)Malloc( namelen ))) {
112 free( (char *)new->data );
113 free( (char *)new );
114 return (Xauth *)0;
116 memmove( new->name, name, namelen );
117 new->name_length = namelen;
118 return new;
122 Xauth *
123 krb5GetAuth( unsigned short namelen, const char *name )
125 return krb5GetAuthFor( namelen, name, NULL );
129 static krb5_error_code
130 krb5DisplayCCache( const char *dname, krb5_ccache *ccache_return, char **name )
132 char *ccname;
133 krb5_error_code code;
135 if (!(ccname = krb5CCacheName( dname )))
136 return ENOMEM;
137 debug( "resolving Kerberos cache %s\n", ccname );
138 if ((code = krb5_cc_resolve( ctx, ccname, ccache_return )) || !name)
139 free( ccname );
140 else
141 *name = ccname;
142 return code;
145 char *
146 krb5Init( const char *user, const char *passwd, const char *dname )
148 krb5_error_code code;
149 krb5_get_init_creds_opt options;
150 krb5_principal me;
151 krb5_creds my_creds;
152 krb5_ccache ccache;
153 char *ccname;
155 if (!ctx)
156 return 0;
158 if ((code = krb5_parse_name( ctx, user, &me ))) {
159 logError( "%s while parsing Krb5 user %\"s\n",
160 error_message( code ), user );
161 return 0;
164 krb5_get_init_creds_opt_init( &options );
165 /*krb5_get_init_creds_opt_set_tkt_life (&options, 60*60*8);*/ /* 8 hours */
167 if ((code = krb5_get_init_creds_password( ctx, &my_creds,
168 me, /* principal */
169 (char * /* for MIT */) passwd,
170 0, /* prompter */
171 0, /* prompter ctx */
172 0, /* start time delta */
173 0, /* service */
174 &options )))
176 char *my_name = NULL;
177 int code2 = krb5_unparse_name( ctx, me, &my_name );
178 if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
179 logError( "Password incorrect for Krb5 principal %\"s\n",
180 code2 ? user : my_name );
181 else
182 logError( "%s while getting initial Krb5 credentials for %\"s\n",
183 error_message( code ), code2 ? user : my_name );
184 if (my_name)
185 free( my_name );
186 goto err3;
189 if ((code = krb5DisplayCCache( dname, &ccache, &ccname ))) {
190 logError( "%s while getting Krb5 ccache for %\"s\n",
191 error_message( code ), dname );
192 goto err2;
195 if ((code = krb5_cc_initialize( ctx, ccache, me ))) {
196 logError( "%s while initializing Krb5 cache %\"s\n",
197 error_message( code ), ccname );
198 goto err1;
201 if ((code = krb5_cc_store_cred( ctx, ccache, &my_creds ))) {
202 logError( "%s while storing Krb5 credentials to cache %\"s\n",
203 error_message( code ), ccname );
204 err1:
205 krb5_cc_close( ctx, ccache );
206 free( ccname );
207 err2:
208 krb5_free_cred_contents( ctx, &my_creds );
209 err3:
210 krb5_free_principal( ctx, me );
211 return 0;
214 krb5_cc_close( ctx, ccache );
215 krb5_free_cred_contents( ctx, &my_creds );
216 krb5_free_principal( ctx, me );
217 return ccname;
220 void
221 krb5Destroy( const char *dname )
223 krb5_error_code code;
224 krb5_ccache ccache;
226 if (!ctx)
227 return;
229 if ((code = krb5DisplayCCache( dname, &ccache, 0 )))
230 logError( "%s while getting Krb5 ccache to destroy\n",
231 error_message( code ) );
232 else {
233 if ((code = krb5_cc_destroy( ctx, ccache ))) {
234 if (code == KRB5_FCC_NOFILE)
235 debug( "no Kerberos ccache file found to destroy\n" );
236 else
237 logError( "%s while destroying Krb5 credentials cache\n",
238 error_message( code ) );
239 } else
240 debug( "kerberos ccache destroyed\n" );