Esempio n. 1
0
File: ext.c Progetto: Henauxg/minix
int
ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
{
    krb5_error_code ret;
    int i;
    struct ext_keytab_data data;

    if (opt->keytab_string == NULL)
	ret = krb5_kt_default(context, &data.keytab);
    else
	ret = krb5_kt_resolve(context, opt->keytab_string, &data.keytab);

    if(ret){
	krb5_warn(context, ret, "krb5_kt_resolve");
	return 1;
    }

    for(i = 0; i < argc; i++) {
	ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data);
	if (ret)
	    break;
    }

    krb5_kt_close(context, data.keytab);

    return ret != 0;
}
Esempio n. 2
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_kt_read_service_key(krb5_context context,
			 krb5_pointer keyprocarg,
			 krb5_principal principal,
			 krb5_kvno vno,
			 krb5_enctype enctype,
			 krb5_keyblock **key)
{
    krb5_keytab keytab;
    krb5_keytab_entry entry;
    krb5_error_code ret;

    if (keyprocarg)
	ret = krb5_kt_resolve (context, keyprocarg, &keytab);
    else
	ret = krb5_kt_default (context, &keytab);

    if (ret)
	return ret;

    ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
    krb5_kt_close (context, keytab);
    if (ret)
	return ret;
    ret = krb5_copy_keyblock (context, &entry.keyblock, key);
    krb5_kt_free_entry(context, &entry);
    return ret;
}
Esempio n. 3
0
KRB5_DEPRECATED
KRB5_LIB_FUNCTION krb5_error_code KRB5_CALLCONV
krb5_keytab_key_proc (krb5_context context,
		      krb5_enctype enctype,
		      krb5_salt salt,
		      krb5_const_pointer keyseed,
		      krb5_keyblock **key)
{
    krb5_keytab_key_proc_args *args  = rk_UNCONST(keyseed);
    krb5_keytab keytab = args->keytab;
    krb5_principal principal  = args->principal;
    krb5_error_code ret;
    krb5_keytab real_keytab;
    krb5_keytab_entry entry;

    if(keytab == NULL)
	krb5_kt_default(context, &real_keytab);
    else
	real_keytab = keytab;

    ret = krb5_kt_get_entry (context, real_keytab, principal,
			     0, enctype, &entry);

    if (keytab == NULL)
	krb5_kt_close (context, real_keytab);

    if (ret)
	return ret;

    ret = krb5_copy_keyblock (context, &entry.keyblock, key);
    krb5_kt_free_entry(context, &entry);
    return ret;
}
mit_krb5_error_code KRB5_CALLCONV
krb5_kt_read_service_key(mit_krb5_context context,
			 mit_krb5_pointer keyprocarg,
			 mit_krb5_principal principal,
			 mit_krb5_kvno vno,
			 mit_krb5_enctype enctype,
			 mit_krb5_keyblock **key)
{
    mit_krb5_keytab keytab;
    mit_krb5_keytab_entry entry;
    mit_krb5_error_code ret;

    LOG_ENTRY();

    if (keyprocarg)
	ret = krb5_kt_resolve (context, keyprocarg, &keytab);
    else
	ret = krb5_kt_default (context, &keytab);

    if (ret)
	return ret;

    ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
    krb5_kt_close (context, keytab);
    if (ret)
	return ret;
    ret = krb5_copy_keyblock (context, &entry.key, key);
    krb5_kt_free_entry(context, &entry);
    return ret;
}
Esempio n. 5
0
int
kerberos5_init(Authenticator *ap, int server)
{
    krb5_error_code ret;

    ret = krb5_init_context(&context);
    if (ret)
	return 0;
    if (server) {
	krb5_keytab kt;
	krb5_kt_cursor cursor;

	ret = krb5_kt_default(context, &kt);
	if (ret)
	    return 0;

	ret = krb5_kt_start_seq_get (context, kt, &cursor);
	if (ret) {
	    krb5_kt_close (context, kt);
	    return 0;
	}
	krb5_kt_end_seq_get (context, kt, &cursor);
	krb5_kt_close (context, kt);

	str_data[3] = TELQUAL_REPLY;
    } else
	str_data[3] = TELQUAL_IS;
    return(1);
}
Esempio n. 6
0
krb5_error_code KRB5_CALLCONV
krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
			      krb5_address *const *addrs, krb5_enctype *ktypes,
			      krb5_preauthtype *pre_auth_types,
			      krb5_keytab arg_keytab, krb5_ccache ccache,
			      krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
{
    krb5_error_code retval;
    krb5_gic_opt_ext *opte;
    char * server = NULL;
    krb5_keytab keytab;
    krb5_principal client_princ, server_princ;
    int use_master = 0;
    
    retval = krb5int_populate_gic_opt(context, &opte,
				      options, addrs, ktypes,
				      pre_auth_types, creds);
    if (retval)
	return retval;

    if (arg_keytab == NULL) {
	retval = krb5_kt_default(context, &keytab);
	if (retval)
	    return retval;
    }
    else keytab = arg_keytab;
    
    retval = krb5_unparse_name( context, creds->server, &server);
    if (retval)
	goto cleanup;
    server_princ = creds->server;
    client_princ = creds->client;
    retval = krb5_get_init_creds (context,
				  creds, creds->client,  
				  krb5_prompter_posix,  NULL,
				  0, server, opte,
				  krb5_get_as_key_keytab, (void *)keytab,
				  &use_master, ret_as_reply);
    krb5_free_unparsed_name( context, server);
    krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
    if (retval) {
	goto cleanup;
    }
	if (creds->server)
	    krb5_free_principal( context, creds->server);
	if (creds->client)
	    krb5_free_principal( context, creds->client);
	creds->client = client_princ;
	creds->server = server_princ;
	
    /* store it in the ccache! */
    if (ccache)
	if ((retval = krb5_cc_store_cred(context, ccache, creds)))
	    goto cleanup;
 cleanup:    if (arg_keytab == NULL)
     krb5_kt_close(context, keytab);
    return retval;
}
Esempio n. 7
0
int
kssl_keytab_is_available(KSSL_CTX *kssl_ctx)
{
	krb5_context		krb5context = NULL;
	krb5_keytab 		krb5keytab = NULL;
	krb5_keytab_entry           entry;
	krb5_principal              princ = NULL;
	krb5_error_code  		krb5rc = KRB5KRB_ERR_GENERIC;
	int rc = 0;

	if ((krb5rc = krb5_init_context(&krb5context)))
		return (0);

    /*	kssl_ctx->keytab_file == NULL ==> use Kerberos default
    */
	if (kssl_ctx->keytab_file) {
		krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
		    &krb5keytab);
		if (krb5rc)
			goto exit;
	} else {
		krb5rc = krb5_kt_default(krb5context, &krb5keytab);
		if (krb5rc)
			goto exit;
	}

	/* the host key we are looking for */
	krb5rc = krb5_sname_to_principal(krb5context, NULL,
	    kssl_ctx->service_name ? kssl_ctx->service_name : KRB5SVC,
	    KRB5_NT_SRV_HST, &princ);

	if (krb5rc)
		goto exit;

	krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ,
	    0 /* IGNORE_VNO */,
	    0 /* IGNORE_ENCTYPE */,
	    &entry);
	if (krb5rc == KRB5_KT_NOTFOUND) {
		rc = 1;
		goto exit;
	} else if (krb5rc)
		goto exit;

	krb5_kt_free_entry(krb5context, &entry);
	rc = 1;

	exit:
	if (krb5keytab)
		krb5_kt_close(krb5context, krb5keytab);
	if (princ)
		krb5_free_principal(krb5context, princ);
	if (krb5context)
		krb5_free_context(krb5context);
	return (rc);
}
Krb5Keytab::Krb5Keytab(krb5_context context, const std::string& name)
    : context_(context)
    , keytab_(nullptr) {
  if (name.empty()) {
    krb5_error_code code = krb5_kt_default(context, &keytab_);
    raiseIf(context, code, "getting default keytab");
  } else {
    krb5_error_code code = krb5_kt_resolve(context, name.c_str(), &keytab_);
    raiseIf(context, code, folly::to<std::string>(
      "failed to open keytab: ", name));
  }
}
Esempio n. 9
0
/** Create and return a new connection
 *
 * libkrb5(s) can talk to the KDC over TCP. Were assuming something sane is implemented
 * by libkrb5 and that it does connection caching associated with contexts, so it's
 * worth using a connection pool to preserve connections when workers die.
 *
 * @param instance rlm_krb5 instance instance.
 * @return A new context or NULL on error.
 */
