summaryrefslogtreecommitdiffstats
path: root/support/nfsidmap/gums.c
diff options
context:
space:
mode:
Diffstat (limited to 'support/nfsidmap/gums.c')
-rw-r--r--support/nfsidmap/gums.c787
1 files changed, 787 insertions, 0 deletions
diff --git a/support/nfsidmap/gums.c b/support/nfsidmap/gums.c
new file mode 100644
index 0000000..1d6eb31
--- /dev/null
+++ b/support/nfsidmap/gums.c
@@ -0,0 +1,787 @@
+/*
+ * gums.c
+ *
+ * Copyright (c) 2004 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Olga Kornievskaia <aglo@umich.edu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pwd.h>
+#include <grp.h>
+#include <err.h>
+#include <syslog.h>
+#include "nfsidmap.h"
+#include "nfsidmap_plugin.h"
+
+#include <voms_apic.h>
+
+#include <prima_logger.h>
+#include <prima_soap_client.h>
+#include <prima_saml_support.h>
+
+#define DEFAULT_PRIMA_CONF_LOCATION "/etc/grid-security/prima-authz.conf"
+#define DEFAULT_VOMSDIR "/etc/grid-security/vomsdir"
+#define DEFAULT_CADIR "/etc/grid-security/certificates"
+#define X509_DN_SIZE 1024
+
+//#define DEBUG_PRINT_VOMS
+
+#define USING_TEST_PROGRAM
+#ifdef USING_TEST_PROGRAM
+nfs4_idmap_log_function_t idmap_log_func = printf;
+int idmap_verbosity = 10;
+#endif
+
+/*
+ * GUMS Translation Methods
+ *
+ */
+
+/* global variables. voms/gums configuration attributes*/
+static char prima_conf[] = DEFAULT_PRIMA_CONF_LOCATION;
+typedef struct _plugin_config_params {
+ char *saml_schema_dir;
+ int saml_log_level;
+ char *server_cert;
+ char *server_key;
+ char *ca_dir;
+ char *gums_server_location;
+ char *voms_dir;
+} plugin_config_params;
+plugin_config_params conf;
+
+#ifdef VOMS_BUG
+static void my_VOMS_Delete(struct voms *v)
+{
+ int i;
+
+ if (!v) return;
+ if (v->user)
+ free(v->user);
+ if (v->server)
+ free(v->server);
+ if (v->fqan) {
+ for (i = 0; v->fqan[i] != NULL; i++)
+ free(v->fqan[i]);
+ free(v->fqan);
+ }
+ free(v);
+}
+
+static struct voms *my_VOMS_Copy(struct voms *v, int *err)
+{
+ struct voms *cv;
+ int i;
+
+ cv = calloc(1, sizeof(struct voms));
+ if (cv == NULL)
+ goto out;
+ cv->user = strdup(v->user);
+ if (cv->user == NULL)
+ goto out;
+ cv->server = strdup(v->server);
+ if (cv->server == NULL)
+ goto out;
+ for (i = 0; v->fqan[i] != NULL; i++) {
+ if (v->fqan[i] == NULL)
+ break;
+ }
+ cv->fqan = calloc(i+1, sizeof(char *));
+ if (cv->fqan == NULL)
+ goto out;
+ cv->fqan[i] = NULL;
+ for (i = 0; v->fqan[i] != NULL; i++) {
+ cv->fqan[i] = strdup(v->fqan[i]);
+ if (cv->fqan[i] == NULL)
+ goto out;
+ }
+ return cv;
+out:
+ if (cv)
+ my_VOMS_Delete(cv);
+
+ return NULL;
+}
+#endif
+
+
+#ifdef DEBUG_PRINT_VOMS
+void printvoms(struct voms *v)
+{
+ int j;
+
+ printf("SIGLEN: %d\nUSER: %s\n", v->siglen, v->user);
+ printf("UCA: %s\nSERVER: %s\n", v->userca, v->server);
+ printf("SCA: %s\nVO: %s\n", v->serverca, v->voname);
+ printf("URI: %s\nDATE1: %s\n", v->uri, v->date1);
+ printf("DATE2: %s\n", v->date2);
+
+ switch (v->type) {
+ case TYPE_NODATA:
+ printf("NO DATA\n");
+ break;
+ case TYPE_CUSTOM:
+ printf("%*s\n", v->datalen - 10, v->custom);
+ break;
+ case TYPE_STD:
+ j = 0;
+ while (v->std[j]) {
+ printf("GROUP: %s\nROLE: %s\nCAP: %s\n",v->std[j]->group,
+ v->std[j]->role,v->std[j]->cap);
+ j++;
+ }
+ }
+}
+
+void print(struct vomsdata *d)
+{
+ struct voms **vo = d->data;
+ struct voms *v;
+ int k = 0;
+
+ while(vo[k]) {
+ v = vo[k++];
+ printf("%d *******************************************\n",k);
+ printvoms(v);
+ }
+
+ if (d->workvo)
+ printf("WORKVO: %s\n", d->workvo);
+
+ if (d->extra_data)
+ printf("EXTRA: %s\n", d->extra_data);
+}
+#endif
+
+static void free_plugin_config_params()
+{
+ if (conf.saml_schema_dir)
+ free(conf.saml_schema_dir);
+ conf.saml_schema_dir = NULL;
+ if (conf.server_cert)
+ free(conf.server_cert);
+ conf.server_cert = NULL;
+ if (conf.server_key)
+ free(conf.server_key);
+ conf.server_key = NULL;
+ if (conf.ca_dir)
+ free(conf.ca_dir);
+ conf.ca_dir = NULL;
+ if (conf.voms_dir)
+ free(conf.voms_dir);
+ conf.voms_dir = NULL;
+}
+
+static int validate_plugin_config_params()
+{
+ if (conf.saml_schema_dir == NULL ||
+ conf.server_cert == NULL ||
+ conf.server_key == NULL ||
+ conf.gums_server_location == NULL)
+ return -1;
+
+ if (conf.ca_dir == NULL) {
+ conf.ca_dir = strdup(DEFAULT_CADIR);
+ if (conf.ca_dir == NULL)
+ return -1;
+ }
+ if (conf.voms_dir == NULL) {
+ conf.voms_dir = strdup(DEFAULT_VOMSDIR);
+ if (conf.voms_dir == NULL)
+ return -1;
+ }
+ return 0;
+}
+
+static int gums_init(void)
+{
+ FILE *f = NULL;
+ int ret = -1, i = 0;
+ char buf[512], type[128], value[256];
+ char *alt_conf = NULL;
+
+ alt_conf = nfsidmap_config_get("GUMS", "Conf_File");
+ if (alt_conf == NULL)
+ f = fopen(prima_conf, "r");
+ else
+ f = fopen(alt_conf, "r");
+ if (f == NULL)
+ goto out;
+
+ while (fgets(buf, 512, f)) {
+ i = 0;
+ while(buf[i] == ' ' || buf[i] == '\t')
+ i++;
+ if (buf[i] == '#' || buf[i] == '\0' || buf[i] == '\n')
+ continue;
+ if (sscanf(&buf[i], "%127s%255s",type,value) < 2) {
+ IDMAP_LOG(0, ("ERROR: malformed line: %s\n", &buf[i]));
+ goto out;
+ }
+ IDMAP_LOG(1, ("PRIMA conf: type=%s value=%s\n", type, value));
+ if (strncmp(type, "imsContact", 10) == 0) {
+ conf.gums_server_location = strdup(value);
+ } else if (strncmp(type, "serviceCert", 11) == 0) {
+ conf.server_cert = strdup(value);
+ } else if (strncmp(type, "serviceKey", 10) == 0) {
+ conf.server_key = strdup(value);
+ } else if (strncmp(type, "caCertDir", 9) == 0) {
+ conf.ca_dir = strdup(value);
+ } else if (strncmp(type, "samlSchemaDir", 13) == 0) {
+ conf.saml_schema_dir = strdup(value);
+ } else if (strncmp(type, "logLevel", 8) == 0) {
+ if (strncmp(value, "debug", 5) == 0)
+ conf.saml_log_level = PRIMA_LOG_DEBUG;
+ else if (strncmp(value, "error", 5) == 0)
+ conf.saml_log_level = PRIMA_LOG_ERROR;
+ else if (strncmp(value, "none", 4) == 0)
+ conf.saml_log_level = PRIMA_LOG_NONE;
+ else
+ conf.saml_log_level = PRIMA_LOG_INFO;
+ }
+ }
+
+ if (validate_plugin_config_params() != 0)
+ goto out;
+
+ ret = 0;
+out:
+ if (f)
+ fclose(f);
+ if (ret)
+ free_plugin_config_params();
+
+ return ret;
+}
+
+static int retrieve_attributes(X509 *cert, STACK_OF(X509) *cas,
+ struct voms **attrs)
+{
+ int ret = -1, err = 0;
+ struct vomsdata *vd = NULL;
+
+ vd = VOMS_Init(conf.voms_dir, conf.ca_dir);
+ if (vd == NULL) {
+ IDMAP_LOG(0, ("VOMS_Init failed\n"));
+ return -1;
+ }
+ ret = VOMS_Retrieve(cert, cas, RECURSE_CHAIN, vd, &err);
+ if (err) {
+ char *err_msg;
+ err_msg = VOMS_ErrorMessage(vd, err, NULL, 0);
+ if (err == VERR_NOEXT)
+ ret = 0;
+ else
+ IDMAP_LOG(0, ("VOMS error %s\n", err_msg));
+ goto out;
+ } else if (ret) {
+ struct voms *v, *v2;
+#ifdef DEBUG_PRINT_VOMS
+ print(vd);
+#endif
+ v = VOMS_DefaultData(vd, &err);
+ if (err == VERR_NONE) {
+#ifdef DEBUG_PRINT_VOMS
+ printvoms(v);
+ while (v->fqan[i] != NULL)
+ IDMAP_LOG(1, ("user's fqan: %s\n", v->fqan[i++]));
+#endif
+#ifdef VOMS_BUG
+ v2 = my_VOMS_Copy(v, &err);
+#else
+ v2 = VOMS_Copy(v, &err);
+#endif
+ if (v2 == NULL) {
+ IDMAP_LOG(0, ("VOMS_Copy failed err=%d\n", err));
+ goto out;
+ }
+ *attrs = v2;
+ }
+ }
+ ret = 0;
+out:
+ if (vd)
+ VOMS_Destroy(vd);
+ return ret;
+}
+
+static int get_server_dn(unsigned char **server_dn)
+{
+ BIO *tmp = NULL;
+ X509 *cert = NULL;
+ int ret = -1;
+ char dn[X509_DN_SIZE];
+
+ tmp = BIO_new(BIO_s_file());
+ if (tmp == NULL)
+ goto out;
+
+ ret = BIO_read_filename(tmp, conf.server_cert);
+ if (ret == 0) {
+ ret = errno;
+ goto out;
+ }
+
+ cert = (X509 *) PEM_read_bio_X509(tmp, NULL, NULL, NULL);
+ if (cert == NULL)
+ goto out;
+
+ X509_NAME_oneline(X509_get_subject_name(cert), dn, sizeof(dn));
+
+ *server_dn = strdup(dn);
+ if (*server_dn == NULL)
+ goto out;
+
+ ret = 0;
+out:
+ if (tmp)
+ BIO_free(tmp);
+ if (cert)
+ X509_free(cert);
+
+ return ret;
+}
+
+static int create_saml_request(char *dn, struct voms *attrs, char **saml_req)
+{
+ int ret = -1, i;
+ char *req = NULL;
+ unsigned char *server_dn = NULL;
+ prima_saml_fqans fqans;
+
+ IDMAP_LOG(2, ("create_saml_request start\n"));
+ ret = initPrimaSAMLFQANs(&fqans);
+ if (ret) {
+ IDMAP_LOG(0, ("initPrimaSAMLFQANs failed with %d\n", ret));
+ goto out;
+ }
+
+ if (attrs) {
+ for (i = 0; attrs->fqan[i] != NULL; i++) {
+ ret = addPrimaSAMLFQAN(&fqans, attrs->server, attrs->fqan[i]);
+ IDMAP_LOG(1, ("addPrimaSAMLFQAN returned %d\n", ret));
+ }
+ dn = attrs->user;
+ } else
+ IDMAP_LOG(1, ("No VOMS attributes present in the cert\n"));
+
+ if (get_server_dn(&server_dn) != 0)
+ goto out;
+ req = createSAMLQueryAndRequest(server_dn, dn, &fqans);
+ if (req == NULL) {
+ IDMAP_LOG(0, ("createSAMLQueryAndRequest failed to create "
+ "SAML request\n"));
+ goto out;
+ }
+ IDMAP_LOG(1, ("SAML Request %s\n", req));
+
+ ret = 0;
+ *saml_req = req;
+out:
+ cleanupPrimaSAMLFQANs(&fqans);
+
+ if (server_dn)
+ free(server_dn);
+
+ IDMAP_LOG(2, ("create_saml_request returning %d\n", ret));
+ return ret;
+}
+
+static int process_parameters(extra_mapping_params **ex, X509 **user_cert,
+ STACK_OF(X509) **user_chain)
+{
+
+ int ret = -1, i;
+ X509 *cert = NULL, *x;
+ STACK_OF(X509) *chain = NULL;
+ unsigned char *p;
+
+ if (ex[0]->content_type != X509_CERT)
+ return -1;
+
+ /* get user's x509 certificate */
+ p = ex[0]->content;
+ cert = d2i_X509(NULL, &p, ex[0]->content_len);
+ if (cert == NULL)
+ goto out;
+
+ /* get user's other certificates */
+ chain = sk_X509_new_null();
+ if (chain == NULL)
+ goto out;
+ for (i = 1; ex[i] != NULL; i++) {
+ if (ex[i]->content_type != X509_CERT)
+ continue;
+ p = ex[i]->content;
+ x = d2i_X509(NULL, &p, ex[i]->content_len);
+ if (x == NULL)
+ goto out;
+ sk_X509_push(chain, x);
+ }
+ ret = 0;
+
+ *user_cert = cert;
+ *user_chain = chain;
+out:
+ if (ret) {
+ int num;
+ if (cert)
+ X509_free(cert);
+ if (chain)
+ sk_X509_pop_free(chain, X509_free);
+ }
+
+ return ret;
+}
+
+struct pwbuf {
+ struct passwd pwbuf;
+ char buf[1];
+};
+
+static int translate_to_uid(char *local_uid, uid_t *uid, uid_t *gid)
+{
+ int ret = -1;
+ struct passwd *pw = NULL;
+ struct pwbuf *buf = NULL;
+ size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+
+ buf = malloc(sizeof(*buf) + buflen);
+ if (buf == NULL)
+ goto out;
+
+ ret = getpwnam_r(local_uid, &buf->pwbuf, buf->buf, buflen, &pw);
+ if (pw == NULL) {
+ IDMAP_LOG(0, ("getpwnam: name %s not found\n", local_uid));
+ goto out;
+ }
+ *uid = pw->pw_uid;
+ *gid = pw->pw_gid;
+
+ ret = 0;
+out:
+ if (buf)
+ free(buf);
+ return ret;
+}
+
+static int translate_to_gid(char *local_gid, uid_t *gid)
+{
+ struct group *gr = NULL;
+ struct group grbuf;
+ char *buf = NULL;
+ size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+ int ret = -1;
+
+ do {
+ buf = malloc(buflen);
+ if (buf == NULL)
+ goto out;
+
+ ret = -getgrnam_r(local_gid, &grbuf, buf, buflen, &gr);
+ if (gr == NULL && !ret)
+ ret = -ENOENT;
+ if (ret == -ERANGE) {
+ buflen *= 2;
+ free(buf);
+ }
+ } while (ret == -ERANGE);
+
+ if (ret)
+ goto out;
+
+ *gid = gr->gr_gid;
+
+ ret = 0;
+out:
+ if (buf)
+ free(buf);
+ return ret;
+}
+
+static int gums_gss_princ_to_ids(char *secname, char *princ,
+ uid_t *uid, uid_t *gid,
+ extra_mapping_params **ex)
+{
+ int ret = -1, size, i;
+ X509 *cert = NULL;
+ STACK_OF(X509) *cas = NULL;
+ char dn[X509_DN_SIZE];
+ struct voms *attrs = NULL;
+ char *saml_req = NULL, *saml_resp = NULL;
+ int saml_result;
+ char *local_uid = NULL, *local_gid = NULL, *p;
+
+ /* accept only spkm3 translations */
+ if (strcmp(secname, "spkm3"))
+ return -EINVAL;
+
+ /* must supply either a DN and/or at least 1 binary blob */
+ if (princ == NULL && (ex == NULL || (ex && ex[0] == NULL)))
+ return -EINVAL;
+
+ /* process extra parameters */
+ if (process_parameters(ex, &cert, &cas) != 0)
+ goto out;
+
+ IDMAP_LOG(1, ("Processing name translation of client\n"));
+ X509_NAME_oneline(X509_get_subject_name(cert), dn, sizeof(dn));
+ IDMAP_LOG(1, ("DN=%s\n", dn));
+ size = sk_X509_num(cas);
+ IDMAP_LOG(1, ("Including following CAs (%d)\n", size));
+ for (i=0; i < size; i++) {
+ X509_NAME_oneline(X509_get_subject_name(sk_X509_value(cas, i)),
+ dn, sizeof(dn));
+ IDMAP_LOG(1, ("DN=%s\n", dn));
+ }
+
+ /* retrieve VOMS attributes */
+ if (retrieve_attributes(cert, cas, &attrs) != 0)
+ goto out;
+ if (attrs == NULL)
+ X509_NAME_oneline(X509_get_subject_name(cert), dn, sizeof(dn));
+
+ /* initialize SAML library */
+ if (initPrimaSAMLSupport(conf.saml_schema_dir,
+ conf.saml_log_level) != 0) {
+ IDMAP_LOG(0, ("initPrimaSAMLSupport failed\n"));
+ goto out;
+ }
+
+ /* create SAML request */
+ if (create_saml_request(dn, attrs, &saml_req) != 0)
+ goto out;
+
+ /* contact GUMS server */
+ saml_resp = queryIdentityMappingService(conf.gums_server_location,
+ saml_req, conf.server_cert, conf.server_key,
+ conf.ca_dir);
+ if (saml_resp != NULL) {
+ saml_result = processResponse(saml_resp, saml_req, &local_uid,
+ &local_gid);
+ IDMAP_LOG(1, ("processResponse returned %d\n", saml_result));
+ if (saml_result || local_uid == NULL) {
+ IDMAP_LOG(0, ("processResponse failed to return "
+ "local id\n"));
+ ret = -ENOENT;
+ goto out;
+ }
+ IDMAP_LOG(1, ("GUMS returned uid=%s gid=%s\n", local_uid,
+ local_gid));
+ }
+
+ /* translate account name to uid */
+ if (translate_to_uid(local_uid, uid, gid))
+ goto out;
+ if (local_gid)
+ if (translate_to_gid(local_gid, gid))
+ goto out;
+
+ ret = 0;
+out:
+ if (cert)
+ X509_free(cert);
+
+ if (cas)
+ sk_X509_pop_free(cas, X509_free);
+
+ if (attrs)
+#ifdef VOMS_BUG
+ my_VOMS_Delete(attrs);
+#else
+ VOMS_Delete(attrs);
+#endif
+
+ if (saml_req)
+ free(saml_req);
+
+ if (saml_resp)
+ free(saml_resp);
+
+ cleanupPrimaSAMLSupport();
+
+ return ret;
+}
+
+struct trans_func gums_trans = {
+ .name = "gums",
+ .init = gums_init,
+ .princ_to_ids = gums_gss_princ_to_ids,
+ .name_to_uid = NULL,
+ .name_to_gid = NULL,
+ .uid_to_name = NULL,
+ .gid_to_name = NULL,
+ .gss_princ_to_grouplist = NULL,
+};
+
+struct trans_func *libnfsidmap_plugin_init()
+{
+ return (&gums_trans);
+}
+
+#ifdef USING_TEST_PROGRAM
+static STACK_OF(X509) *load_chain(char *certfile)
+{
+ STACK_OF(X509_INFO) *sk=NULL;
+ STACK_OF(X509) *stack=NULL, *ret=NULL;
+ BIO *in=NULL;
+ X509_INFO *xi;
+ int first = 1;
+
+ if (!(stack = sk_X509_new_null())) {
+ printf("memory allocation failure\n");
+ goto end;
+ }
+
+ if (!(in=BIO_new_file(certfile, "r"))) {
+ printf("error opening the file, %s\n",certfile);
+ goto end;
+ }
+
+ /* This loads from a file, a stack of x509/crl/pkey sets */
+ if (!(sk=(STACK_OF(X509_INFO) *)PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) {
+ /* if (!(sk=PEM_X509_read_bio(in,NULL,NULL,NULL))) { */
+ printf("error reading the file, %s\n",certfile);
+ goto end;
+ }
+
+ /* scan over it and pull out the certs */
+ while (sk_X509_INFO_num(sk)) {
+ /* skip first cert */
+ if (first) {
+ xi=sk_X509_INFO_shift(sk);
+ X509_INFO_free(xi);
+ first = 0;
+ continue;
+ }
+ xi=sk_X509_INFO_shift(sk);
+ if (xi->x509 != NULL) {
+ sk_X509_push(stack,xi->x509);
+ xi->x509=NULL;
+ }
+ X509_INFO_free(xi);
+ }
+ if (!sk_X509_num(stack)) {
+ printf("no certificates in file, %s\n",certfile);
+ sk_X509_free(stack);
+ goto end;
+ }
+ ret=stack;
+end:
+ BIO_free(in);
+ sk_X509_INFO_free(sk);
+ return(ret);
+}
+
+void create_params(X509 *cert, STACK_OF(X509) *cas,
+ extra_mapping_params ***ret_params)
+{
+ int len = 0, i, size = 0;
+ unsigned char *p, *buf = NULL;
+ extra_mapping_params **params = NULL;
+ X509 *x;
+
+ if (cas)
+ size = sk_X509_num(cas);
+ params = malloc((size+2)*sizeof(extra_mapping_params *));
+ params[size+1] = NULL;
+
+ /* 1st element is user's certificate */
+ len = i2d_X509(cert, NULL);
+ p = buf = malloc(len);
+ i2d_X509(cert, &p);
+ params[0] = malloc(sizeof(extra_mapping_params));
+ params[0]->content_type = X509_CERT;
+ params[0]->content = buf;
+ params[0]->content_len = len;
+
+ /* add other certificates to the array */
+ for (i = 0; i < size; i++) {
+ x = sk_X509_value(cas, i);
+ params[i+1] = malloc(sizeof(extra_mapping_params));
+ len = i2d_X509(x, NULL);
+ p = buf = malloc(len);
+ i2d_X509(x, &p);
+ params[i+1]->content_type = X509_CERT;
+ params[i+1]->content = buf;
+ params[i+1]->content_len = len;
+ }
+ *ret_params = params;
+}
+
+int main(void)
+{
+ int uid, gid, ret, i;
+ extra_mapping_params **params = NULL;
+ BIO *tmp = NULL;
+ X509 *cert = NULL, *x;
+ STACK_OF(X509) *cas = NULL;
+ unsigned char *proxy_file;
+
+ if (gums_init())
+ return -1;
+ proxy_file = getenv("X509_USER_PROXY");
+ if (proxy_file == NULL) {
+ fprintf(stderr, "X509_USER_PROXY is not set\n");
+ return -1;
+ }
+ tmp = BIO_new(BIO_s_file());
+ BIO_read_filename(tmp, proxy_file);
+ cert = (X509 *) PEM_read_bio_X509(tmp, NULL, NULL, NULL);
+ cas = load_chain(proxy_file);
+ create_params(cert, cas, &params);
+ ret = gums_gss_princ_to_ids("spkm3", NULL, &uid, &gid, params);
+ fprintf(stderr, "gums_gss_princ_to_ids returns %d uid=%d gid=%d\n",
+ ret, uid, gid);
+
+ if (tmp)
+ BIO_free(tmp);
+ if (cert)
+ X509_free(cert);
+ if (cas)
+ sk_X509_pop_free(cas, X509_free);
+
+ free_plugin_config_params();
+
+ if (params) {
+ for (i=0; params[i] != NULL; i++) {
+ free(params[i]->content);
+ free(params[i]);
+ }
+ free(params);
+ }
+
+ return 0;
+}
+#endif