aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/internal.h7
-rw-r--r--client/keytab.c55
-rw-r--r--client/wallet.c8
3 files changed, 56 insertions, 14 deletions
diff --git a/client/internal.h b/client/internal.h
index 960554e..7980fef 100644
--- a/client/internal.h
+++ b/client/internal.h
@@ -37,9 +37,10 @@ int run_command(struct remctl *, const char **command, char **data,
/* Given a remctl object, the type for the wallet interface, the name of a
keytab object, and a file name, call the correct wallet commands to
- download a keytab and write it to that file. */
-void get_keytab(struct remctl *, const char *type, const char *name,
- const char *file);
+ download a keytab and write it to that file. If srvtab is not NULL, write
+ a srvtab based on the keytab after a successful download. */
+int get_keytab(struct remctl *, const char *type, const char *name,
+ const char *file, const char *srvtab);
/* Given a filename, some data, and a length, write that data to the given
file safely and atomically by creating file.new, writing the data, linking
diff --git a/client/keytab.c b/client/keytab.c
index b815e4a..51b3889 100644
--- a/client/keytab.c
+++ b/client/keytab.c
@@ -16,20 +16,56 @@
#include <client/internal.h>
#include <util/util.h>
+
+/*
+** Configure a given keytab to be synchronized with an AFS kaserver if it
+** isn't already. Returns true on success, false on failure.
+*/
+static int
+set_sync(struct remctl *r, const char *type, const char *name)
+{
+ const char *command[7];
+ char *data = NULL;
+ size_t length = 0;
+ int status;
+
+ command[0] = type;
+ command[1] = "attr";
+ command[2] = "keytab";
+ command[3] = name;
+ command[4] = "sync";
+ command[5] = NULL;
+ status = run_command(r, command, &data, &length);
+ if (status != 0)
+ return 0;
+ if (data == NULL || strstr(data, "kaserver\n") == NULL) {
+ command[5] = "kaserver";
+ command[6] = NULL;
+ status = run_command(r, command, NULL, NULL);
+ if (status != 0)
+ return 0;
+ }
+ return 1;
+}
+
+
/*
** Given a remctl object, the name of a keytab object, and a file name, call
** the correct wallet commands to download a keytab and write it to that
-** file.
+** file. Returns the setatus or 255 on an internal error.
*/
-void
+int
get_keytab(struct remctl *r, const char *type, const char *name,
- const char *file)
+ const char *file, const char *srvtab)
{
const char *command[5];
char *data = NULL;
size_t length = 0;
- int status = 255;
+ int status;
+ if (srvtab != NULL)
+ if (!set_sync(r, type, name))
+ return 255;
command[0] = type;
command[1] = "get";
command[2] = "keytab";
@@ -37,8 +73,13 @@ get_keytab(struct remctl *r, const char *type, const char *name,
command[4] = NULL;
status = run_command(r, command, &data, &length);
if (status != 0)
- exit(status);
- if (data == NULL)
- die("no data returned by wallet server");
+ return status;
+ if (data == NULL) {
+ warn("no data returned by wallet server");
+ return 255;
+ }
write_file(file, data, length);
+ if (srvtab != NULL)
+ write_srvtab(srvtab, name, file);
+ return 0;
}
diff --git a/client/wallet.c b/client/wallet.c
index 5e23503..9aa2cee 100644
--- a/client/wallet.c
+++ b/client/wallet.c
@@ -129,10 +129,9 @@ main(int argc, char *argv[])
if (strcmp(argv[0], "get") == 0 && strcmp(argv[1], "keytab") == 0) {
if (argc > 3)
die("too many arguments");
- get_keytab(r, type, argv[2], file);
- if (srvtab != NULL)
- write_srvtab(srvtab, argv[2], file);
- exit(0);
+ status = get_keytab(r, type, argv[2], file, srvtab);
+ remctl_close(r);
+ exit(status);
} else {
command = xmalloc(sizeof(char *) * (argc + 2));
command[0] = type;
@@ -140,6 +139,7 @@ main(int argc, char *argv[])
command[i + 1] = argv[i];
command[argc + 1] = NULL;
status = run_command(r, command, NULL, NULL);
+ remctl_close(r);
exit(status);
}