void *mod_conn_create(void *instance)
{
	rlm_krb5_t *inst = instance;
	rlm_krb5_handle_t *conn;
	krb5_error_code ret;

	MEM(conn = talloc_zero(instance, rlm_krb5_handle_t));
	ret = krb5_init_context(&conn->context);
	if (ret) {
		ERROR("rlm_krb5 (%s): Context initialisation failed: %s", inst->xlat_name,
		       rlm_krb5_error(NULL, ret));

		return NULL;
	}
	talloc_set_destructor(conn, _free_handle);

	ret = inst->keytabname ?
		krb5_kt_resolve(conn->context, inst->keytabname, &conn->keytab) :
		krb5_kt_default(conn->context, &conn->keytab);
	if (ret) {
		ERROR("Resolving keytab failed: %s", rlm_krb5_error(conn->context, ret));

		goto cleanup;
	}

#ifdef HEIMDAL_KRB5
	ret = krb5_cc_new_unique(conn->context, "MEMORY", NULL, &conn->ccache);
	if (ret) {
		ERROR("rlm_krb5 (%s): Credential cache creation failed: %s", inst->xlat_name,
		      rlm_krb5_error(conn->context, ret));

		return NULL;
	}

	krb5_verify_opt_init(&conn->options);
	krb5_verify_opt_set_ccache(&conn->options, conn->ccache);

	krb5_verify_opt_set_keytab(&conn->options, conn->keytab);
	krb5_verify_opt_set_secure(&conn->options, true);

	if (inst->service) {
		krb5_verify_opt_set_service(&conn->options, inst->service);
	}
#else
	krb5_verify_init_creds_opt_set_ap_req_nofail(inst->vic_options, true);
#endif
	return conn;

cleanup:
	talloc_free(conn);
	return NULL;
}
Esempio n. 10
0
static PyObject *
k5_get_init_creds_keytab(PyObject *self, PyObject *args)
{
    char *name, *ktname;
    krb5_context ctx;
    krb5_error_code code;
    krb5_keytab keytab;
    krb5_ccache ccache;
    krb5_principal principal;
    krb5_get_init_creds_opt options;
    krb5_creds creds;

    if (!PyArg_ParseTuple(args, "sz", &name, &ktname))
        return NULL;

    /* Initialize parameters. */
    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_parse_name(ctx, name, &principal);
    RETURN_ON_ERROR("krb5_parse_name()", code);
    krb5_get_init_creds_opt_init(&options);
    memset(&creds, 0, sizeof (creds));

    /* Resolve keytab */
    if (ktname)
    {
	code = krb5_kt_resolve(ctx, ktname, &keytab);
	RETURN_ON_ERROR("krb5_kt_resolve()", code);
    } else
    {
	code = krb5_kt_default(ctx, &keytab);
	RETURN_ON_ERROR("krb5_kt_resolve()", code);
    }

    /* Get the credentials. */
    code = krb5_get_init_creds_keytab(ctx, &creds, principal,
                                      keytab, 0, NULL, &options);
    RETURN_ON_ERROR("krb5_get_init_creds_keytab()", code);

    /* Store the credential in the credential cache. */
    code = krb5_cc_default(ctx, &ccache);
    RETURN_ON_ERROR("krb5_cc_default()", code);
    code = krb5_cc_initialize(ctx, ccache, principal);
    RETURN_ON_ERROR("krb5_cc_initialize()", code);
    code = krb5_cc_store_cred(ctx, ccache, &creds);
    RETURN_ON_ERROR("krb5_cc_store_creds()", code);
    krb5_cc_close(ctx, ccache);

    Py_INCREF(Py_None);
    return Py_None;
}
Esempio n. 11
0
int
server_setup(krb5_context *context, int argc, char **argv)
{
    int port = common_setup(context, &argc, argv, server_usage);
    krb5_error_code ret;

    if(argv[argc] != NULL)
	server_usage(1, args, num_args);
    if (keytab_str != NULL)
	ret = krb5_kt_resolve (*context, keytab_str, &keytab);
    else
	ret = krb5_kt_default (*context, &keytab);
    if (ret)
	krb5_err (*context, 1, ret, "krb5_kt_resolve/default");
    return port;
}
Esempio n. 12
0
static int
k5ping(krb5_context ctx, const char *host, int socktype, krb5_principal princ,
    int use_kt, const char *passwd, krb5_principal sprinc)
{
	K5BAIL_DECLS;
	krb5_error_code		 kerr;
	krb5_ccache		 ccache = NULL;
	krb5_keytab		 kt;
	krb5_creds		 creds;
	krb5_get_init_creds_opt	*opt = NULL;

	VERBOSE(1, (stderr, "initiating kerberos5/%s ping to %s\n",
	    socktype == SOCK_DGRAM ? "udp" : "tcp", host));

	parse_kdc(host);
	current_socktype = socktype;

	K5BAIL(krb5_cc_resolve(ctx, "MEMORY:k5ping", &ccache));

        K5BAIL(krb5_get_init_creds_opt_alloc(ctx, &opt));
        krb5_get_init_creds_opt_set_tkt_life(opt, 15 * 60);

	if (use_kt) {
		K5BAIL(krb5_kt_default(ctx, &kt));
		K5BAIL(krb5_get_init_creds_keytab(ctx, &creds, princ, kt, 0,
		    NULL, opt));
	} else {
		K5BAIL(krb5_get_init_creds_password(ctx, &creds, princ, passwd,
		    krb5_prompter_posix, NULL, 0, NULL, opt));
	}

	K5BAIL(krb5_cc_store_cred(ctx, ccache, &creds));

	kret = kvno5(ctx, host, socktype, princ, sprinc, ccache);
done:
	if (ccache)
		krb5_cc_destroy(ctx, ccache);

	/* XXXrcd: free a few more things here... */
	/*	   opt.  creds.                   */

	if (croakstr[0])
		fail_msg("kerberos5", socktype, host, croakstr);

	return kret;
}
Esempio n. 13
0
OM_uint32
_gsskrb5_register_acceptor_identity(OM_uint32 *min_stat, const char *identity)
{
    krb5_context context;
    krb5_error_code ret;

    *min_stat = 0;

    ret = _gsskrb5_init(&context);
    if(ret)
	return GSS_S_FAILURE;

    HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);

    if(_gsskrb5_keytab != NULL) {
	krb5_kt_close(context, _gsskrb5_keytab);
	_gsskrb5_keytab = NULL;
    }
    if (identity == NULL) {
	ret = krb5_kt_default(context, &_gsskrb5_keytab);
    } else {
	/*
	 * First check if we can the keytab as is and if it has content...
	 */
	ret = validate_keytab(context, identity, &_gsskrb5_keytab);
	/*
	 * if it doesn't, lets prepend FILE: and try again
	 */
	if (ret) {
	    char *p = NULL;
	    ret = asprintf(&p, "FILE:%s", identity);
	    if(ret < 0 || p == NULL) {
		HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
		return GSS_S_FAILURE;
	    }
	    ret = validate_keytab(context, p, &_gsskrb5_keytab);
	    free(p);
	}
    }
    HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);
    if(ret) {
	*min_stat = ret;
	return GSS_S_FAILURE;
    }
    return GSS_S_COMPLETE;
}
Esempio n. 14
0
static int
process_keytab(krb5_context my_context, char **keytab_str,
               krb5_keytab *keytab)
{
    int code;
    char *name = *keytab_str;

    if (name == NULL) {
        name = malloc(BUFSIZ);
        if (!name) {
            com_err(whoami, ENOMEM, "while creating keytab name");
            return 1;
        }
        code = krb5_kt_default(my_context, keytab);
        if (code != 0) {
            com_err(whoami, code, "while opening default keytab");
            free(name);
            return 1;
        }
        code = krb5_kt_get_name(my_context, *keytab, name, BUFSIZ);
        if (code != 0) {
            com_err(whoami, code, "while getting keytab name");
            free(name);
            return 1;
        }
    } else {
        if (strchr(name, ':') != NULL)
            name = strdup(name);
        else if (asprintf(&name, "WRFILE:%s", name) < 0)
            name = NULL;
        if (name == NULL) {
            com_err(whoami, ENOMEM, "while creating keytab name");
            return 1;
        }

        code = krb5_kt_resolve(my_context, name, keytab);
        if (code != 0) {
            com_err(whoami, code, "while resolving keytab %s", name);
            free(name);
            return 1;
        }
    }

    *keytab_str = name;
    return 0;
}
Esempio n. 15
0
long kerberos_server_valid ()
{
  krb5_context ctx;
  krb5_keytab kt;
  krb5_kt_cursor csr;
  long ret = NIL;
				/* make a context */
  if (!krb5_init_context (&ctx)) {
				/* get default keytab */
    if (!krb5_kt_default (ctx,&kt)) {
				/* can do server if have good keytab */
      if (!krb5_kt_start_seq_get (ctx,kt,&csr)) ret = LONGT;
      krb5_kt_close (ctx,kt);	/* finished with keytab */
    }
    krb5_free_context (ctx);	/* finished with context */
  }
  return ret;
}
Esempio n. 16
0
static void
setup_env (krb5_context context, krb5_keytab *kt)
{
    krb5_error_code ret;

    if (keytab_file)
	ret = krb5_kt_resolve (context, keytab_file, kt);
    else
	ret = krb5_kt_default (context, kt);
    if (ret)
	krb5_err (context, 1, ret, "resolving keytab");

    if (client_principal_str == NULL)
	krb5_errx (context, 1, "missing client principal");
    ret = krb5_parse_name (context, client_principal_str, &client_principal);
    if (ret)
	krb5_err (context, 1, ret, "resolvning client name");

    if (server_principal_str == NULL)
	krb5_errx (context, 1, "missing server principal");
    ret = krb5_parse_name (context, server_principal_str, &server_principal);
    if (ret)
	krb5_err (context, 1, ret, "resolvning server name");

    /* If no session-enc-type specified on command line and this is an afs */
    /* service ticket, change default of session_enc_type to DES.       */
    if (session_enctype_string == NULL 
	&& strcmp("afs", *server_principal->name.name_string.val) == 0)
	session_enc_type = "des-cbc-crc";

    if (ticket_flags_str) {
	int ticket_flags_int;

	ticket_flags_int = parse_flags(ticket_flags_str,
				       asn1_TicketFlags_units(), 0);
	if (ticket_flags_int <= 0) {
	    krb5_warnx (context, "bad ticket flags: `%s'", ticket_flags_str);
	    print_flags_table (asn1_TicketFlags_units(), stderr);
	    exit (1);
	}
	if (ticket_flags_int)
	    ticket_flags = int2TicketFlags (ticket_flags_int);
    }
}
Esempio n. 17
0
static krb5_error_code
get_keytab(krb5_keytab *keytab)
{
    char kt_name[256];
    krb5_error_code kret;

    HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);

    if (gssapi_krb5_keytab != NULL) {
	kret = krb5_kt_get_name(gssapi_krb5_context,
				gssapi_krb5_keytab,
				kt_name, sizeof(kt_name));
	if (kret == 0)
	    kret = krb5_kt_resolve(gssapi_krb5_context, kt_name, keytab);
    } else
	kret = krb5_kt_default(gssapi_krb5_context, keytab);

    HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);

    return (kret);
}
Esempio n. 18
0
static krb5_error_code
get_key_from_keytab(krb5_context context,
		    krb5_auth_context *auth_context,
		    krb5_ap_req *ap_req,
		    krb5_const_principal server,
		    krb5_keytab keytab,
		    krb5_keyblock **out_key)
{
    krb5_keytab_entry entry;
    krb5_error_code ret;
    int kvno;
    krb5_keytab real_keytab;

    if(keytab == NULL)
	krb5_kt_default(context, &real_keytab);
    else
	real_keytab = keytab;
    
    if (ap_req->ticket.enc_part.kvno)
	kvno = *ap_req->ticket.enc_part.kvno;
    else
	kvno = 0;

    ret = krb5_kt_get_entry (context,
			     real_keytab,
			     server,
			     kvno,
			     ap_req->ticket.enc_part.etype,
			     &entry);
    if(ret)
	goto out;
    ret = krb5_copy_keyblock(context, &entry.keyblock, out_key);
    krb5_kt_free_entry (context, &entry);
out:    
    if(keytab == NULL)
	krb5_kt_close(context, real_keytab);
    
    return ret;
}
Esempio n. 19
0
static krb5_error_code
get_keytab(krb5_context context, krb5_keytab *keytab)
{
    krb5_error_code kret;

    HEIMDAL_MUTEX_lock(&gssapi_keytab_mutex);

    if (_gsskrb5_keytab != NULL) {
	char *name = NULL;

	kret = krb5_kt_get_full_name(context, _gsskrb5_keytab, &name);
	if (kret == 0) {
	    kret = krb5_kt_resolve(context, name, keytab);
	    krb5_xfree(name);
	}
    } else
	kret = krb5_kt_default(context, keytab);

    HEIMDAL_MUTEX_unlock(&gssapi_keytab_mutex);

    return (kret);
}
Esempio n. 20
0
static void
setup_env (krb5_context context, krb5_keytab *kt)
{
    krb5_error_code ret;

    if (keytab_file)
	ret = krb5_kt_resolve (context, keytab_file, kt);
    else
	ret = krb5_kt_default (context, kt);
    if (ret)
	krb5_err (context, 1, ret, "resolving keytab");

    if (client_principal_str == NULL)
	krb5_errx (context, 1, "missing client principal");
    ret = krb5_parse_name (context, client_principal_str, &client_principal);
    if (ret)
	krb5_err (context, 1, ret, "resolvning client name");

    if (server_principal_str == NULL)
	krb5_errx (context, 1, "missing server principal");
    ret = krb5_parse_name (context, server_principal_str, &server_principal);
    if (ret)
	krb5_err (context, 1, ret, "resolvning client name");

    if (ticket_flags_str) {
	int ticket_flags_int;

	ticket_flags_int = parse_flags(ticket_flags_str,
				       asn1_TicketFlags_units(), 0);
	if (ticket_flags_int <= 0) {
	    krb5_warnx (context, "bad ticket flags: `%s'", ticket_flags_str);
	    print_flags_table (asn1_TicketFlags_units(), stderr);
	    exit (1);
	}
	if (ticket_flags_int)
	    ticket_flags = int2TicketFlags (ticket_flags_int);
    }
}
Esempio n. 21
0
int
main(int argc, char **argv)
{
    krb5_context kcontext = NULL;
    krb5_keytab kt = NULL;
    krb5_keytab_entry entry;
    krb5_kt_cursor cursor = NULL;
    krb5_error_code krb5_err;
    int matched = 0;
    
    char svc_name[] = "host";
    int svc_name_len = strlen (svc_name);
    
    
    krb5_err = krb5_init_context(&kcontext);
    if (krb5_err) { goto Error; }
    krb5_err = krb5_kt_default(kcontext, &kt);
    if (krb5_err) { goto Error; }
    krb5_err = krb5_kt_start_seq_get(kcontext, kt, &cursor);
    if (krb5_err) { goto Error; }
    while ((matched == 0) && (krb5_err = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) {
	
	krb5_data *nameData = krb5_princ_name (kcontext, entry.principal);
	if (NULL != nameData->data && svc_name_len == nameData->length
	    && 0 == strncmp (svc_name, nameData->data, nameData->length)) {
	    matched = 1;
	}
        
	krb5_free_keytab_entry_contents(kcontext, &entry);
    }
    
    krb5_err = krb5_kt_end_seq_get(kcontext, kt, &cursor);
 Error:
    if (NULL != kt) { krb5_kt_close (kcontext, kt); }
    if (NULL != kcontext) { krb5_free_context (kcontext); }
    // Return 0 if we got match or -1 if err or no match
    return (0 != krb5_err) ? -1 : matched ? 0 : -1;
}        
Esempio n. 22
0
int print_keytab (const char *in_name)
{
    krb5_error_code err = 0;
    krb5_keytab kt;
    krb5_keytab_entry entry;
    krb5_kt_cursor cursor;
    char keytab_name[BUFSIZ]; /* hopefully large enough for any type */

    if (!err) {
        if (!in_name) {
            err = krb5_kt_default (kcontext, &kt);
            printiferr (err, "while resolving default keytab");
        } else {
            err = krb5_kt_resolve (kcontext, in_name, &kt);
            printiferr (err, "while resolving keytab %s", in_name);
        }
    }

    if (!err) {
        err = krb5_kt_get_name (kcontext, kt, keytab_name, sizeof (keytab_name));
        printiferr (err, "while getting keytab name");
    }

    if (!err) {
        printmsg ("Keytab name: %s\n", keytab_name);
    }

    if (!err) {
        err = krb5_kt_start_seq_get (kcontext, kt, &cursor);
        printiferr (err, "while starting scan of keytab %s", keytab_name);
    }

    if (!err) {
        if (show_entry_timestamps) {
            printmsg ("KVNO Timestamp");
            printfiller (' ', get_timestamp_width () - sizeof ("Timestamp") + 2);
            printmsg ("Principal\n");
            printmsg ("---- ");
            printfiller ('-', get_timestamp_width ());
            printmsg (" ");
            printfiller ('-', 78 - get_timestamp_width () - sizeof ("KVNO"));
            printmsg ("\n");
        } else {
            printmsg("KVNO Principal\n");
            printmsg("---- --------------------------------------------------------------------------\n");
        }
    }

    while (!err) {
        char *principal_name = NULL;

        err = krb5_kt_next_entry (kcontext, kt, &entry, &cursor);
	if (err == KRB5_KT_END) {
	    err = 0;
	    break;
	}
 
        if (!err) {
            err = krb5_unparse_name (kcontext, entry.principal, &principal_name);
            printiferr (err, "while unparsing principal name");
        }
        
        if (!err) {
            printmsg ("%4d ", entry.vno);
            if (show_entry_timestamps) {
                printtime (entry.timestamp);
                printmsg (" ");
            }
            printmsg ("%s", principal_name);
            if (show_enctypes) {
                printmsg (" (%s) ", enctype_to_string (entry.key.enctype));
            }
            if (show_entry_DES_keys) {
                unsigned int i;
                
                printmsg (" (0x");
                for (i = 0; i < entry.key.length; i++) {
                    printmsg ("%02x", entry.key.contents[i]);
                }
                printmsg (")");
            }
            printmsg ("\n");
        }
	printiferr (err, "while scanning keytab %s", keytab_name);

        if (principal_name) { krb5_free_unparsed_name (kcontext, principal_name); }
    }

    if (!err) {
        err = krb5_kt_end_seq_get (kcontext, kt, &cursor);
        printiferr (err, "while ending scan of keytab %s", keytab_name);
    }

    return err ? 1 : 0;
}
Esempio n. 23
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache  ccache;
    krb5_principal principal = NULL;
    int optidx = 0;
    krb5_deltat ticket_life = 0;
#ifdef HAVE_SIGACTION
    struct sigaction sa;
#endif

    setprogname(argv[0]);

    setlocale(LC_ALL, "");
    bindtextdomain("heimdal_kuser", HEIMDAL_LOCALEDIR);
    textdomain("heimdal_kuser");

    ret = krb5_init_context(&context);
    if (ret == KRB5_CONFIG_BADFORMAT)
	errx(1, "krb5_init_context failed to parse configuration file");
    else if (ret)
	errx(1, "krb5_init_context failed: %d", ret);

    if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage(0);

    if (version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    /*
     * Open the keytab now, we use the keytab to determine the principal's
     * realm when the requested principal has no realm.
     */
    if (use_keytab || keytab_str) {
	if (keytab_str)
	    ret = krb5_kt_resolve(context, keytab_str, &kt);
	else
	    ret = krb5_kt_default(context, &kt);
	if (ret)
	    krb5_err(context, 1, ret, "resolving keytab");
    }

    if (pk_enterprise_flag) {
	ret = krb5_pk_enterprise_cert(context, pk_user_id,
				      argv[0], &principal,
				      &ent_user_id);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_pk_enterprise_certs");

	pk_user_id = NULL;

    } else if (anonymous_flag) {

	ret = krb5_make_principal(context, &principal, argv[0],
				  KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME,
				  NULL);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_make_principal");
	krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);

    } else if (use_keytab || keytab_str) {
	get_princ_kt(context, &principal, argv[0]);
    } else {
	get_princ(context, &principal, argv[0]);
    }

    if (fcache_version)
	krb5_set_fcache_version(context, fcache_version);

    if (renewable_flag == -1)
	/* this seems somewhat pointless, but whatever */
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"renewable", FALSE, &renewable_flag);
    if (do_afslog == -1)
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"afslog", TRUE, &do_afslog);

    if (cred_cache)
	ret = krb5_cc_resolve(context, cred_cache, &ccache);
    else {
	if (argc > 1) {
	    char s[1024];
	    ret = krb5_cc_new_unique(context, NULL, NULL, &ccache);
	    if (ret)
		krb5_err(context, 1, ret, "creating cred cache");
	    snprintf(s, sizeof(s), "%s:%s",
		     krb5_cc_get_type(context, ccache),
		     krb5_cc_get_name(context, ccache));
	    setenv("KRB5CCNAME", s, 1);
	} else {
	    ret = krb5_cc_cache_match(context, principal, &ccache);
	    if (ret) {
		const char *type;
		ret = krb5_cc_default(context, &ccache);
		if (ret)
		    krb5_err(context, 1, ret,
			     N_("resolving credentials cache", ""));

		/*
		 * Check if the type support switching, and we do,
		 * then do that instead over overwriting the current
		 * default credential
		 */
		type = krb5_cc_get_type(context, ccache);
		if (krb5_cc_support_switch(context, type)) {
		    krb5_cc_close(context, ccache);
		    ret = get_switched_ccache(context, type, principal,
					      &ccache);
		}
	    }
	}
    }
    if (ret)
	krb5_err(context, 1, ret, N_("resolving credentials cache", ""));

