2 Copyright (C) 2003 - 2010 Chaskiel Grundman
3 Copyright (c) 2011 Your Filesystem Inc.
4 Copyright (c) 2012 Sine Nomine Associates
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
18 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <afsconfig.h>
30 #include <afs/param.h>
35 #include <afs/cellconfig.h>
36 #ifndef AFSCONF_CLIENTNAME
37 #include <afs/dirpath.h>
38 #define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
41 #include <rx/rx_null.h>
47 #include "afscp_internal.h"
50 #include <hcrypto/des.h>
52 #ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
53 #define Z_keydata(keyblock) ((keyblock)->contents)
54 #define Z_keylen(keyblock) ((keyblock)->length)
55 #define Z_credskey(creds) (&(creds)->keyblock)
56 #define Z_enctype(keyblock) ((keyblock)->enctype)
58 #define Z_keydata(keyblock) ((keyblock)->keyvalue.data)
59 #define Z_keylen(keyblock) ((keyblock)->keyvalue.length)
60 #define Z_credskey(creds) (&(creds)->session)
61 #define Z_enctype(keyblock) ((keyblock)->keytype)
64 static int insecure = 0;
65 static int try_anonymous = 0;
66 static char authas_name[256];
67 static char authas_inst[256];
77 afscp_AnonymousAuth(int state)
79 try_anonymous = state;
84 * Connect to all servers using authenticated connections, using the local
85 * KeyFile to appear as an arbitrary user.
87 * @param[in] aname The pts username to impersonate
89 * @note aname is krb4-based name, not a krb5 principal. So for example, you
90 * probably want to give "user.admin" instead of "user/admin".
92 * @return operation status
96 afscp_LocalAuthAs(const char *aname)
98 const char *ainst = strchr(aname, '.');
99 size_t namelen, instlen;
102 namelen = ainst - aname;
104 instlen = strlen(ainst);
106 namelen = strlen(aname);
111 if (namelen+1 > sizeof(authas_name) || instlen+1 > sizeof(authas_inst)) {
114 strncpy(authas_name, aname, namelen);
115 strncpy(authas_inst, ainst, instlen);
119 static struct afsconf_dir *confdir;
122 afscp_SetConfDir(char *confDir)
125 afsconf_Close(confdir);
127 confdir = afsconf_Open(confDir);
131 _GetCellInfo(char *cell, struct afsconf_cell *celldata)
135 confdir = afsconf_Open(AFSCONF_CLIENTNAME);
136 if (confdir == NULL) {
139 code = afsconf_GetCellInfo(confdir, cell, AFSCONF_VLDBSERVICE, celldata);
144 _GetNullSecurityObject(struct afscp_cell *cell)
146 cell->security = (struct rx_securityClass *)rxnull_NewClientSecurityObject();
147 cell->scindex = RX_SECIDX_NULL;
152 _GetLocalSecurityObject(struct afscp_cell *cell,
153 char *aname, char *ainst)
157 struct ktc_encryptionKey key, session;
158 struct rx_securityClass *tc;
162 struct afsconf_dir *tdir;
164 tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
166 code = AFSCONF_FAILURE;
170 code = afsconf_GetLatestKey(tdir, &kvno, &key);
175 DES_init_random_number_generator((DES_cblock *)&key);
176 code = DES_new_random_key((DES_cblock *)&session);
181 ticketLen = sizeof(tbuffer);
182 memset(tbuffer, 0, sizeof(tbuffer));
183 code = tkt_MakeTicket(tbuffer, &ticketLen, &key, aname, ainst, "", 0,
184 0xffffffff, &session, 0, "afs", "");
195 tc = (struct rx_securityClass *)
196 rxkad_NewClientSecurityObject(lev, &session, kvno, ticketLen,
214 _GetSecurityObject(struct afscp_cell *cell)
218 krb5_context context;
222 char **realms, *realm;
223 struct afsconf_cell celldata;
224 char localcell[MAXCELLCHARS + 1];
225 struct rx_securityClass *sc;
226 struct ktc_encryptionKey k;
229 code = _GetCellInfo(cell->name, &celldata);
234 if (authas_name[0]) {
235 code = _GetLocalSecurityObject(cell, authas_name, authas_inst);
241 code = krb5_init_context(&context); /* see aklog.c main() */
246 if (cell->realm == NULL) {
248 code = krb5_get_host_realm(context, celldata.hostName[0], &realms);
251 strlcpy(localcell, realms[0], sizeof(localcell));
252 krb5_free_host_realm(context, realms);
258 strlcpy(localcell, realm, MAXCELLCHARS + 1);
262 for (i = 0; (i < MAXCELLCHARS && cell->name[i]); i++) {
263 if (isalpha(cell->name[i]))
264 localcell[i] = toupper(cell->name[i]);
266 localcell[i] = cell->name[i];
272 code = krb5_cc_default(context, &cc);
274 memset(&match, 0, sizeof(match));
275 Z_enctype(Z_credskey(&match)) = ENCTYPE_DES_CBC_CRC;
278 code = krb5_cc_get_principal(context, cc, &match.client);
280 code = krb5_build_principal(context, &match.server,
281 strlen(realm), realm,
282 "afs", cell->name, NULL);
285 krb5_free_cred_contents(context, &match);
287 krb5_cc_close(context, cc);
288 krb5_free_context(context);
292 code = krb5_get_credentials(context, 0, cc, &match, &cred);
294 krb5_free_principal(context, match.server);
297 code = krb5_build_principal(context, &match.server,
298 strlen(realm), realm, "afs", (void *)NULL);
300 code = krb5_get_credentials(context, 0, cc, &match, &cred);
302 krb5_free_cred_contents(context, &match);
304 krb5_cc_close(context, cc);
305 krb5_free_context(context);
314 memcpy(&k.data, Z_keydata(Z_credskey(cred)), 8);
315 sc = (struct rx_securityClass *)rxkad_NewClientSecurityObject
316 (l, &k, RXKAD_TKT_TYPE_KERBEROS_V5,
317 cred->ticket.length, cred->ticket.data);
318 krb5_free_creds(context, cred);
319 krb5_free_cred_contents(context, &match);
321 krb5_cc_close(context, cc);
322 krb5_free_context(context);
328 #endif /* HAVE_KERBEROS */
330 return _GetNullSecurityObject(cell);
336 _GetVLservers(struct afscp_cell *cell)
338 struct rx_connection *conns[MAXHOSTSPERCELL + 1];
341 struct afsconf_cell celldata;
343 code = _GetCellInfo(cell->name, &celldata);
348 for (i = 0; i < celldata.numServers; i++) {
349 conns[i] = rx_NewConnection(celldata.hostAddr[i].sin_addr.s_addr,
350 htons(AFSCONF_VLDBPORT),
351 USER_SERVICE_ID, cell->security,
355 return ubik_ClientInit(conns, &cell->vlservers);