* Makefile.in, configure.in: break out client lib into a
authorTom Yu <tlyu@mit.edu>
Wed, 24 Jul 1996 22:22:49 +0000 (22:22 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 24 Jul 1996 22:22:49 +0000 (22:22 +0000)
subdirectory

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@8805 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/kadm5/clnt/ChangeLog [new file with mode: 0644]
src/lib/kadm5/clnt/Makefile.in [new file with mode: 0644]
src/lib/kadm5/clnt/client_handle.c [new file with mode: 0644]
src/lib/kadm5/clnt/client_init.c [new file with mode: 0644]
src/lib/kadm5/clnt/client_internal.h [new file with mode: 0644]
src/lib/kadm5/clnt/client_principal.c [new file with mode: 0644]
src/lib/kadm5/clnt/client_rpc.c [new file with mode: 0644]
src/lib/kadm5/clnt/clnt_chpass_util.c [new file with mode: 0644]
src/lib/kadm5/clnt/clnt_policy.c [new file with mode: 0644]
src/lib/kadm5/clnt/clnt_privs.c [new file with mode: 0644]
src/lib/kadm5/clnt/configure.in [new file with mode: 0644]

diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog
new file mode 100644 (file)
index 0000000..cc4e44b
--- /dev/null
@@ -0,0 +1,5 @@
+Wed Jul 24 18:20:47 1996  Tom Yu  <tlyu@voltage-multiplier.mit.edu>
+
+       * Makefile.in, configure.in: break out client lib into a
+               subdirectory
+
diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in
new file mode 100644 (file)
index 0000000..743ca39
--- /dev/null
@@ -0,0 +1,79 @@
+CFLAGS = $(CCOPTS) $(DEFS) -I$(BUILDTOP)/include/kadm5
+
+##DOSBUILDTOP = ..\..\..
+##DOSLIBNAME = libkadm5clnt.lib
+
+.c.o:
+       $(CC) $(CFLAGS) -c $(srcdir)/$*.c
+@SHARED_RULE@
+
+SRCS = $(srcdir)/clnt_policy.c \
+       $(srcdir)/client_rpc.c \
+       $(srcdir)/client_principal.c \
+       $(srcdir)/client_init.c \
+       $(srcdir)/clnt_privs.c \
+       $(srcdir)/clnt_chpass_util.c
+
+OBJS = @LIBOBJS@ \
+       clnt_policy.$(OBJEXT) \
+       client_rpc.$(OBJEXT) \
+       client_principal.$(OBJEXT) \
+       client_init.$(OBJEXT) \
+       clnt_privs.$(OBJEXT) \
+       clnt_chpass_util.$(OBJEXT)
+
+LIBUPDATE=$(BUILDTOP)/util/libupdate
+
+#
+# Depends on libgssrpc, libgssapi_krb5, libkdb5, libkrb5, libcrypto,
+# libcom_err, libdyn
+#
+GSSRPC_VER=@GSSRPC_SH_VERS@
+GSSAPI_KRB5_VER=@GSSAPI_KRB5_SH_VERS@
+KDB5_VER=@KDB5_SH_VERS@
+KRB5_VER=@KRB5_SH_VERS@
+CRYPTO_VER=@CRYPTO_SH_VERS@
+COMERR_VER=@COMERR_SH_VERS@
+DYN_VER=@DYN_SH_VERS@
+DEPLIBS=$(TOPLIBD)/libgssrpc.$(SHEXT).$(GSSRPC_VER) \
+       $(TOPLIBD)/libgssapi_krb5.$(SHEXT).$(GSSAPI_KRB5_VER) \
+       $(TOPLIBD)/libkdb5.$(SHEXT).$(KDB5_VER) \
+       $(TOPLIBD)/libkrb5.$(SHEXT).$(KRB5_VER) \
+       $(TOPLIBD)/libcrypto.$(SHEXT).$(CRYPTO_VER) \
+       $(TOPLIBD)/libcom_err.$(SHEXT).$(COMERR_VER) \
+       $(TOPLIBD)/libdyn.$(SHEXT).$(DYN_VER)
+
+SHLIB_LIBS=-lgssrpc -lgssapi_krb5 -lkdb5 -lkrb5 -lcrypto -lcom_err -ldyn
+SHLIB_LDFLAGS= $(LDFLAGS) @SHLIB_RPATH_DIRS@
+SHLIB_LIBDIRS= @SHLIB_LIBDIRS@
+
+all-unix:: shared includes $(OBJS)
+all-mac:: $(OBJS)
+all-windows:: $(OBJS)
+
+LIBDONE=../DONE DONE
+LIB_SUBDIRS=.. .
+
+shared:
+       mkdir shared
+
+libkadm5clnt.$(STEXT): $(LIBDONE)
+       @if test -f $@ ; then \
+               (set -x; $(LIBUPDATE) $@ DONE $(LIB_SUBDIRS)) \
+       else \
+               (set -x; $(LIBUPDATE) --force $@ DONE $(LIB_SUBDIRS)) \
+       fi
+       $(RANLIB) $@
+       touch libkadm5clnt.stamp
+
+check-windows::
+
+clean-mac::
+clean-windows::
+
+clean-unix::
+       $(RM) libkadm5clnt.$(STEXT) libkadm5clnt.stamp
+
+install:: libkadm5clnt.a
+       $(INSTALL_DATA) libkadm5clnt.a $(DESTDIR)$(KRB5_LIBDIR)/libkadm5clnt.a
+       $(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/libkadm5clnt.a
diff --git a/src/lib/kadm5/clnt/client_handle.c b/src/lib/kadm5/clnt/client_handle.c
new file mode 100644 (file)
index 0000000..895777a
--- /dev/null
@@ -0,0 +1,9 @@
+#include <krb5.h>
+#include <kadm5/admin.h>
+#include "client_internal.h"
+
+int _kadm5_check_handle(void *handle)
+{
+     CHECK_HANDLE(handle);
+     return 0;
+}
diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c
new file mode 100644 (file)
index 0000000..bfc1c3a
--- /dev/null
@@ -0,0 +1,554 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ */
+
+#if !defined(lint) && !defined(__CODECENTER__)
+static char *rcsid = "$Header$";
+#endif
+
+#include <stdio.h>
+#include <netdb.h>
+#include <memory.h>
+#include <string.h>
+#include <com_err.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <krb5.h>
+#include <k5-int.h> /* for KRB5_ADM_DEFAULT_PORT */
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+#include <kadm5/admin.h>
+#include <kadm5/kadm_rpc.h>
+#include "client_internal.h"
+
+#include <rpc/rpc.h>
+#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_krb5.h>
+#include <rpc/auth_gssapi.h>
+
+#define        ADM_CCACHE  "/tmp/ovsec_adm.XXXXXX"
+
+#ifndef _POSIX_SOURCE /* Perhaps this should actually say __STDC__ */
+int    setenv(const char *var, const char *val, int flag);
+void   unsetenv(const char *var);
+#endif
+
+enum init_type { INIT_PASS, INIT_SKEY, INIT_CREDS };
+
+static kadm5_ret_t _kadm5_init_any(char *client_name,
+                                  enum init_type init_type,
+                                  char *pass,
+                                  krb5_ccache ccache_in,
+                                  char *service_name,
+                                  kadm5_config_params *params,
+                                  krb5_ui_4 struct_version,
+                                  krb5_ui_4 api_version,
+                                  void **server_handle);
+
+kadm5_ret_t kadm5_init_with_creds(char *client_name,
+                                 krb5_ccache ccache,
+                                 char *service_name,
+                                 kadm5_config_params *params,
+                                 krb5_ui_4 struct_version,
+                                 krb5_ui_4 api_version,
+                                 void **server_handle)
+{
+     return _kadm5_init_any(client_name, INIT_CREDS, NULL, ccache,
+                           service_name, params,
+                           struct_version, api_version,
+                           server_handle);
+}
+
+
+kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass,
+                                    char *service_name,
+                                    kadm5_config_params *params,
+                                    krb5_ui_4 struct_version,
+                                    krb5_ui_4 api_version,
+                                    void **server_handle)
+{
+     return _kadm5_init_any(client_name, INIT_PASS, pass, NULL,
+                           service_name, params, struct_version,
+                           api_version, server_handle);
+}
+
+kadm5_ret_t kadm5_init(char *client_name, char *pass,
+                      char *service_name, 
+                      kadm5_config_params *params,
+                      krb5_ui_4 struct_version,
+                      krb5_ui_4 api_version,
+                      void **server_handle)
+{
+     return _kadm5_init_any(client_name, INIT_PASS, pass, NULL,
+                           service_name, params, struct_version,
+                           api_version, server_handle);
+}
+
+kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab,
+                                char *service_name,
+                                kadm5_config_params *params,
+                                krb5_ui_4 struct_version,
+                                krb5_ui_4 api_version,
+                                void **server_handle)
+{
+     return _kadm5_init_any(client_name, INIT_SKEY, keytab, NULL,
+                           service_name, params, struct_version,
+                           api_version, server_handle);
+}
+
+/*
+ * Try no preauthentication first; then try the encrypted timestamp
+ * (stolen from krb5 kinit.c)
+ */
+static int preauth_search_list[] = {
+     0,                        
+     KRB5_PADATA_ENC_UNIX_TIME,
+     -1
+};
+
+static kadm5_ret_t _kadm5_init_any(char *client_name,
+                                  enum init_type init_type,
+                                  char *pass,
+                                  krb5_ccache ccache_in,
+                                  char *service_name,
+                                  kadm5_config_params *params_in,
+                                  krb5_ui_4 struct_version,
+                                  krb5_ui_4 api_version,
+                                  void **server_handle)
+{
+     struct sockaddr_in addr;
+     struct hostent *hp;
+     struct servent *srv;
+     int fd;
+     int i;
+
+     char full_service_name[BUFSIZ], host[MAXHOSTNAMELEN], *ccname_orig;
+     char *realm;
+     krb5_creds        creds;
+     krb5_ccache ccache = NULL;
+     krb5_timestamp  now;
+     
+     OM_uint32 gssstat, minor_stat;
+     gss_buffer_desc input_name;
+     gss_name_t gss_target, gss_client;
+     gss_cred_id_t gss_client_creds = GSS_C_NO_CREDENTIAL;
+
+     kadm5_server_handle_t handle;
+     kadm5_config_params params_local;
+
+     int code = 0;
+     generic_ret *r;
+
+     initialize_ovk_error_table();
+     initialize_adb_error_table();
+     initialize_ovku_error_table();
+     
+     if (! server_handle) {
+        return EINVAL;
+     }
+
+     if (! (handle = malloc(sizeof(*handle)))) {
+         return ENOMEM;
+     }
+     if (! (handle->lhandle = malloc(sizeof(*handle)))) {
+         free(handle);
+         return ENOMEM;
+     }
+
+     handle->magic_number = KADM5_SERVER_HANDLE_MAGIC;
+     handle->struct_version = struct_version;
+     handle->api_version = api_version;
+     handle->clnt = 0;
+     handle->cache_name = 0;
+     handle->destroy_cache = 0;
+     *handle->lhandle = *handle;
+     handle->lhandle->api_version = KADM5_API_VERSION_2;
+     handle->lhandle->struct_version = KADM5_STRUCT_VERSION;
+     handle->lhandle->lhandle = handle->lhandle;
+
+     krb5_init_context(&handle->context);
+     krb5_init_ets(handle->context);   
+
+     if(service_name == NULL || client_name == NULL) {
+       free(handle);
+       return EINVAL;
+     }
+     memset((char *) &creds, 0, sizeof(creds));
+
+     /*
+      * Verify the version numbers before proceeding; we can't use
+      * CHECK_HANDLE because not all fields are set yet.
+      */
+     GENERIC_CHECK_HANDLE(handle, KADM5_OLD_LIB_API_VERSION,
+                         KADM5_NEW_LIB_API_VERSION);
+     
+     /*
+      * Acquire relevant profile entries.  In version 2, merge values
+      * in params_in with values from profile, based on
+      * params_in->mask.
+      *
+      * In version 1, we've given a realm (which may be NULL) instead
+      * of params_in.  So use that realm, make params_in contain an
+      * empty mask, and behave like version 2.
+      */
+     memset((char *) &params_local, 0, sizeof(params_local));
+     if (api_version == KADM5_API_VERSION_1) {
+         realm = params_local.realm = (char *) params_in;
+         if (params_in)
+              params_local.mask = KADM5_CONFIG_REALM;
+         params_in = &params_local;
+     } else {
+         if (params_in && (params_in->mask & KADM5_CONFIG_REALM))
+              realm = params_in->realm;
+         else
+              realm = NULL;
+     }
+
+#define ILLEGAL_PARAMS (KADM5_CONFIG_DBNAME | KADM5_CONFIG_ADBNAME | \
+                       KADM5_CONFIG_ADB_LOCKFILE | \
+                       KADM5_CONFIG_ACL_FILE | KADM5_CONFIG_DICT_FILE \
+                       | KADM5_CONFIG_ADMIN_KEYTAB | \
+                       KADM5_CONFIG_STASH_FILE | \
+                       KADM5_CONFIG_MKEY_NAME | KADM5_CONFIG_ENCTYPE \
+                       | KADM5_CONFIG_MAX_LIFE | \
+                       KADM5_CONFIG_MAX_RLIFE | \
+                       KADM5_CONFIG_EXPIRATION | KADM5_CONFIG_FLAGS | \
+                       KADM5_CONFIG_ENCTYPES | KADM5_CONFIG_MKEY_FROM_KBD)
+
+     if (params_in && params_in->mask & ILLEGAL_PARAMS) {
+         free(handle);
+         return KADM5_BAD_CLIENT_PARAMS;
+     }
+                       
+     if (code = kadm5_get_config_params(handle->context,
+                                       "/etc/krb5.conf",
+                                       "KRB5_CONFIG",
+                                       params_in,
+                                       &handle->params)) {
+         krb5_free_context(handle->context);
+         free(handle);
+         return(code);
+     }
+
+#define REQUIRED_PARAMS (KADM5_CONFIG_REALM | \
+                        KADM5_CONFIG_ADMIN_SERVER | \
+                        KADM5_CONFIG_KADMIND_PORT) 
+
+     if ((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
+         krb5_free_context(handle->context);
+         free(handle);
+         return KRB5_CONFIG_BADFORMAT;
+     }
+     
+     /*
+      * Acquire a service ticket for service_name@realm in the name of
+      * client_name, using password pass (which could be NULL), and
+      * create a ccache to store them in.  If INIT_CREDS, use the
+      * ccache we were provided instead.
+      */
+     
+     if ((code = krb5_parse_name(handle->context, client_name, &creds.client)))
+         goto error;
+
+     if (realm) {
+         sprintf(full_service_name, "%s@%s", service_name, realm);
+     } else {
+         /* krb5_princ_realm(creds.client) is not null terminated */
+         strcpy(full_service_name, service_name);
+         strcat(full_service_name, "@");
+         strncat(full_service_name, krb5_princ_realm(handle->context,
+                                                     creds.client)->data, 
+                 krb5_princ_realm(handle->context, creds.client)->length);
+     }
+     
+     if ((code = krb5_parse_name(handle->context, full_service_name,
+         &creds.server))) 
+         goto error;
+
+     /* XXX temporarily fix a bug in krb5_cc_get_type */
+#undef krb5_cc_get_type
+#define krb5_cc_get_type(context, cache) ((cache)->ops->prefix)
+     
+
+     if (init_type == INIT_CREDS) {
+         ccache = ccache_in;
+         handle->cache_name = (char *)
+              malloc(strlen(krb5_cc_get_type(handle->context, ccache)) +
+                     strlen(krb5_cc_get_name(handle->context, ccache)) + 2);
+         if (handle->cache_name == NULL) {
+              code = ENOMEM;
+              goto error;
+         }
+         sprintf(handle->cache_name, "%s:%s",
+                 krb5_cc_get_type(handle->context, ccache),
+                 krb5_cc_get_name(handle->context, ccache));
+     } else {
+         handle->cache_name =
+              (char *) malloc(strlen(ADM_CCACHE)+strlen("FILE:")+1);
+         if (handle->cache_name == NULL) {
+              code = ENOMEM;
+              goto error;
+         }
+         sprintf(handle->cache_name, "FILE:%s", ADM_CCACHE);
+         mktemp(handle->cache_name + strlen("FILE:"));
+     
+         if ((code = krb5_cc_resolve(handle->context, handle->cache_name,
+                                     &ccache))) 
+              goto error;
+         
+         if ((code = krb5_cc_initialize (handle->context, ccache,
+                                         creds.client))) 
+              goto error;
+
+         handle->destroy_cache = 1;
+     }
+     handle->lhandle->cache_name = handle->cache_name;
+     
+     if ((code = krb5_timeofday(handle->context, &now)))
+         goto error;
+
+     /*
+      * Get a ticket, use the method specified in init_type.
+      */
+     
+     creds.times.starttime = 0; /* start timer at KDC */
+     creds.times.endtime = 0; /* endtime will be limited by service */
+
+     if (init_type == INIT_PASS) {
+         for (i=0; preauth_search_list[i] >= 0; i++) {
+              code = krb5_get_in_tkt_with_password(handle->context,
+                                                   0, /* no options */
+                                                   0, /* default addresses */
+                                                   NULL,
+                                                   NULL, /* XXX preauth */
+                                                   pass,
+                                                   ccache,
+                                                   &creds,
+                                                   NULL);
+              if (code != KRB5KDC_ERR_PREAUTH_FAILED &&
+                  code != KRB5KDC_ERR_PREAUTH_REQUIRED &&
+                  code != KRB5KRB_ERR_GENERIC)
+                   break;
+         }
+     } else if (init_type == INIT_SKEY) {
+         krb5_keytab kt = NULL;
+
+         if (pass && (code = krb5_kt_resolve(handle->context, pass, &kt)))
+              ;
+         else {
+              for (i=0; preauth_search_list[i] >= 0; i++) {
+                   code = krb5_get_in_tkt_with_keytab(handle->context,
+                                                      0, /* no options */
+                                                      0, /* default addrs */
+                                                      NULL,
+                                                      NULL, /* XXX preauth */
+                                                      kt,
+                                                      ccache,
+                                                      &creds,
+                                                      NULL);
+                   if (code != KRB5KDC_ERR_PREAUTH_FAILED &&
+                       code != KRB5KDC_ERR_PREAUTH_REQUIRED &&
+                       code != KRB5KRB_ERR_GENERIC)
+                        break;
+              }
+
+              if (pass) krb5_kt_close(handle->context, kt);
+         }
+     }
+
+     /* Improved error messages */
+     if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) code = KADM5_BAD_PASSWORD;
+     if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
+         code = KADM5_SECURE_PRINC_MISSING;
+
+     if (code != 0) goto error;
+
+#ifdef ZEROPASSWD
+     if (pass != NULL)
+         memset(pass, 0, strlen(pass));
+#endif
+
+     /*
+      * We have ticket; open the RPC connection.
+      */
+
+     hp = gethostbyname(handle->params.admin_server);
+     if (hp == (struct hostent *) NULL) {
+         code = KRB5_CONFIG_BADFORMAT;
+         goto cleanup;
+     }
+
+     memset(&addr, 0, sizeof(addr));
+     addr.sin_family = hp->h_addrtype;
+     (void) memcpy((char *) &addr.sin_addr, (char *) hp->h_addr,
+                  sizeof(addr.sin_addr));
+     addr.sin_port = htons((u_short) handle->params.kadmind_port);
+     
+     fd = RPC_ANYSOCK;
+     
+     handle->clnt = clnttcp_create(&addr, KADM, KADMVERS, &fd, 0, 0);
+     if (handle->clnt == NULL) {
+         code = KADM5_RPC_ERROR;
+         goto error;
+     }
+     handle->lhandle->clnt = handle->clnt;
+
+     /* now that handle->clnt is set, we can check the handle */
+     if (code = _kadm5_check_handle((void *) handle))
+         goto error;
+
+     /*
+      * The RPC connection is open; establish the GSS-API
+      * authentication context.
+      */
+
+     /* use the kadm5 cache */
+     ccname_orig = getenv("KRB5CCNAME");
+     if (ccname_orig)
+         ccname_orig = strdup(ccname_orig);
+     
+     (void) setenv("KRB5CCNAME", handle->cache_name, 1);
+
+#ifndef INIT_TEST
+     input_name.value = full_service_name;
+     input_name.length = strlen((char *)input_name.value) + 1;
+     gssstat = gss_import_name(&minor_stat, &input_name,
+                              gss_nt_krb5_name, &gss_target);
+     if (gssstat != GSS_S_COMPLETE) {
+         code = KADM5_GSS_ERROR;
+         goto error;
+     }
+#endif /* ! INIT_TEST */
+
+     input_name.value = client_name;
+     input_name.length = strlen((char *)input_name.value) + 1;
+     gssstat = gss_import_name(&minor_stat, &input_name,
+                              gss_nt_krb5_name, &gss_client);
+     if (gssstat != GSS_S_COMPLETE) {
+         code = KADM5_GSS_ERROR;
+         goto error;
+     }
+
+     gssstat = gss_acquire_cred(&minor_stat, gss_client, 0,
+                               GSS_C_NULL_OID_SET, GSS_C_INITIATE,
+                               &gss_client_creds, NULL, NULL);
+     (void) gss_release_name(&minor_stat, &gss_client);
+     if (gssstat != GSS_S_COMPLETE) {
+         code = KADM5_GSS_ERROR;
+         goto error;
+     }
+     
+#ifndef INIT_TEST
+     handle->clnt->cl_auth = auth_gssapi_create(handle->clnt,
+                                       &gssstat,
+                                       &minor_stat,
+                                       gss_client_creds,
+                                       gss_target,
+                                       GSS_C_NULL_OID,
+                                       GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       NULL);
+     (void) gss_release_name(&minor_stat, &gss_target);
+#endif /* ! INIT_TEST */
+
+     if (ccname_orig) {
+         (void) setenv("KRB5CCNAME", ccname_orig, 1);
+         free(ccname_orig);
+     } else
+         (void) unsetenv("KRB5CCNAME");
+
+     
+     if (handle->clnt->cl_auth == NULL) {
+         code = KADM5_GSS_ERROR;
+         goto error;
+     }
+
+     r = init_1(&handle->api_version, handle->clnt);
+     if (r == NULL) {
+         code = KADM5_RPC_ERROR;
+         goto error;
+     }
+     if (r->code) {
+         code = r->code;
+         goto error;
+     }
+
+     *server_handle = (void *) handle;
+
+     if (init_type != INIT_CREDS) 
+         krb5_cc_close(handle->context, ccache);
+
+     goto cleanup;
+     
+error:
+     /*
+      * Note that it is illegal for this code to execute if "handle"
+      * has not been allocated and initialized.  I.e., don't use "goto
+      * error" before the block of code at the top of the function
+      * that allocates and initializes "handle".
+      */
+     if (handle->cache_name)
+        free(handle->cache_name);
+     if (handle->destroy_cache && ccache)
+        krb5_cc_destroy(handle->context, ccache);
+     if(handle->clnt && handle->clnt->cl_auth)
+         AUTH_DESTROY(handle->clnt->cl_auth);
+     if(handle->clnt)
+         clnt_destroy(handle->clnt);
+
+cleanup:
+     krb5_free_cred_contents(handle->context, &creds);
+     if (gss_client_creds != GSS_C_NO_CREDENTIAL)
+         (void) gss_release_cred(&minor_stat, &gss_client_creds);
+
+     if (code)
+         free(handle);
+
+     return code;
+}
+
+kadm5_ret_t
+kadm5_destroy(void *server_handle)
+{
+     krb5_ccache           ccache = NULL;
+     int                   code = KADM5_OK;
+     kadm5_server_handle_t     handle =
+         (kadm5_server_handle_t) server_handle;
+
+     CHECK_HANDLE(server_handle);
+
+     if (handle->destroy_cache && handle->cache_name) {
+        if ((code = krb5_cc_resolve(handle->context,
+                                    handle->cache_name, &ccache)) == 0) 
+            code = krb5_cc_destroy (handle->context, ccache);
+     }
+     if (handle->cache_name)
+        free(handle->cache_name);
+     if (handle->clnt && handle->clnt->cl_auth)
+         AUTH_DESTROY(handle->clnt->cl_auth);
+     if (handle->clnt)
+         clnt_destroy(handle->clnt);
+
+     handle->magic_number = 0;
+     free(handle);
+
+     return code;
+}
+
+kadm5_ret_t kadm5_flush(void *server_handle)
+{
+     return KADM5_OK;
+}
+
+int _kadm5_check_handle(void *handle)
+{
+     CHECK_HANDLE(handle);
+     return 0;
+}
diff --git a/src/lib/kadm5/clnt/client_internal.h b/src/lib/kadm5/clnt/client_internal.h
new file mode 100644 (file)
index 0000000..c5ebfec
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ * 
+ * $Log$
+ * Revision 1.1  1996/07/24 22:22:43  tlyu
+ *     * Makefile.in, configure.in: break out client lib into a
+ *             subdirectory
+ *
+ * Revision 1.11  1996/07/22 20:35:46  marc
+ * this commit includes all the changes on the OV_9510_INTEGRATION and
+ * OV_MERGE branches.  This includes, but is not limited to, the new openvision
+ * admin system, and major changes to gssapi to add functionality, and bring
+ * the implementation in line with rfc1964.  before committing, the
+ * code was built and tested for netbsd and solaris.
+ *
+ * Revision 1.10.4.1  1996/07/18 03:08:37  marc
+ * merged in changes from OV_9510_BP to OV_9510_FINAL1
+ *
+ * Revision 1.10.2.1  1996/06/20  02:16:46  marc
+ * File added to the repository on a branch
+ *
+ * Revision 1.10  1996/06/06  20:09:16  bjaspan
+ * add destroy_cache, for kadm5_init_with_creds
+ *
+ * Revision 1.9  1996/05/30 21:04:42  bjaspan
+ * add lhandle to handle
+ *
+ * Revision 1.8  1996/05/28 20:33:49  bjaspan
+ * rework kadm5_config
+ *
+ * Revision 1.7  1996/05/17 21:36:59  bjaspan
+ * rename to kadm5, begin implementing version 2
+ *
+ * Revision 1.6  1996/05/16 21:45:07  bjaspan
+ * add context
+ *
+ * Revision 1.5  1996/05/08 21:10:23  bjaspan
+ * marc's changes
+ *
+ * Revision 1.4  1996/01/16  20:54:30  grier
+ * secure/3570 use krb5_ui_4 not unsigned int
+ *
+ * Revision 1.3  1995/11/14  17:48:57  grier
+ * long to int
+ *
+ * Revision 1.2  1994/08/16  18:53:47  jik
+ * Versioning stuff.
+ *
+ * Revision 1.1  1994/08/09  21:14:38  jik
+ * Initial revision
+ *
+ */
+
+/*
+ * This header file is used internally by the Admin API client
+ * libraries.  IF YOU THINK YOU NEED TO USE THIS FILE FOR ANYTHING,
+ * YOU'RE ALMOST CERTAINLY WRONG.
+ */
+
+#ifndef __KADM5_CLIENT_INTERNAL_H__
+#define __KADM5_CLIENT_INTERNAL_H__
+
+#include "admin_internal.h"
+
+typedef struct _kadm5_server_handle_t {
+       krb5_ui_4       magic_number;
+       krb5_ui_4       struct_version;
+       krb5_ui_4       api_version;
+       char *          cache_name;
+       int             destroy_cache;
+       CLIENT *        clnt;
+       krb5_context    context;
+       kadm5_config_params params;
+       struct _kadm5_server_handle_t *lhandle;
+} kadm5_server_handle_rec, *kadm5_server_handle_t;
+
+#define CLIENT_CHECK_HANDLE(handle) \
+{ \
+       kadm5_server_handle_t srvr = \
+            (kadm5_server_handle_t) handle; \
+ \
+       if (! srvr->clnt) \
+            return KADM5_BAD_SERVER_HANDLE; \
+       if (! srvr->cache_name) \
+            return KADM5_BAD_SERVER_HANDLE; \
+       if (! srvr->lhandle) \
+            return KADM5_BAD_SERVER_HANDLE; \
+}
+
+#define CHECK_HANDLE(handle) \
+     GENERIC_CHECK_HANDLE(handle, KADM5_OLD_LIB_API_VERSION, \
+                         KADM5_NEW_LIB_API_VERSION) \
+     CLIENT_CHECK_HANDLE(handle)
+
+#endif /* __KADM5_CLIENT_INTERNAL_H__ */
diff --git a/src/lib/kadm5/clnt/client_principal.c b/src/lib/kadm5/clnt/client_principal.c
new file mode 100644 (file)
index 0000000..c419227
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ */
+
+#if !defined(lint) && !defined(__CODECENTER__)
+static char *rcsid = "$Header$";
+#endif
+
+#include    <rpc/rpc.h>
+#include    <kadm5/admin.h>
+#include    <kadm5/kadm_rpc.h>
+#include    <memory.h>
+#include    "client_internal.h"
+
+kadm5_ret_t
+kadm5_create_principal(void *server_handle,
+                           kadm5_principal_ent_t princ, long mask,
+                           char *pw)
+{
+    generic_ret                *r;
+    cprinc_arg         arg;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+
+    arg.mask = mask;
+    arg.passwd = pw;
+    arg.api_version = handle->api_version;
+
+    if(princ == NULL)
+       return EINVAL;
+    memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
+    if (handle->api_version == KADM5_API_VERSION_1) {
+        /*
+         * hack hack cough cough.
+         * krb5_unparse name dumps core if we pass it in garbage
+         * or null. So, since the client is not allowed to set mod_name
+         * anyway, we just fill it in with a dummy principal. The server of
+         * course ignores this.
+         */
+        krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name);
+    } else
+        arg.rec.mod_name = NULL;
+    
+    if(!(mask & KADM5_POLICY))
+       arg.rec.policy = NULL;
+    if (! (mask & KADM5_KEY_DATA)) {
+        arg.rec.n_key_data = 0;
+        arg.rec.key_data = NULL;
+    }
+    if (! (mask & KADM5_TL_DATA)) {
+        arg.rec.n_tl_data = 0;
+        arg.rec.tl_data = NULL;
+    }
+        
+    r = create_principal_1(&arg, handle->clnt);
+
+    if (handle->api_version == KADM5_API_VERSION_1)
+        krb5_free_principal(handle->context, arg.rec.mod_name);
+
+    if(r == NULL)
+       return KADM5_RPC_ERROR;
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_delete_principal(void *server_handle, krb5_principal principal)
+{
+    dprinc_arg         arg;
+    generic_ret                *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+
+    if(principal == NULL)
+       return EINVAL;
+    arg.princ = principal;
+    arg.api_version = handle->api_version;
+    r = delete_principal_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;    
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_modify_principal(void *server_handle,
+                           kadm5_principal_ent_t princ, long mask)
+{
+    mprinc_arg         arg;
+    generic_ret                *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+
+    arg.mask = mask;
+    arg.api_version = handle->api_version;
+    /*
+     * cough cough gag gag
+     * see comment in create_principal.
+     */
+    if(princ == NULL)
+       return EINVAL;
+    memcpy(&arg.rec, princ, sizeof(kadm5_principal_ent_rec));
+    if(!(mask & KADM5_POLICY))
+       arg.rec.policy = NULL;
+    if (! (mask & KADM5_KEY_DATA)) {
+        arg.rec.n_key_data = 0;
+        arg.rec.key_data = NULL;
+    }
+    if (! (mask & KADM5_TL_DATA)) {
+        arg.rec.n_tl_data = 0;
+        arg.rec.tl_data = NULL;
+    }
+
+    if (handle->api_version == KADM5_API_VERSION_1) {
+        /*
+         * See comment in create_principal
+         */
+        krb5_parse_name(handle->context, "bogus/bogus", &arg.rec.mod_name);
+    } else
+        arg.rec.mod_name = NULL;
+    
+    r = modify_principal_1(&arg, handle->clnt);
+
+    if (handle->api_version == KADM5_API_VERSION_1)
+        krb5_free_principal(handle->context, arg.rec.mod_name);    
+
+    if(r == NULL)
+       return KADM5_RPC_ERROR;    
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_get_principal(void *server_handle,
+                   krb5_principal princ, kadm5_principal_ent_t ent,
+                   long mask)
+{
+    gprinc_arg arg;
+    gprinc_ret *r;
+    kadm5_server_handle_t handle = server_handle;
+    krb5_error_code retval;
+
+    CHECK_HANDLE(server_handle);
+
+    if(princ == NULL)
+       return EINVAL;
+    arg.princ = princ;
+    if (handle->api_version == KADM5_API_VERSION_1)
+       arg.mask = KADM5_PRINCIPAL_NORMAL_MASK;
+    else
+       arg.mask = mask;
+    arg.api_version = handle->api_version;
+    r = get_principal_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;
+    if (handle->api_version == KADM5_API_VERSION_1) {
+        kadm5_principal_ent_t_v1 *entp;
+
+        entp = (kadm5_principal_ent_t_v1 *) ent;
+        if (r->code == 0) {
+             if (!(*entp = (kadm5_principal_ent_t_v1)
+                   malloc(sizeof(kadm5_principal_ent_rec_v1))))
+                  return ENOMEM;
+             /* this memcpy works because the v1 structure is an initial
+                subset of the v2 struct.  C guarantees that this will
+                result in the same layout in memory */
+             memcpy(*entp, &r->rec, sizeof(**entp));
+        } else {
+           *entp = NULL;
+        }
+    } else {
+        if (r->code == 0)
+             memcpy(ent, &r->rec, sizeof(r->rec));
+    }
+    
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_get_principals(void *server_handle,
+                         char *exp, char ***princs, int *count)
+{
+    gprincs_arg        arg;
+    gprincs_ret        *r;
+    kadm5_server_handle_t handle = server_handle;
+    krb5_error_code retval;
+
+    CHECK_HANDLE(server_handle);
+
+    if(princs == NULL || count == NULL)
+       return EINVAL;
+    arg.exp = exp;
+    arg.api_version = handle->api_version;
+    r = get_princs_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;
+    if(r->code == 0) {
+        *count = r->count;
+        *princs = r->princs;
+    } else {
+        *count = 0;
+        *princs = NULL;
+    }
+    
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_rename_principal(void *server_handle,
+                           krb5_principal source, krb5_principal dest)
+{
+    rprinc_arg         arg;
+    generic_ret                *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+
+    arg.src = source;
+    arg.dest = dest;
+    arg.api_version = handle->api_version;
+    if (source == NULL || dest == NULL)
+       return EINVAL;
+    r = rename_principal_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;        
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_chpass_principal(void *server_handle,
+                           krb5_principal princ, char *password)
+{
+    chpass_arg         arg;
+    generic_ret                *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+
+    arg.princ = princ;
+    arg.pass = password;
+    arg.api_version = handle->api_version;
+
+    if(princ == NULL)
+       return EINVAL;
+    r = chpass_principal_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;        
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_randkey_principal(void *server_handle,
+                       krb5_principal princ,
+                       krb5_keyblock **key, int *n_keys)
+{
+    chrand_arg         arg;
+    chrand_ret         *r;
+    krb5_keyblock      new;
+    kadm5_server_handle_t handle = server_handle;
+    int                        i, ret;
+
+    CHECK_HANDLE(server_handle);
+
+    arg.princ = princ;
+    arg.api_version = handle->api_version;
+
+    if(princ == NULL)
+       return EINVAL;
+    r = chrand_principal_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;
+    if (handle->api_version == KADM5_API_VERSION_1) {
+        if (key)
+             krb5_copy_keyblock(handle->context, &r->key, key);
+    } else {
+        if (n_keys)
+             *n_keys = r->n_keys;
+        if (key) {
+             *key = (krb5_keyblock *) malloc(r->n_keys*sizeof(krb5_keyblock));
+             if (*key == NULL)
+                  return ENOMEM;
+             for (i = 0; i < r->n_keys; i++) {
+                  ret = krb5_copy_keyblock_contents(handle->context,
+                                                    &r->keys[i],
+                                                    &(*key)[i]);
+                  if (ret) {
+                       free(*key);
+                       return ENOMEM;
+                  }
+             }
+        }
+    }
+        
+    return r->code;
+}
+
+/* not supported on client side */
+kadm5_ret_t kadm5_decrypt_key(void *server_handle,
+                             kadm5_principal_ent_t entry, krb5_int32
+                             ktype, krb5_int32 stype, krb5_int32
+                             kvno, krb5_keyblock *keyblock,
+                             krb5_keysalt *keysalt, int *kvnop)
+{
+     return EINVAL;
+}
diff --git a/src/lib/kadm5/clnt/client_rpc.c b/src/lib/kadm5/clnt/client_rpc.c
new file mode 100644 (file)
index 0000000..547844a
--- /dev/null
@@ -0,0 +1,221 @@
+#include <rpc/rpc.h>
+#include <kadm5/kadm_rpc.h>
+#include <krb5.h>
+#include <kadm5/admin.h>
+#include <memory.h>
+
+/* Default timeout can be changed using clnt_control() */
+static struct timeval TIMEOUT = { 25, 0 };
+
+generic_ret *
+create_principal_1(argp, clnt)
+       cprinc_arg *argp;
+       CLIENT *clnt;
+{
+       static generic_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, CREATE_PRINCIPAL, xdr_cprinc_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+generic_ret *
+delete_principal_1(argp, clnt)
+       dprinc_arg *argp;
+       CLIENT *clnt;
+{
+       static generic_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, DELETE_PRINCIPAL, xdr_dprinc_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+generic_ret *
+modify_principal_1(argp, clnt)
+       mprinc_arg *argp;
+       CLIENT *clnt;
+{
+       static generic_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, MODIFY_PRINCIPAL, xdr_mprinc_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+generic_ret *
+rename_principal_1(argp, clnt)
+       rprinc_arg *argp;
+       CLIENT *clnt;
+{
+       static generic_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, RENAME_PRINCIPAL, xdr_rprinc_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+gprinc_ret *
+get_principal_1(argp, clnt)
+       gprinc_arg *argp;
+       CLIENT *clnt;
+{
+       static gprinc_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, GET_PRINCIPAL, xdr_gprinc_arg, argp, xdr_gprinc_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+gprincs_ret *
+get_princs_1(argp, clnt)
+       gprinc_arg *argp;
+       CLIENT *clnt;
+{
+       static gprincs_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, GET_PRINCS, xdr_gprincs_arg, argp,
+                     xdr_gprincs_ret, &res, TIMEOUT) != RPC_SUCCESS) { 
+            return (NULL);
+       }
+       return (&res);
+}
+
+generic_ret *
+chpass_principal_1(argp, clnt)
+       chpass_arg *argp;
+       CLIENT *clnt;
+{
+       static generic_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, CHPASS_PRINCIPAL, xdr_chpass_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+chrand_ret *
+chrand_principal_1(argp, clnt)
+       chrand_arg *argp;
+       CLIENT *clnt;
+{
+       static chrand_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, CHRAND_PRINCIPAL, xdr_chrand_arg, argp, xdr_chrand_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+generic_ret *
+create_policy_1(argp, clnt)
+       cpol_arg *argp;
+       CLIENT *clnt;
+{
+       static generic_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, CREATE_POLICY, xdr_cpol_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+generic_ret *
+delete_policy_1(argp, clnt)
+       dpol_arg *argp;
+       CLIENT *clnt;
+{
+       static generic_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, DELETE_POLICY, xdr_dpol_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+generic_ret *
+modify_policy_1(argp, clnt)
+       mpol_arg *argp;
+       CLIENT *clnt;
+{
+       static generic_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, MODIFY_POLICY, xdr_mpol_arg, argp, xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+gpol_ret *
+get_policy_1(argp, clnt)
+       gpol_arg *argp;
+       CLIENT *clnt;
+{
+       static gpol_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, GET_POLICY, xdr_gpol_arg, argp, xdr_gpol_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+               return (NULL);
+       }
+       return (&res);
+}
+
+gpols_ret *
+get_pols_1(argp, clnt)
+       gprinc_arg *argp;
+       CLIENT *clnt;
+{
+       static gpols_ret res;
+
+       memset((char *)&res, 0, sizeof(res));
+       if (clnt_call(clnt, GET_POLS, xdr_gpols_arg, argp,
+                     xdr_gpols_ret, &res, TIMEOUT) != RPC_SUCCESS) { 
+            return (NULL);
+       }
+       return (&res);
+}
+
+getprivs_ret *get_privs_1(argp, clnt)
+   void *argp;
+   CLIENT *clnt;
+{
+     static getprivs_ret res;
+
+     memset((char *)&res, 0, sizeof(res));
+     if (clnt_call(clnt, GET_PRIVS, xdr_u_int32, argp,
+                  xdr_getprivs_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+         return (NULL);
+     }
+     return (&res);
+}
+
+generic_ret *
+init_1(argp, clnt)
+   void *argp;
+   CLIENT *clnt;
+{
+     static generic_ret res;
+
+     memset((char *)&res, 0, sizeof(res));
+     if (clnt_call(clnt, INIT, xdr_u_int32, argp,
+                  xdr_generic_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+         return (NULL);
+     }
+     return (&res);
+}
diff --git a/src/lib/kadm5/clnt/clnt_chpass_util.c b/src/lib/kadm5/clnt/clnt_chpass_util.c
new file mode 100644 (file)
index 0000000..d6c7f0b
--- /dev/null
@@ -0,0 +1,15 @@
+#include <kadm5/admin.h>
+#include "client_internal.h"
+
+kadm5_ret_t kadm5_chpass_principal_util(void *server_handle,
+                                       krb5_principal princ,
+                                       char *new_pw, 
+                                       char **ret_pw,
+                                       char *msg_ret)
+{
+  kadm5_server_handle_t handle = server_handle;
+
+  CHECK_HANDLE(server_handle);
+  return _kadm5_chpass_principal_util(handle, handle->lhandle, princ,
+                                     new_pw, ret_pw, msg_ret);
+}
diff --git a/src/lib/kadm5/clnt/clnt_policy.c b/src/lib/kadm5/clnt/clnt_policy.c
new file mode 100644 (file)
index 0000000..f81cf74
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
+ *
+ * $Header$
+ */
+
+#if !defined(lint) && !defined(__CODECENTER__)
+static char *rcsid = "$Header$";
+#endif
+
+#include    <rpc/rpc.h>
+#include    <kadm5/admin.h>
+#include    <kadm5/kadm_rpc.h>
+#include    "client_internal.h"
+#include       <stdlib.h>
+#include       <string.h>
+
+kadm5_ret_t
+kadm5_create_policy(void *server_handle,
+                        kadm5_policy_ent_t policy, long mask)
+{
+    cpol_arg           arg;
+    generic_ret                *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+
+    if(policy == (kadm5_policy_ent_t) NULL)
+       return EINVAL;
+
+    arg.mask = mask;
+    arg.api_version = handle->api_version;
+    memcpy(&arg.rec, policy, sizeof(kadm5_policy_ent_rec));
+    r = create_policy_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;    
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_delete_policy(void *server_handle, char *name)
+{
+    dpol_arg           arg;
+    generic_ret                *r;
+    kadm5_server_handle_t handle = server_handle;
+        
+    CHECK_HANDLE(server_handle);
+
+    if(name == NULL)
+       return EINVAL;
+
+    arg.name = name;
+    arg.api_version = handle->api_version;
+
+    r = delete_policy_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;    
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_modify_policy(void *server_handle,
+                        kadm5_policy_ent_t policy, long mask)
+
+{
+    mpol_arg           arg;
+    generic_ret                *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+
+    if(policy == (kadm5_policy_ent_t) NULL)
+       return EINVAL;
+       
+    arg.mask = mask;
+    arg.api_version = handle->api_version;
+
+    memcpy(&arg.rec, policy, sizeof(kadm5_policy_ent_rec));
+    r = modify_policy_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;    
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_get_policy(void *server_handle, char *name, kadm5_policy_ent_t ent)
+
+{
+    gpol_arg       arg;
+    gpol_ret       *r;
+    kadm5_server_handle_t handle = server_handle;
+
+    CHECK_HANDLE(server_handle);
+
+    arg.name = name;
+    arg.api_version = handle->api_version;
+
+    if(name == NULL)
+       return EINVAL;
+       
+    r = get_policy_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;
+    if (handle->api_version == KADM5_API_VERSION_1) {
+        kadm5_policy_ent_t *entp;
+
+        entp = (kadm5_policy_ent_t *) ent;
+        if(r->code == 0) {
+             if (!(*entp = (kadm5_policy_ent_t)
+                   malloc(sizeof(kadm5_policy_ent_rec))))
+                  return ENOMEM;
+             memcpy(*entp, &r->rec, sizeof(**entp));
+        } else {
+             *entp = NULL;
+        }
+    } else {
+        if (r->code == 0)
+             memcpy(ent, &r->rec, sizeof(r->rec));
+    }
+        
+    return r->code;
+}
+
+kadm5_ret_t
+kadm5_get_policies(void *server_handle,
+                         char *exp, char ***pols, int *count)
+{
+    gpols_arg  arg;
+    gpols_ret  *r;
+    kadm5_server_handle_t handle = server_handle;
+    krb5_error_code retval;
+
+    CHECK_HANDLE(server_handle);
+
+    if(pols == NULL || count == NULL)
+       return EINVAL;
+    arg.exp = exp;
+    arg.api_version = handle->api_version;
+    r = get_pols_1(&arg, handle->clnt);
+    if(r == NULL)
+       return KADM5_RPC_ERROR;
+    if(r->code == 0) {
+        *count = r->count;
+        *pols = r->pols;
+    } else {
+        *count = 0;
+        *pols = NULL;
+    }
+    
+    return r->code;
+}
diff --git a/src/lib/kadm5/clnt/clnt_privs.c b/src/lib/kadm5/clnt/clnt_privs.c
new file mode 100644 (file)
index 0000000..7eab2f8
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
+ *
+ * $Id$
+ * $Source$
+ * 
+ * $Log$
+ * Revision 1.1  1996/07/24 22:22:48  tlyu
+ *     * Makefile.in, configure.in: break out client lib into a
+ *             subdirectory
+ *
+ * Revision 1.6  1996/07/22 20:35:57  marc
+ * this commit includes all the changes on the OV_9510_INTEGRATION and
+ * OV_MERGE branches.  This includes, but is not limited to, the new openvision
+ * admin system, and major changes to gssapi to add functionality, and bring
+ * the implementation in line with rfc1964.  before committing, the
+ * code was built and tested for netbsd and solaris.
+ *
+ * Revision 1.5.4.1  1996/07/18 03:08:45  marc
+ * merged in changes from OV_9510_BP to OV_9510_FINAL1
+ *
+ * Revision 1.5.2.1  1996/06/20  02:16:53  marc
+ * File added to the repository on a branch
+ *
+ * Revision 1.5  1996/05/17  21:36:50  bjaspan
+ * rename to kadm5, begin implementing version 2
+ *
+ * Revision 1.4  1996/05/16 21:45:51  bjaspan
+ * u_int32 -> long, add krb5_context
+ *
+ * Revision 1.3  1994/09/20 16:25:05  bjaspan
+ * [secure-admin/2436: API versioning fixes to various admin files]
+ * [secure-releng/2502: audit secure-admin/2436: random API versioning fixes]
+ *
+ * Sandbox:
+ *
+ *  Unnecessary variable initialization removed.
+ *
+ * Revision 1.3  1994/09/12  20:26:39  jik
+ * Unnecessary variable initialization removed.
+ *
+ * Revision 1.2  1994/08/16  18:52:02  jik
+ * Versioning changes.
+ *
+ * Revision 1.1  1993/11/10  23:10:39  bjaspan
+ * Initial revision
+ *
+ */
+
+#if !defined(lint) && !defined(__CODECENTER__)
+static char *rcsid = "$Header$";
+#endif
+
+#include    <rpc/rpc.h>
+#include    <kadm5/admin.h>
+#include    <kadm5/kadm_rpc.h>
+#include    "client_internal.h"
+
+kadm5_ret_t kadm5_get_privs(void *server_handle, long *privs)
+{
+     getprivs_ret *r;
+     kadm5_server_handle_t handle = server_handle;
+
+     r = get_privs_1(&handle->api_version, handle->clnt);
+     if (r == NULL)
+         return KADM5_RPC_ERROR;
+     else if (r->code == KADM5_OK)
+         *privs = r->privs;
+     return r->code;
+}
diff --git a/src/lib/kadm5/clnt/configure.in b/src/lib/kadm5/clnt/configure.in
new file mode 100644 (file)
index 0000000..6eb3627
--- /dev/null
@@ -0,0 +1,29 @@
+AC_INIT(client_rpc.c)
+CONFIG_RULES
+AC_PROG_ARCHIVE
+AC_PROG_ARCHIVE_ADD
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+AC_REPLACE_FUNCS(setenv)
+V5_SHARED_LIB_OBJS
+V5_MAKE_SHARED_LIB(libkadm5clnt, 1.0, ../.., ./kadm5/clnt)
+
+GSSRPC_SH_VERS=$krb5_cv_shlib_version_libgssrpc
+AC_SUBST(GSSRPC_SH_VERS)
+GSSAPI_KRB5_SH_VERS=$krb5_cv_shlib_version_libgssapi_krb5
+AC_SUBST(GSSAPI_KRB5_SH_VERS)
+KDB5_SH_VERS=$krb5_cv_shlib_version_libkdb5
+AC_SUBST(KDB5_SH_VERS)
+KRB5_SH_VERS=$krb5_cv_shlib_version_libkrb5
+AC_SUBST(KRB5_SH_VERS)
+CRYPTO_SH_VERS=$krb5_cv_shlib_version_libcrypto
+AC_SUBST(CRYPTO_SH_VERS)
+COMERR_SH_VERS=$krb5_cv_shlib_version_libcom_err
+AC_SUBST(COMERR_SH_VERS)
+DYN_SH_VERS=$krb5_cv_shlib_version_libdyn
+AC_SUBST(DYN_SH_VERS)
+
+SubdirLibraryRule([$(OBJS)])
+
+CopySrcHeader(client_internal.h,[$](BUILDTOP)/include/kadm5)
+V5_AC_OUTPUT_MAKEFILE