#ifndef NO_AFS
    if (argc > 1 && k_hasafs())
	k_setpag();
#endif

    if (lifetime) {
	int tmp = parse_time(lifetime, "s");
	if (tmp < 0)
	    errx(1, N_("unparsable time: %s", ""), lifetime);

	ticket_life = tmp;
    }

    if (addrs_flag == 0 && extra_addresses.num_strings > 0)
	krb5_errx(context, 1,
		  N_("specifying both extra addresses and "
		     "no addresses makes no sense", ""));
    {
	int i;
	krb5_addresses addresses;
	memset(&addresses, 0, sizeof(addresses));
	for(i = 0; i < extra_addresses.num_strings; i++) {
	    ret = krb5_parse_address(context, extra_addresses.strings[i],
				     &addresses);
	    if (ret == 0) {
		krb5_add_extra_addresses(context, &addresses);
		krb5_free_addresses(context, &addresses);
	    }
	}
	free_getarg_strings(&extra_addresses);
    }

    if (renew_flag || validate_flag) {
	ret = renew_validate(context, renew_flag, validate_flag,
			     ccache, server_str, ticket_life);

#ifndef NO_AFS
	if (ret == 0 && server_str == NULL && do_afslog && k_hasafs())
	    krb5_afslog(context, ccache, NULL, NULL);
#endif

	exit(ret != 0);
    }

    ret = get_new_tickets(context, principal, ccache, ticket_life, 1);
    if (ret)
	exit(1);

