diff options
| -rw-r--r-- | client/internal.h | 9 | ||||
| -rw-r--r-- | client/remctl.c | 45 | ||||
| -rw-r--r-- | client/wallet.c | 8 | ||||
| -rw-r--r-- | client/wallet.pod | 8 | ||||
| -rw-r--r-- | tests/client/basic-t.in | 12 | ||||
| -rwxr-xr-x | tests/data/cmd-fake | 35 | 
6 files changed, 112 insertions, 5 deletions
| diff --git a/client/internal.h b/client/internal.h index 88b0e24..795c58d 100644 --- a/client/internal.h +++ b/client/internal.h @@ -42,6 +42,15 @@ void kinit(krb5_context, const char *principal);  int run_command(struct remctl *, const char **command, char **data,                  size_t *length); +/* Check whether an object exists using the exists wallet interface.  Returns +   true if it does, false if it doesn't, and dies on remctl errors. */ +int object_exists(struct remctl *, const char *prefix, const char *type, +                  const char *name); + +/* Attempt autocreation of an object.  Dies if autocreation fails. */ +void object_autocreate(struct remctl *, const char *prefix, const char *type, +                       const char *name); +  /* Given a remctl object, the type for the wallet interface, object type,     object name, and a file (which may be NULL), send a wallet get command and     write the results to the provided file.  If the file is NULL, write the diff --git a/client/remctl.c b/client/remctl.c index 6d80bf2..aa9a9f8 100644 --- a/client/remctl.c +++ b/client/remctl.c @@ -72,3 +72,48 @@ run_command(struct remctl *r, const char **command, char **data,      } while (output->type != REMCTL_OUT_DONE);      return status;  } + + +/* +**  Check whether an object exists using the exists wallet interface.  Returns +**  true if it does, false if it doesn't, and dies on remctl errors. +*/ +int +object_exists(struct remctl *r, const char *prefix, const char *type, +              const char *name) +{ +    const char *command[5]; +    char *data = NULL; +    size_t length; + +    command[0] = prefix; +    command[1] = "exists"; +    command[2] = type; +    command[3] = name; +    command[4] = NULL; +    if (run_command(r, command, &data, &length) != 0) +        exit(1); +    if (length == 4 && strncmp(data, "yes\n", 4) == 0) +        return 1; +    else +        return 0; +} + + +/* +**  Attempt autocreation of an object.  Dies if autocreation fails. +*/ +void +object_autocreate(struct remctl *r, const char *prefix, const char *type, +                  const char *name) +{ +    const char *command[5]; + +    command[0] = prefix; +    command[1] = "autocreate"; +    command[2] = type; +    command[3] = name; +    command[4] = NULL; +    if (run_command(r, command, NULL, NULL) != 0) +        exit(1); +} diff --git a/client/wallet.c b/client/wallet.c index 8ce7ae0..2e4f755 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -216,8 +216,12 @@ main(int argc, char *argv[])      if (!remctl_open(r, options.server, options.port, options.principal))          die("%s", remctl_error(r)); -    /* Most commands, we handle ourselves, but get commands are special and -       keytab get commands with -f are doubly special. */ +    /* Most commands, we handle ourselves, but get and store commands are +       special and keytab get commands with -f are doubly special. */ +    if (strcmp(argv[0], "get") == 0 || strcmp(argv[0], "store") == 0) { +        if (!object_exists(r, options.type, argv[1], argv[2])) +            object_autocreate(r, options.type, argv[1], argv[2]); +    }      if (strcmp(argv[0], "get") == 0) {          if (argc > 3)              die("too many arguments"); diff --git a/client/wallet.pod b/client/wallet.pod index 10c44ba..3f2ca51 100644 --- a/client/wallet.pod +++ b/client/wallet.pod @@ -261,6 +261,10 @@ by <type> and <name>, or stores it in a file if the B<-f> option was  given.  This may trigger generation of new data and invalidate old data  for that object depending on the object type. +If an object with type <type> and name <name> does not already exist when +this command is issued (as checked with the exists interface), B<wallet> +will attempt to automatically create it (using autocreate). +  =item getacl <type> <name> <acl>  Prints the ACL <acl>, which must be one of C<get>, C<store>, C<show>, @@ -329,6 +333,10 @@ therefore not be binary data, and is limited by the maximum command line  length of the operating system of the wallet server.  These restrictions  will be lifted in the future. +If an object with type <type> and name <name> does not already exist when +this command is issued (as checked with the exists interface), B<wallet> +will attempt to automatically create it (using autocreate). +  =back  =head1 ATTRIBUTES diff --git a/tests/client/basic-t.in b/tests/client/basic-t.in index 807d9e9..67d7a3a 100644 --- a/tests/client/basic-t.in +++ b/tests/client/basic-t.in @@ -12,7 +12,7 @@  . "@abs_top_srcdir@/tests/libtest.sh"  # Print the number of tests. -total=30 +total=31  count=1  echo "$total" @@ -78,7 +78,8 @@ if [ -z "$krb5conf" ] ; then  fi  # Make sure everything's clean. -rm -f output output.bak keytab keytab.bak srvtab srvtab.bak sync-kaserver +rm -f output output.bak keytab keytab.bak srvtab srvtab.bak sync-kaserver \ +    autocreated  # Now, we can finally run our tests.  First, basic operations.  runsuccess "" "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet \ @@ -93,6 +94,11 @@ if [ -f output.bak ] || [ -f output.new ] ; then  else      printcount "ok"  fi +if [ -f autocreated ] ; then +    printcount "ok" +else +    printcount "not ok" +fi  runsuccess "" "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet \      -f output get file fake-test  if cmp output data/fake-data >/dev/null 2>&1 ; then @@ -220,7 +226,7 @@ runsuccess "Expiration date of keytab service/fake-test" \  # Clean up.  KRB5_CONFIG=  rm krb5.conf -rm -f data/test.cache +rm -f autocreated data/test.cache  if [ -f data/pid ] ; then      kill `cat data/pid`      rm -f data/pid diff --git a/tests/data/cmd-fake b/tests/data/cmd-fake index a8d979a..17bbb90 100755 --- a/tests/data/cmd-fake +++ b/tests/data/cmd-fake @@ -67,6 +67,41 @@ setattr)          ;;      esac      ;; +exists) +    if [ -n "$2" ] ; then +        echo "Too many arguments" >&2 +        exit 1 +    fi +    case "${type}:${1}" in +    file:fake-test) +        if [ -f autocreated ] ; then +            echo 'yes' +        else +            echo 'no' +        fi +        ;; +    *) +        echo 'yes' +        ;; +    esac +    exit 0 +    ;; +autocreate) +    if [ -n "$2" ] ; then +        echo "Too many arguments" >&2 +        exit 1 +    fi +    case "${type}:${1}" in +    file:fake-test) +        touch autocreated +        exit 0 +        ;; +    *) +        echo "Autocreate called for existing object" >&2 +        exit 1 +        ;; +    esac +    ;;  get)      if [ -n "$2" ] ; then          echo "Too many arguments" >&2 | 
