Windows: define HAVE_KRB5_CREDS_SESSION
[openafs.git] / src / WINNT / aklog / asetkey.c
1 /*
2  * $Id$
3  *
4  * asetkey - Manipulates an AFS KeyFile
5  *
6  * Updated for Kerberos 5
7  */
8 /*
9  * Copyright (c) 2007 Secure Endpoints Inc.
10  *
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  *     * Redistributions of source code must retain the above copyright
18  *       notice, this list of conditions and the following disclaimer.
19  *     * Neither the name of the Secure Endpoints Inc. nor the names of its
20  *       contributors may be used to endorse or promote products derived
21  *       from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include <afsconfig.h>
37 #include <afs/param.h>
38 #include <roken.h>
39
40 #include <ws2tcpip.h>
41
42 #include <stdio.h>
43 #include <sys/types.h>
44 #include <krb5.h>
45
46 #include <afs/stds.h>
47 #include <afs/cellconfig.h>
48 #include <afs/keys.h>
49 #ifndef PRE_AFS35
50 #include <afs/dirpath.h>
51 #endif /* !PRE_AFS35 */
52 #include <afs/com_err.h>
53 #include <krbcompat_delayload.h>
54
55 void
56 validate_krb5_availability(void)
57 {
58 #ifndef _WIN64
59 #define KRB5LIB "krb5_32.dll"
60 #else
61 #define KRB5LIB "krb5_64.dll"
62 #endif
63     HINSTANCE h = LoadLibrary(KRB5LIB);
64     if (h)
65         FreeLibrary(h);
66     else {
67         fprintf(stderr, "Kerberos for Windows library %s is not available.\n", KRB5LIB);
68         exit(2);
69     }
70 }
71
72 int
73 main(int argc, char **argv)
74 {
75     struct afsconf_dir *tdir;
76     register long code;
77     const char *confdir;
78
79     validate_krb5_availability();
80
81     if (argc == 1) {
82         printf("asetkey: usage is 'setkey <opcode> options, e.g.\n");
83         printf("    asetkey add <kvno> <keyfile> <princ>\n");
84         printf("    asetkey delete <kvno>\n");
85         printf("    asetkey list\n");
86         exit(1);
87     }
88
89 #ifdef PRE_AFS35
90     confdir = AFSCONF_SERVERNAME;
91 #else /* PRE_AFS35 */
92     confdir = AFSDIR_SERVER_ETC_DIRPATH;
93 #endif /* PRE_AFS35 */
94
95     tdir = afsconf_Open(confdir);
96     if (!tdir) {
97         printf("asetkey: can't initialize conf dir '%s'\n", confdir);
98         exit(1);
99     }
100
101     if (strcmp(argv[1], "add")==0) {
102         krb5_context context;
103         krb5_principal principal;
104         krb5_keyblock *key;
105         krb5_error_code retval;
106         int kvno;
107
108         if (argc != 5) {
109             printf("asetkey add: usage is 'asetkey add <kvno> <keyfile> <princ>\n");
110             exit(1);
111         }
112
113         krb5_init_context(&context);
114         if (krb5_enctype_valid(context, ETYPE_DES_CBC_CRC))
115             krb5_enctype_enable(context, ETYPE_DES_CBC_CRC);
116
117         kvno = atoi(argv[2]);
118         retval = krb5_parse_name(context, argv[4], &principal);
119         if (retval != 0) {
120                 afs_com_err(argv[0], retval, "while parsing AFS principal");
121                 exit(1);
122         }
123         retval = krb5_kt_read_service_key(context, argv[3], principal, kvno,
124                                           ENCTYPE_DES_CBC_CRC, &key);
125         if (retval == KRB5_KT_NOTFOUND)
126             retval = krb5_kt_read_service_key(context, argv[3], principal, kvno,
127                                                ENCTYPE_DES_CBC_MD5, &key);
128         if (retval == KRB5_KT_NOTFOUND)
129             retval = krb5_kt_read_service_key(context, argv[3], principal, kvno,
130                                                ENCTYPE_DES_CBC_MD4, &key);
131         if (retval == KRB5_KT_NOTFOUND) {
132             char * princname = NULL;
133
134             krb5_unparse_name(context, principal, &princname);
135
136             afs_com_err(argv[0], retval,
137                         "for keytab entry with Principal %s, kvno %u, DES-CBC-CRC/MD5/MD4",
138                         princname ? princname : argv[4],
139                         kvno);
140             exit(1);
141         } else if (retval != 0) {
142             afs_com_err(argv[0], retval, "while extracting AFS service key");
143                 exit(1);
144         }
145
146         if (key->keyvalue.length != 8) {
147                 printf("Key length should be 8, but is really %d!\n",
148                        key->keyvalue.length);
149                 exit(1);
150         }
151
152         code = afsconf_AddKey(tdir, kvno, key->keyvalue.data, 1);
153         if (code) {
154             printf("asetkey: failed to set key, code %d.\n", code);
155             exit(1);
156         }
157         krb5_free_principal(context, principal);
158         krb5_free_keyblock(context, key);
159     }
160     else if (strcmp(argv[1], "delete")==0) {
161         long kvno;
162         if (argc != 3) {
163             printf("asetkey delete: usage is 'asetkey delete <kvno>\n");
164             exit(1);
165         }
166         kvno = atoi(argv[2]);
167         code = afsconf_DeleteKey(tdir, kvno);
168         if (code) {
169             printf("asetkey: failed to delete key %d, (code %d)\n", kvno, code);
170             exit(1);
171         }
172     }
173     else if (strcmp(argv[1], "list") == 0) {
174         struct afsconf_keys tkeys;
175         register int i, j;
176
177         code = afsconf_GetKeys(tdir, &tkeys);
178         if (code) {
179             printf("asetkey: failed to get keys, code %d\n", code);
180             exit(1);
181         }
182         for(i=0;i<tkeys.nkeys;i++) {
183             if (tkeys.key[i].kvno != -1) {
184                 printf("kvno %4d: key is: ", tkeys.key[i].kvno);
185                 for (j = 0; j < 8; j++)
186                         printf("%02x", (unsigned char) tkeys.key[i].key[j]);
187                 printf("\n");
188             }
189         }
190         printf("All done.\n");
191     }
192     else {
193         printf("asetkey: unknown operation '%s', type 'asetkey' for assistance\n", argv[1]);
194         exit(1);
195     }
196     exit(0);
197 }