#ifndef NO_AFS
    if (ret == 0 && server_str == NULL && do_afslog && k_hasafs())
	krb5_afslog(context, ccache, NULL, NULL);
#endif

    if (argc > 1) {
	struct renew_ctx ctx;
	time_t timeout;

	timeout = ticket_lifetime(context, ccache, principal,
				  server_str, NULL) / 2;

	ctx.context = context;
	ctx.ccache = ccache;
	ctx.principal = principal;
	ctx.ticket_life = ticket_life;
	ctx.timeout = timeout;

#ifdef HAVE_SIGACTION
	memset(&sa, 0, sizeof(sa));
	sigemptyset(&sa.sa_mask);
	sa.sa_handler = handle_siginfo;

	sigaction(SIGINFO, &sa, NULL);
#endif

	ret = simple_execvp_timed(argv[1], argv+1,
				  renew_func, &ctx, timeout);
#define EX_NOEXEC	126
#define EX_NOTFOUND	127
	if (ret == EX_NOEXEC)
	    krb5_warnx(context, N_("permission denied: %s", ""), argv[1]);
	else if (ret == EX_NOTFOUND)
	    krb5_warnx(context, N_("command not found: %s", ""), argv[1]);

	krb5_cc_destroy(context, ccache);
#ifndef NO_AFS
	if (k_hasafs())
	    k_unlog();
#endif
    } else {
	krb5_cc_close(context, ccache);
	ret = 0;
    }
    krb5_free_principal(context, principal);
    if (kt)
	krb5_kt_close(context, kt);
    krb5_free_context(context);
    return ret;
}
Esempio n. 24
0
int
main(int argc, const char **argv)
{
    krb5_context ctx;
    krb5_ccache ccache;
    krb5_creds mcreds, creds;
    krb5_keytab keytab;
    krb5_principal server;
    krb5_verify_init_creds_opt opts;
    int ret;

    ctx = NULL;
    ret = krb5_init_context(&ctx);
    if (ret != 0) {
        crit("error initializing Kerberos: %s", error_message(ret));
        return ret;
    }

    ccache = NULL;
    ret = krb5_cc_default(ctx, &ccache);
    if (ret != 0) {
        crit("error resolving ccache: %s", error_message(ret));
        return ret;
    }

    keytab = NULL;
    ret = krb5_kt_default(ctx, &keytab);
    if (ret != 0) {
        crit("error resolving keytab: %s", error_message(ret));
        return ret;
    }

    server = NULL;
    memset(&mcreds, 0, sizeof(mcreds));
    ret = krb5_cc_get_principal(ctx, ccache, &mcreds.client);
    if (ret != 0) {
        crit("error reading client name from ccache: %s",
             error_message(ret));
        return ret;
    }
    ret = krb5_build_principal_ext(ctx, &mcreds.server,
                                   v5_princ_realm_length(mcreds.client),
                                   v5_princ_realm_contents(mcreds.client),
                                   KRB5_TGS_NAME_SIZE,
                                   KRB5_TGS_NAME,
                                   v5_princ_realm_length(mcreds.client),
                                   v5_princ_realm_contents(mcreds.client),
                                   0);
    if (ret != 0) {
        crit("error building ticket granting server name: %s",
             error_message(ret));
        return ret;
    }

    ret = krb5_cc_retrieve_cred(ctx, ccache, 0, &mcreds, &creds);
    if (ret != 0) {
        crit("error reading ccache: %s", error_message(ret));
        return ret;
    }
    krb5_cc_close(ctx, ccache);

    krb5_verify_init_creds_opt_init(&opts);
    ret = krb5_verify_init_creds(ctx, &creds,
                                 server, keytab, NULL,
                                 &opts);
    if (ret != 0) {
        crit("error verifying creds: %s", error_message(ret));
    } else {
        printf("OK\n");
    }

    krb5_free_context(ctx);

    return ret;
}
Esempio n. 25
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rd_req_ctx(krb5_context context,
		krb5_auth_context *auth_context,
		const krb5_data *inbuf,
		krb5_const_principal server,
		krb5_rd_req_in_ctx inctx,
		krb5_rd_req_out_ctx *outctx)
{
    krb5_error_code ret;
    krb5_ap_req ap_req;
    krb5_rd_req_out_ctx o = NULL;
    krb5_keytab id = NULL, keytab = NULL;
    krb5_principal service = NULL;

    *outctx = NULL;

    o = calloc(1, sizeof(*o));
    if (o == NULL) {
	krb5_set_error_message(context, ENOMEM,
			       N_("malloc: out of memory", ""));
	return ENOMEM;
    }

    if (*auth_context == NULL) {
	ret = krb5_auth_con_init(context, auth_context);
	if (ret)
	    goto out;
    }

    ret = krb5_decode_ap_req(context, inbuf, &ap_req);
    if(ret)
	goto out;

    /* Save that principal that was in the request */
    ret = _krb5_principalname2krb5_principal(context,
					     &o->server,
					     ap_req.ticket.sname,
					     ap_req.ticket.realm);
    if (ret)
	goto out;

    if (ap_req.ap_options.use_session_key &&
	(*auth_context)->keyblock == NULL) {
	ret = KRB5KRB_AP_ERR_NOKEY;
	krb5_set_error_message(context, ret,
			       N_("krb5_rd_req: user to user auth "
				  "without session key given", ""));
	goto out;
    }

    if (inctx && inctx->keytab)
	id = inctx->keytab;

    if((*auth_context)->keyblock){
	ret = krb5_copy_keyblock(context,
				 (*auth_context)->keyblock,
				 &o->keyblock);
	if (ret)
	    goto out;
    } else if(inctx && inctx->keyblock){
	ret = krb5_copy_keyblock(context,
				 inctx->keyblock,
				 &o->keyblock);
	if (ret)
	    goto out;
    } else {

	if(id == NULL) {
	    krb5_kt_default(context, &keytab);
	    id = keytab;
	}
	if (id == NULL)
	    goto out;

	if (server == NULL) {
	    ret = _krb5_principalname2krb5_principal(context,
						     &service,
						     ap_req.ticket.sname,
						     ap_req.ticket.realm);
	    if (ret)
		goto out;
	    server = service;
	}

	ret = get_key_from_keytab(context,
				  &ap_req,
				  server,
				  id,
				  &o->keyblock);
	if (ret) {
	    /* If caller specified a server, fail. */
	    if (service == NULL && (context->flags & KRB5_CTX_F_RD_REQ_IGNORE) == 0)
		goto out;
	    /* Otherwise, fall back to iterating over the keytab. This
	     * have serious performace issues for larger keytab.
	     */
	    o->keyblock = NULL;
	}
    }

    if (o->keyblock) {
	/*
	 * We got an exact keymatch, use that.
	 */

	ret = krb5_verify_ap_req2(context,
				  auth_context,
				  &ap_req,
				  server,
				  o->keyblock,
				  0,
				  &o->ap_req_options,
				  &o->ticket,
				  KRB5_KU_AP_REQ_AUTH);

	if (ret)
	    goto out;

    } else {
	/*
	 * Interate over keytab to find a key that can decrypt the request.
	 */

	krb5_keytab_entry entry;
	krb5_kt_cursor cursor;
	int done = 0, kvno = 0;

	memset(&cursor, 0, sizeof(cursor));

	if (ap_req.ticket.enc_part.kvno)
	    kvno = *ap_req.ticket.enc_part.kvno;

	ret = krb5_kt_start_seq_get(context, id, &cursor);
	if (ret)
	    goto out;

	done = 0;
	while (!done) {
	    krb5_principal p;

	    ret = krb5_kt_next_entry(context, id, &entry, &cursor);
	    if (ret) {
		_krb5_kt_principal_not_found(context, ret, id, o->server,
					     ap_req.ticket.enc_part.etype,
					     kvno);
		krb5_kt_end_seq_get(context, id, &cursor);
		goto out;
	    }

	    if (entry.keyblock.keytype != ap_req.ticket.enc_part.etype) {
		krb5_kt_free_entry (context, &entry);
		continue;
	    }

	    ret = krb5_verify_ap_req2(context,
				      auth_context,
				      &ap_req,
				      server,
				      &entry.keyblock,
				      0,
				      &o->ap_req_options,
				      &o->ticket,
				      KRB5_KU_AP_REQ_AUTH);
	    if (ret) {
		krb5_kt_free_entry(context, &entry);
		continue;
	    }

	    /*
	     * Found a match, save the keyblock for PAC processing,
	     * and update the service principal in the ticket to match
	     * whatever is in the keytab.
	     */

	    ret = krb5_copy_keyblock(context,
				     &entry.keyblock,
				     &o->keyblock);
	    if (ret) {
		krb5_kt_free_entry(context, &entry);
		krb5_kt_end_seq_get(context, id, &cursor);
		goto out;
	    }

	    ret = krb5_copy_principal(context, entry.principal, &p);
	    if (ret) {
		krb5_kt_free_entry(context, &entry);
		krb5_kt_end_seq_get(context, id, &cursor);
		goto out;
	    }
	    krb5_free_principal(context, o->ticket->server);
	    o->ticket->server = p;
	    
	    krb5_kt_free_entry(context, &entry);

	    done = 1;
	}
	krb5_kt_end_seq_get(context, id, &cursor);
    }

    /* If there is a PAC, verify its server signature */
    if (inctx == NULL || inctx->check_pac) {
	krb5_pac pac;
	krb5_data data;

	ret = krb5_ticket_get_authorization_data_type(context,
						      o->ticket,
						      KRB5_AUTHDATA_WIN2K_PAC,
						      &data);
	if (ret == 0) {
	    ret = krb5_pac_parse(context, data.data, data.length, &pac);
	    krb5_data_free(&data);
	    if (ret)
		goto out;

	    ret = krb5_pac_verify(context,
				  pac,
				  o->ticket->ticket.authtime,
				  o->ticket->client,
				  o->keyblock,
				  NULL);
	    krb5_pac_free(context, pac);
	    if (ret == 0)
		o->flags |= KRB5_RD_REQ_OUT_PAC_VALID;
	    ret = 0;
	} else
	    ret = 0;
    }
 out:

    if (ret || outctx == NULL) {
	krb5_rd_req_out_ctx_free(context, o);
    } else
	*outctx = o;

    free_AP_REQ(&ap_req);

    if (service)
	krb5_free_principal(context, service);

    if (keytab)
	krb5_kt_close(context, keytab);

    return ret;
}
Esempio n. 26
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_auth_context ac = NULL;
    krb5_principal c1, c2;
    krb5_authenticator authent;
    krb5_keytab keytab;
    krb5_socket_t sock = rk_INVALID_SOCKET;
    HDB *db = NULL;
    int optidx = 0;
    char *tmp_db;
    krb5_log_facility *fac;
    int nprincs;

    setprogname(argv[0]);

    ret = krb5_init_context(&context);
    if(ret)
	exit(1);

    ret = krb5_openlog(context, "hpropd", &fac);
    if(ret)
	errx(1, "krb5_openlog");
    krb5_set_warn_dest(context, fac);

    if(getarg(args, num_args, argc, argv, &optidx))
	usage(1);

    if(local_realm != NULL)
	krb5_set_default_realm(context, local_realm);

    if(help_flag)
	usage(0);
    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    if (argc != 0)
	usage(1);

    if (database == NULL)
	database = hdb_default_db(context);

    if(from_stdin) {
	sock = STDIN_FILENO;
    } else {
	struct sockaddr_storage ss;
	struct sockaddr *sa = (struct sockaddr *)&ss;
	socklen_t sin_len = sizeof(ss);
	char addr_name[256];
	krb5_ticket *ticket;
	char *server;

	sock = STDIN_FILENO;
#ifdef SUPPORT_INETD
	if (inetd_flag == -1) {
	    if (getpeername (sock, sa, &sin_len) < 0) {
		inetd_flag = 0;
	    } else {
		inetd_flag = 1;
	    }
	}
#else
	inetd_flag = 0;
#endif
	if (!inetd_flag) {
	    mini_inetd (krb5_getportbyname (context, "hprop", "tcp",
					    HPROP_PORT), &sock);
	}
	sin_len = sizeof(ss);
	if(getpeername(sock, sa, &sin_len) < 0)
	    krb5_err(context, 1, errno, "getpeername");

	if (inet_ntop(sa->sa_family,
		      socket_get_address (sa),
		      addr_name,
		      sizeof(addr_name)) == NULL)
	    strlcpy (addr_name, "unknown address",
		     sizeof(addr_name));

	krb5_log(context, fac, 0, "Connection from %s", addr_name);

	ret = krb5_kt_register(context, &hdb_kt_ops);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_kt_register");

	if (ktname != NULL) {
	    ret = krb5_kt_resolve(context, ktname, &keytab);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_kt_resolve %s", ktname);
	} else {
	    ret = krb5_kt_default (context, &keytab);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_kt_default");
	}

	ret = krb5_recvauth(context, &ac, &sock, HPROP_VERSION, NULL,
			    0, keytab, &ticket);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_recvauth");

	ret = krb5_unparse_name(context, ticket->server, &server);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_unparse_name");
	if (strncmp(server, "hprop/", 5) != 0)
	    krb5_errx(context, 1, "ticket not for hprop (%s)", server);

	free(server);
	krb5_free_ticket (context, ticket);

	ret = krb5_auth_con_getauthenticator(context, ac, &authent);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_auth_con_getauthenticator");

	ret = krb5_make_principal(context, &c1, NULL, "kadmin", "hprop", NULL);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_make_principal");
	_krb5_principalname2krb5_principal(context, &c2,
					   authent->cname, authent->crealm);
	if(!krb5_principal_compare(context, c1, c2)) {
	    char *s;
	    ret = krb5_unparse_name(context, c2, &s);
	    if (ret)
		s = unparseable_name;
	    krb5_errx(context, 1, "Unauthorized connection from %s", s);
	}
	krb5_free_principal(context, c1);
	krb5_free_principal(context, c2);

	ret = krb5_kt_close(context, keytab);
	if(ret)
	    krb5_err(context, 1, ret, "krb5_kt_close");
    }

    if(!print_dump) {
	asprintf(&tmp_db, "%s~", database);

	ret = hdb_create(context, &db, tmp_db);
	if(ret)
	    krb5_err(context, 1, ret, "hdb_create(%s)", tmp_db);
	ret = db->hdb_open(context, db, O_RDWR | O_CREAT | O_TRUNC, 0600);
	if(ret)
	    krb5_err(context, 1, ret, "hdb_open(%s)", tmp_db);
    }

    nprincs = 0;
    while(1){
	krb5_data data;
	hdb_entry_ex entry;

	if(from_stdin) {
	    ret = krb5_read_message(context, &sock, &data);
	    if(ret != 0 && ret != HEIM_ERR_EOF)
		krb5_err(context, 1, ret, "krb5_read_message");
	} else {
	    ret = krb5_read_priv_message(context, ac, &sock, &data);
	    if(ret)
		krb5_err(context, 1, ret, "krb5_read_priv_message");
	}

	if(ret == HEIM_ERR_EOF || data.length == 0) {
	    if(!from_stdin) {
		data.data = NULL;
		data.length = 0;
		krb5_write_priv_message(context, ac, &sock, &data);
	    }
	    if(!print_dump) {
		ret = db->hdb_close(context, db);
		if(ret)
		    krb5_err(context, 1, ret, "db_close");
		ret = db->hdb_rename(context, db, database);
		if(ret)
		    krb5_err(context, 1, ret, "db_rename");
	    }
	    break;
	}
	memset(&entry, 0, sizeof(entry));
	ret = hdb_value2entry(context, &data, &entry.entry);
	krb5_data_free(&data);
	if(ret)
	    krb5_err(context, 1, ret, "hdb_value2entry");
	if(print_dump)
	    hdb_print_entry(context, db, &entry, stdout);
	else {
	    ret = db->hdb_store(context, db, 0, &entry);
	    if(ret == HDB_ERR_EXISTS) {
		char *s;
		ret = krb5_unparse_name(context, entry.entry.principal, &s);
		if (ret)
		    s = strdup(unparseable_name);
		krb5_warnx(context, "Entry exists: %s", s);
		free(s);
	    } else if(ret)
		krb5_err(context, 1, ret, "db_store");
	    else
		nprincs++;
	}
	hdb_free_entry(context, &entry);
    }
    if (!print_dump)
	krb5_log(context, fac, 0, "Received %d principals", nprincs);

    if (inetd_flag == 0)
	rk_closesocket(sock);

    exit(0);
}
Esempio n. 27
0
static krb5_error_code
get_new_cache(krb5_context context,
	      krb5_principal client,
	      const char *password,
	      krb5_prompter_fct prompter,
	      const char *keytab,
	      const char *server_name,
	      krb5_ccache *ret_cache)
{
    krb5_error_code ret;
    krb5_creds cred;
    krb5_get_init_creds_opt *opt;
    krb5_ccache id;

    ret = krb5_get_init_creds_opt_alloc (context, &opt);
    if (ret)
	return ret;

    krb5_get_init_creds_opt_set_default_flags(context, "kadmin",
					      krb5_principal_get_realm(context,
								       client),
					      opt);


    krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
    krb5_get_init_creds_opt_set_proxiable (opt, FALSE);

    if(password == NULL && prompter == NULL) {
	krb5_keytab kt;
	if(keytab == NULL)
	    ret = krb5_kt_default(context, &kt);
	else
	    ret = krb5_kt_resolve(context, keytab, &kt);
	if(ret) {
	    krb5_get_init_creds_opt_free(context, opt);
	    return ret;
	}
	ret = krb5_get_init_creds_keytab (context,
					  &cred,
					  client,
					  kt,
					  0,
					  server_name,
					  opt);
	krb5_kt_close(context, kt);
    } else {
	ret = krb5_get_init_creds_password (context,
					    &cred,
					    client,
					    password,
					    prompter,
					    NULL,
					    0,
					    server_name,
					    opt);
    }
    krb5_get_init_creds_opt_free(context, opt);
    switch(ret){
    case 0:
	break;
    case KRB5_LIBOS_PWDINTR:	/* don't print anything if it was just C-c:ed */
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
    case KRB5KRB_AP_ERR_MODIFIED:
	return KADM5_BAD_PASSWORD;
    default:
	return ret;
    }
    ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
    if(ret)
	return ret;
    ret = krb5_cc_initialize (context, id, cred.client);
    if (ret)
	return ret;
    ret = krb5_cc_store_cred (context, id, &cred);
    if (ret)
	return ret;
    krb5_free_cred_contents (context, &cred);
    *ret_cache = id;
    return 0;
}
Esempio n. 28
0
krb5_error_code KRB5_CALLCONV
krb5_get_init_creds_keytab(krb5_context context,
                           krb5_creds *creds,
                           krb5_principal client,
                           krb5_keytab arg_keytab,
                           krb5_deltat start_time,
                           const char *in_tkt_service,
                           krb5_get_init_creds_opt *options)
{
    krb5_error_code ret;
    int use_master;
    krb5_keytab keytab;
    struct errinfo errsave = EMPTY_ERRINFO;

    if (arg_keytab == NULL) {
        if ((ret = krb5_kt_default(context, &keytab)))
            return ret;
    } else {
        keytab = arg_keytab;
    }

    use_master = 0;

    /* first try: get the requested tkt from any kdc */

    ret = get_init_creds_keytab(context, creds, client, keytab, start_time,
                                in_tkt_service, options, &use_master);

    /* check for success */

    if (ret == 0)
        goto cleanup;

    /* If all the kdc's are unavailable fail */

    if ((ret == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE))
        goto cleanup;

    /* if the reply did not come from the master kdc, try again with
       the master kdc */

    if (!use_master) {
        use_master = 1;

        k5_save_ctx_error(context, ret, &errsave);
        ret = get_init_creds_keytab(context, creds, client, keytab,
                                    start_time, in_tkt_service, options,
                                    &use_master);
        if (ret == 0)
            goto cleanup;

        /* If the master is unreachable, return the error from the slave we
         * were able to contact. */
        if (ret == KRB5_KDC_UNREACH || ret == KRB5_REALM_CANT_RESOLVE ||
            ret == KRB5_REALM_UNKNOWN)
            ret = k5_restore_ctx_error(context, &errsave);
    }

    /* at this point, we have a response from the master.  Since we don't
       do any prompting or changing for keytabs, that's it. */

cleanup:
    if (arg_keytab == NULL)
        krb5_kt_close(context, keytab);
    k5_clear_error(&errsave);

    return(ret);
}
Esempio n. 29
0
static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx,
                                               const char *realm_str,
                                               const char *princ_str,
                                               const char *keytab_name,
                                               const krb5_deltat lifetime,
                                               const char **ccname_out,
                                               time_t *expire_time_out)
{
    char *ccname;
    char *realm_name = NULL;
    char *full_princ = NULL;
    char *default_realm = NULL;
    char *tmp_str = NULL;
    krb5_context context = NULL;
    krb5_keytab keytab = NULL;
    krb5_ccache ccache = NULL;
    krb5_principal kprinc;
    krb5_creds my_creds;
    krb5_get_init_creds_opt options;
    krb5_error_code krberr;
    krb5_timestamp kdc_time_offset;
    int canonicalize = 0;
    int kdc_time_offset_usec;
    int ret;

    krberr = krb5_init_context(&context);
    if (krberr) {
        DEBUG(SSSDBG_OP_FAILURE, ("Failed to init kerberos context\n"));
        return krberr;
    }
    DEBUG(SSSDBG_TRACE_INTERNAL, ("Kerberos context initialized\n"));

    krberr = set_child_debugging(context);
    if (krberr != EOK) {
        DEBUG(SSSDBG_MINOR_FAILURE, ("Cannot set krb5_child debugging\n"));
    }

    if (!realm_str) {
        krberr = krb5_get_default_realm(context, &default_realm);
        if (krberr) {
            DEBUG(SSSDBG_OP_FAILURE, ("Failed to get default realm name: %s\n",
                      sss_krb5_get_error_message(context, krberr)));
            goto done;
        }

        realm_name = talloc_strdup(memctx, default_realm);
        krb5_free_default_realm(context, default_realm);
        if (!realm_name) {
            krberr = KRB5KRB_ERR_GENERIC;
            goto done;
        }
    } else {
        realm_name = talloc_strdup(memctx, realm_str);
        if (!realm_name) {
            krberr = KRB5KRB_ERR_GENERIC;
            goto done;
        }
    }

    DEBUG(SSSDBG_TRACE_INTERNAL, ("got realm_name: [%s]\n", realm_name));

    if (princ_str) {
        if (!strchr(princ_str, '@')) {
            full_princ = talloc_asprintf(memctx, "%s@%s",
                                         princ_str, realm_name);
        } else {
            full_princ = talloc_strdup(memctx, princ_str);
        }
    } else {
        char hostname[512];

        ret = gethostname(hostname, 511);
        if (ret == -1) {
            krberr = KRB5KRB_ERR_GENERIC;
            goto done;
        }
        hostname[511] = '\0';

        DEBUG(SSSDBG_TRACE_LIBS, ("got hostname: [%s]\n", hostname));

        ret = select_principal_from_keytab(memctx, hostname, realm_name,
                keytab_name, &full_princ, NULL, NULL);
        if (ret) {
            krberr = KRB5_KT_IOERR;
            goto done;
        }
    }
    if (!full_princ) {
        krberr = KRB5KRB_ERR_GENERIC;
        goto done;
    }
    DEBUG(SSSDBG_CONF_SETTINGS, ("Principal name is: [%s]\n", full_princ));

    krberr = krb5_parse_name(context, full_princ, &kprinc);
    if (krberr) {
        DEBUG(2, ("Unable to build principal: %s\n",
                  sss_krb5_get_error_message(context, krberr)));
        goto done;
    }

    if (keytab_name) {
        krberr = krb5_kt_resolve(context, keytab_name, &keytab);
    } else {
        krberr = krb5_kt_default(context, &keytab);
    }
    DEBUG(SSSDBG_CONF_SETTINGS, ("Using keytab [%s]\n", KEYTAB_CLEAN_NAME));
    if (krberr) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              ("Failed to read keytab file [%s]: %s\n",
               KEYTAB_CLEAN_NAME,
               sss_krb5_get_error_message(context, krberr)));
        goto done;
    }

    /* Verify the keytab */
    ret = sss_krb5_verify_keytab_ex(full_princ, keytab_name, context, keytab);
    if (ret) {
        DEBUG(SSSDBG_OP_FAILURE,
                ("Unable to verify principal is present in the keytab\n"));
        krberr = KRB5_KT_IOERR;
        goto done;
    }

    ccname = talloc_asprintf(memctx, "FILE:%s/ccache_%s", DB_PATH, realm_name);
    if (!ccname) {
        krberr = KRB5KRB_ERR_GENERIC;
        goto done;
    }
    DEBUG(SSSDBG_TRACE_INTERNAL, ("keytab ccname: [%s]\n", ccname));

    krberr = krb5_cc_resolve(context, ccname, &ccache);
    if (krberr) {
        DEBUG(SSSDBG_OP_FAILURE, ("Failed to set cache name: %s\n",
                  sss_krb5_get_error_message(context, krberr)));
        goto done;
    }

    memset(&my_creds, 0, sizeof(my_creds));
    memset(&options, 0, sizeof(options));

    krb5_get_init_creds_opt_set_address_list(&options, NULL);
    krb5_get_init_creds_opt_set_forwardable(&options, 0);
    krb5_get_init_creds_opt_set_proxiable(&options, 0);
    krb5_get_init_creds_opt_set_tkt_life(&options, lifetime);

    tmp_str = getenv("KRB5_CANONICALIZE");
    if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
        DEBUG(SSSDBG_CONF_SETTINGS, ("Will canonicalize principals\n"));
        canonicalize = 1;
    }
    sss_krb5_get_init_creds_opt_set_canonicalize(&options, canonicalize);

    krberr = krb5_get_init_creds_keytab(context, &my_creds, kprinc,
                                        keytab, 0, NULL, &options);
    if (krberr) {
        DEBUG(SSSDBG_FATAL_FAILURE,
              ("Failed to init credentials: %s\n",
               sss_krb5_get_error_message(context, krberr)));
        sss_log(SSS_LOG_ERR,
                "Failed to initialize credentials using keytab [%s]: %s. "
                "Unable to create GSSAPI-encrypted LDAP connection.",
                KEYTAB_CLEAN_NAME,
                sss_krb5_get_error_message(context, krberr));
        goto done;
    }
    DEBUG(SSSDBG_TRACE_INTERNAL, ("credentials initialized\n"));

    /* Use updated principal if changed due to canonicalization. */
    krberr = krb5_cc_initialize(context, ccache, my_creds.client);
    if (krberr) {
        DEBUG(SSSDBG_OP_FAILURE, ("Failed to init ccache: %s\n",
                  sss_krb5_get_error_message(context, krberr)));
        goto done;
    }

    krberr = krb5_cc_store_cred(context, ccache, &my_creds);
    if (krberr) {
        DEBUG(SSSDBG_OP_FAILURE, ("Failed to store creds: %s\n",
                  sss_krb5_get_error_message(context, krberr)));
        goto done;
    }
    DEBUG(SSSDBG_TRACE_INTERNAL, ("credentials stored\n"));

#ifdef HAVE_KRB5_GET_TIME_OFFSETS
    krberr = krb5_get_time_offsets(context, &kdc_time_offset,
            &kdc_time_offset_usec);
    if (krberr) {
        DEBUG(SSSDBG_OP_FAILURE, ("Failed to get KDC time offset: %s\n",
                  sss_krb5_get_error_message(context, krberr)));
        kdc_time_offset = 0;
    } else {
        if (kdc_time_offset_usec > 0) {
            kdc_time_offset++;
        }
    }
    DEBUG(SSSDBG_TRACE_INTERNAL, ("Got KDC time offset\n"));
#else
    /* If we don't have this function, just assume no offset */
    kdc_time_offset = 0;
#endif

    krberr = 0;
    *ccname_out = ccname;
    *expire_time_out = my_creds.times.endtime - kdc_time_offset;

done:
    if (krberr != 0) KRB5_SYSLOG(krberr);
    if (keytab) krb5_kt_close(context, keytab);
    if (context) krb5_free_context(context);
    return krberr;
}
Esempio n. 30
0
static krb5_error_code
ccache_init_system(void)
{
    kcm_ccache ccache;
    krb5_error_code ret;

    if (system_cache_name == NULL)
	system_cache_name = kcm_system_config_get_string("cc_name");

    ret = kcm_ccache_new(kcm_context,
			 system_cache_name ? system_cache_name : "SYSTEM",
			 &ccache);
    if (ret)
	return ret;

    ccache->flags |= KCM_FLAGS_OWNER_IS_SYSTEM;
    ccache->flags |= KCM_FLAGS_USE_KEYTAB;

    ret = parse_owners(ccache);
    if (ret)
	return ret;

    ret = krb5_parse_name(kcm_context, system_principal, &ccache->client);
    if (ret) {
	kcm_release_ccache(kcm_context, ccache);
	return ret;
    }

    if (system_server == NULL)
	system_server = kcm_system_config_get_string("server");

    if (system_server != NULL) {
	ret = krb5_parse_name(kcm_context, system_server, &ccache->server);
	if (ret) {
	    kcm_release_ccache(kcm_context, ccache);
	    return ret;
	}
    }

    if (system_keytab == NULL)
	system_keytab = kcm_system_config_get_string("keytab_name");

    if (system_keytab != NULL) {
	ret = krb5_kt_resolve(kcm_context, system_keytab, &ccache->key.keytab);
    } else {
	ret = krb5_kt_default(kcm_context, &ccache->key.keytab);
    }
    if (ret) {
	kcm_release_ccache(kcm_context, ccache);
	return ret;
    }

    if (renew_life == NULL)
	renew_life = kcm_system_config_get_string("renew_life");

    if (renew_life == NULL)
	renew_life = "1 month";

    if (renew_life != NULL) {
	ccache->renew_life = parse_time(renew_life, "s");
	if (ccache->renew_life < 0) {
	    kcm_release_ccache(kcm_context, ccache);
	    return EINVAL;
	}
    }

    if (ticket_life == NULL)
	ticket_life = kcm_system_config_get_string("ticket_life");

    if (ticket_life != NULL) {
	ccache->tkt_life = parse_time(ticket_life, "s");
	if (ccache->tkt_life < 0) {
	    kcm_release_ccache(kcm_context, ccache);
	    return EINVAL;
	}
    }

    if (system_perms == NULL)
	system_perms = kcm_system_config_get_string("mode");

    if (system_perms != NULL) {
	int mode;

	if (sscanf(system_perms, "%o", &mode) != 1)
	    return EINVAL;

	ccache->mode = mode;
    }

    if (disallow_getting_krbtgt == -1) {
	disallow_getting_krbtgt =
	    krb5_config_get_bool_default(kcm_context, NULL, FALSE, "kcm",
					 "disallow-getting-krbtgt", NULL);
    }

    /* enqueue default actions for credentials cache */
    ret = kcm_ccache_enqueue_default(kcm_context, ccache, NULL);

    kcm_release_ccache(kcm_context, ccache); /* retained by event queue */

    return ret;
}