static int
pg_krb5_init(void)
{
	krb5_error_code retval;
	char	   *khostname;

	if (pg_krb5_initialised)
		return STATUS_OK;

	retval = krb5_init_context(&pg_krb5_context);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos initialization returned error %d",
						retval)));
		com_err("postgres", retval, "while initializing krb5");
		return STATUS_ERROR;
	}

	retval = krb5_kt_resolve(pg_krb5_context, pg_krb_server_keyfile, &pg_krb5_keytab);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos keytab resolving returned error %d",
						retval)));
		com_err("postgres", retval, "while resolving keytab file \"%s\"",
				pg_krb_server_keyfile);
		krb5_free_context(pg_krb5_context);
		return STATUS_ERROR;
	}

	/*
	 * If no hostname was specified, pg_krb_server_hostname is already NULL.
	 * If it's set to blank, force it to NULL.
	 */
	khostname = pg_krb_server_hostname;
	if (khostname && khostname[0] == '\0')
		khostname = NULL;

	retval = krb5_sname_to_principal(pg_krb5_context,
									 khostname,
									 pg_krb_srvnam,
									 KRB5_NT_SRV_HST,
									 &pg_krb5_server);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d",
		 khostname ? khostname : "server hostname", pg_krb_srvnam, retval)));
		com_err("postgres", retval,
		"while getting server principal for server \"%s\" for service \"%s\"",
				khostname ? khostname : "server hostname", pg_krb_srvnam);
		krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
		krb5_free_context(pg_krb5_context);
		return STATUS_ERROR;
	}

	pg_krb5_initialised = 1;
	return STATUS_OK;
}
Exemple #2
0
int
main(int argc, char **argv)
{
    krb5_principal princ;
    krb5_int32 type;
    const char *service, *hostname;
    char *name;

    /* Parse arguments. */
    assert(argc == 4);
    hostname = argv[1];
    service = argv[2];
    if (strcmp(argv[3], "unknown") == 0)
        type = KRB5_NT_UNKNOWN;
    else if (strcmp(argv[3], "srv-hst") == 0)
        type = KRB5_NT_SRV_HST;
    else
        abort();

    check(krb5_init_context(&ctx));
    check(krb5_sname_to_principal(ctx, hostname, service, type, &princ));
    check(krb5_unparse_name(ctx, princ, &name));
    printf("%s\n", name);

    krb5_free_unparsed_name(ctx, name);
    krb5_free_principal(ctx, princ);
    krb5_free_context(ctx);
    return 0;
}
Exemple #3
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_validated_creds(krb5_context context,
			 krb5_creds *creds,
			 krb5_principal client,
			 krb5_ccache ccache,
			 char *service)
{
    krb5_verify_init_creds_opt vopt;
    krb5_principal server;
    krb5_error_code ret;

    if (krb5_principal_compare(context, creds->client, client) != TRUE) {
	krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
			       N_("Validation credentials and client "
				  "doesn't match", ""));
	return KRB5_PRINC_NOMATCH;
    }

    ret = krb5_sname_to_principal (context, NULL, service, 
				   KRB5_NT_SRV_HST, &server);
    if(ret)
	return ret;

    krb5_verify_init_creds_opt_init(&vopt);

    ret = krb5_verify_init_creds(context, creds, server, NULL, NULL, &vopt);
    krb5_free_principal(context, server);

    return ret;
}
Exemple #4
0
static void
get_creds(krb5_context context, const char *keytab_str,
	  krb5_ccache *cache, const char *serverhost)
{
    krb5_keytab keytab;
    krb5_principal client;
    krb5_error_code ret;
    krb5_get_init_creds_opt *init_opts;
    krb5_creds creds;
    char *server;
    char keytab_buf[256];
    int aret;

    if (keytab_str == NULL) {
	ret = krb5_kt_default_name (context, keytab_buf, sizeof(keytab_buf));
	if (ret)
	    krb5_err (context, 1, ret, "krb5_kt_default_name");
	keytab_str = keytab_buf;
    }

    ret = krb5_kt_resolve(context, keytab_str, &keytab);
    if(ret)
	krb5_err(context, 1, ret, "%s", keytab_str);


    ret = krb5_sname_to_principal (context, slave_str, IPROP_NAME,
				   KRB5_NT_SRV_HST, &client);
    if (ret) krb5_err(context, 1, ret, "krb5_sname_to_principal");

    ret = krb5_get_init_creds_opt_alloc(context, &init_opts);
    if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");

    aret = asprintf (&server, "%s/%s", IPROP_NAME, serverhost);
    if (aret == -1 || server == NULL)
	krb5_errx (context, 1, "malloc: no memory");

    ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
				     0, server, init_opts);
    free (server);
    krb5_get_init_creds_opt_free(context, init_opts);
    if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");

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

    ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, cache);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_new_unique");

    ret = krb5_cc_initialize(context, *cache, client);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_initialize");

    ret = krb5_cc_store_cred(context, *cache, &creds);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred");

    krb5_free_cred_contents(context, &creds);
    krb5_free_principal(context, client);
}
Exemple #5
0
void
kerberos5_forward(kstream ks)
{
    krb5_error_code r;
    krb5_ccache ccache;
    krb5_principal client = 0;
    krb5_principal server = 0;
    krb5_data forw_creds;

    forw_creds.data = 0;

    if ((r = krb5_cc_default(k5_context, &ccache))) {
      com_err(NULL, r, "Kerberos V5: could not get default ccache");
      return;
    }

    if ((r = krb5_cc_get_principal(k5_context, ccache, &client))) {
      com_err(NULL, r, "Kerberos V5: could not get default principal");
      goto cleanup;
    }

    if ((r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME,
				     KRB5_NT_SRV_HST, &server))) {
      com_err(NULL, r, "Kerberos V5: could not make server principal");
      goto cleanup;
    }

    if ((r = krb5_auth_con_genaddrs(k5_context, auth_context, ks->fd,
			    KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR))) {
      com_err(NULL, r, "Kerberos V5: could not gen local full address");
      goto cleanup;
    }

    if (r = krb5_fwd_tgt_creds(k5_context, auth_context, 0, client, server,
			        ccache, forwardable_flag, &forw_creds)) {
      com_err(NULL, r, "Kerberos V5: error getting forwarded creds");
      goto cleanup;
    }
    
    /* Send forwarded credentials */
    if (!Data(ks, KRB_FORWARD, forw_creds.data, forw_creds.length)) {
      MessageBox(HWND_DESKTOP,
		 "Not enough room for authentication data", "",
		 MB_OK | MB_ICONEXCLAMATION);
    }
    
cleanup:
    if (client)
      krb5_free_principal(k5_context, client);
    if (server)
      krb5_free_principal(k5_context, server);
#if 0 /* XXX */
	if (forw_creds.data)
      free(forw_creds.data);
#endif
    krb5_cc_close(k5_context, ccache);
}
Exemple #6
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);
}
Exemple #7
0
static PyKAdminObject *_kadmin_init_with_keytab(PyObject *self, PyObject *args) {

    PyKAdminObject *kadmin = PyKAdminObject_create();
    PyObject *db_args_dict = NULL;
    kadm5_ret_t retval = KADM5_OK;
    krb5_error_code code = 0;

    krb5_principal princ = NULL;
    char *client_name    = NULL;
    char *keytab_name    = NULL;
    char **db_args       = NULL;

    kadm5_config_params *params = calloc(0x1, sizeof(kadm5_config_params));

    if (!PyArg_ParseTuple(args, "|zzO!", &client_name, &keytab_name, &PyDict_Type, &db_args_dict))
        return NULL; 

    db_args = _kadmin_dict_to_db_args(db_args_dict);

    if (keytab_name == NULL) {
        keytab_name = "/etc/krb5.keytab";
    }
  
    if (client_name == NULL) {
        
        code = krb5_sname_to_principal(kadmin->context, NULL, "host", KRB5_NT_SRV_HST, &princ);
        if (code) { PyKAdmin_RETURN_ERROR(code, "krb5_sname_to_principal"); }
        
        code = krb5_unparse_name(kadmin->context, princ, &client_name);
        if (code) { PyKAdmin_RETURN_ERROR(code, "krb5_unparse_name"); }

        krb5_free_principal(kadmin->context, princ);
    }


    retval = kadm5_init_with_skey(
                kadmin->context, 
                client_name, 
                keytab_name, 
                service_name, 
                params,
                struct_version, 
                api_version, 
                db_args, 
                &kadmin->server_handle);

    if (db_args) 
        _kadmin_free_db_args(db_args);

    if (retval != KADM5_OK) { PyKAdmin_RETURN_ERROR(retval, "kadm5_init_with_skey"); }



    Py_XINCREF(kadmin);
    return kadmin;
}
Exemple #8
0
static int
do_v5 (const char *host,
       int port,
       const char *user,
       const char *filename,
       const char *header_str,
       int leavep,
       int verbose,
       int forkp)
{
    krb5_error_code ret;
    krb5_auth_context auth_context = NULL;
    krb5_principal server;
    const char *estr;
    int s;

    s = do_connect (host, port, 1);
    if (s < 0)
	return 1;

    ret = krb5_sname_to_principal (context,
				   host,
				   "pop",
				   KRB5_NT_SRV_HST,
				   &server);
    if (ret) {
	estr = krb5_get_error_message(context, ret);
	warnx ("krb5_sname_to_principal: %s", estr);
	krb5_free_error_message(context, estr);
	return 1;
    }

    ret = krb5_sendauth (context,
			 &auth_context,
			 &s,
			 "KPOPV1.0",
			 NULL,
			 server,
			 0,
			 NULL,
			 NULL,
			 NULL,
			 NULL,
			 NULL,
			 NULL);
    krb5_free_principal (context, server);
    if (ret) {
	estr = krb5_get_error_message(context, ret);
	warnx ("krb5_sendauth: %s", estr);
	krb5_free_error_message(context, estr);
	return 1;
    }
    return doit (s, host, user, filename, header_str, leavep, verbose, forkp);
}
Exemple #9
0
int
kssl_tgt_is_available(KSSL_CTX *kssl_ctx)
{
	krb5_error_code		krb5rc = KRB5KRB_ERR_GENERIC;
	krb5_context		krb5context = NULL;
	krb5_ccache 		krb5ccdef = NULL;
	krb5_creds		krb5creds, *krb5credsp = NULL;
	int                     rc = 0;

	memset((char *)&krb5creds, 0, sizeof(krb5creds));

	if (!kssl_ctx)
		return (0);

	if (!kssl_ctx->service_host)
		return (0);

	if ((krb5rc = krb5_init_context(&krb5context)) != 0)
		goto err;

	if ((krb5rc = krb5_sname_to_principal(
	    krb5context, kssl_ctx->service_host,
	    (kssl_ctx->service_name) ? kssl_ctx->service_name : KRB5SVC,
	    KRB5_NT_SRV_HST, &krb5creds.server)) != 0)
		goto err;

	if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0)
		goto err;

	if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
	    &krb5creds.client)) != 0)
		goto err;

	if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
	    &krb5creds, &krb5credsp)) != 0)
		goto err;

	rc = 1;

	err:
#ifdef KSSL_DEBUG
	kssl_ctx_show(kssl_ctx);
#endif	/* KSSL_DEBUG */

	if (krb5creds.client)
		krb5_free_principal(krb5context, krb5creds.client);
	if (krb5creds.server)
		krb5_free_principal(krb5context, krb5creds.server);
	if (krb5context)
		krb5_free_context(krb5context);
	return (rc);
}
Exemple #10
0
static int
pg_krb5_init(void)
{
	krb5_error_code retval;

	if (pg_krb5_initialised)
		return STATUS_OK;

	retval = krb5_init_context(&pg_krb5_context);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos initialization returned error %d",
						retval)));
		com_err("postgres", retval, "while initializing krb5");
		return STATUS_ERROR;
	}

	retval = krb5_kt_resolve(pg_krb5_context, pg_krb_server_keyfile, &pg_krb5_keytab);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos keytab resolving returned error %d",
						retval)));
		com_err("postgres", retval, "while resolving keytab file \"%s\"",
				pg_krb_server_keyfile);
		krb5_free_context(pg_krb5_context);
		return STATUS_ERROR;
	}

	retval = krb5_sname_to_principal(pg_krb5_context, NULL, PG_KRB_SRVNAM,
									 KRB5_NT_SRV_HST, &pg_krb5_server);
	if (retval)
	{
		ereport(LOG,
		 (errmsg("Kerberos sname_to_principal(\"%s\") returned error %d",
				 PG_KRB_SRVNAM, retval)));
		com_err("postgres", retval,
				"while getting server principal for service \"%s\"",
				PG_KRB_SRVNAM);
		krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
		krb5_free_context(pg_krb5_context);
		return STATUS_ERROR;
	}

	pg_krb5_initialised = 1;
	return STATUS_OK;
}
Exemple #11
0
static krb5_error_code
verify_common (krb5_context context,
	       krb5_principal principal,
	       krb5_ccache ccache,
	       krb5_keytab keytab,
	       krb5_boolean secure,
	       const char *service,
	       krb5_creds cred)
{
    krb5_error_code ret;
    krb5_principal server;
    krb5_verify_init_creds_opt vopt;
    krb5_ccache id;

    ret = krb5_sname_to_principal (context, NULL, service, KRB5_NT_SRV_HST,
				   &server);
    if(ret)
	return ret;

    krb5_verify_init_creds_opt_init(&vopt);
    krb5_verify_init_creds_opt_set_ap_req_nofail(&vopt, secure);

    ret = krb5_verify_init_creds(context,
				 &cred,
				 server,
				 keytab,
				 NULL,
				 &vopt);
    krb5_free_principal(context, server);
    if(ret)
	return ret;
    if(ccache == NULL)
	ret = krb5_cc_default (context, &id);
    else
	id = ccache;
    if(ret == 0){
	ret = krb5_cc_initialize(context, id, principal);
	if(ret == 0){
	    ret = krb5_cc_store_cred(context, id, &cred);
	}
	if(ccache == NULL)
	    krb5_cc_close(context, id);
    }
    krb5_free_cred_contents(context, &cred);
    return ret;
}
Exemple #12
0
OM_uint32
_gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
		    int use_dns, krb5_const_principal sourcename, gss_name_t targetname,
		    krb5_principal *out)
{
    krb5_principal p = (krb5_principal)targetname;
    krb5_error_code ret;
    char *hostname = NULL, *service;

    *minor_status = 0;

    /* If its not a hostname */
    if (krb5_principal_get_type(context, p) != MAGIC_HOSTBASED_NAME_TYPE) {
	ret = krb5_copy_principal(context, p, out);
    } else if (!use_dns) {
	ret = krb5_copy_principal(context, p, out);
	if (ret)
	    goto out;
	krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST);
	if (sourcename)
	    ret = krb5_principal_set_realm(context, *out, sourcename->realm);
    } else {
	if (p->name.name_string.len == 0)
	    return GSS_S_BAD_NAME;
	else if (p->name.name_string.len > 1)
	    hostname = p->name.name_string.val[1];

	service = p->name.name_string.val[0];

	ret = krb5_sname_to_principal(context,
				      hostname,
				      service,
				      KRB5_NT_SRV_HST,
				      out);
    }

 out:
    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    return 0;
}
Exemple #13
0
static int
doit_v5 (char *host, int port)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_auth_context auth_context = NULL;
    krb5_principal server;
    int s = get_socket (host, port);

    ret = krb5_init_context (&context);
    if (ret)
	errx (1, "krb5_init_context failed: %d", ret);

    ret = krb5_sname_to_principal (context,
				   host,
				   "pop",
				   KRB5_NT_SRV_HST,
				   &server);
    if (ret) {
	warnx ("krb5_sname_to_principal: %s",
	       krb5_get_err_text (context, ret));
	return 1;
    }
    ret = krb5_sendauth (context,
			 &auth_context,
			 &s,
			 "KPOPV1.0",
			 NULL,
			 server,
			 0,
			 NULL,
			 NULL,
			 NULL,
			 NULL,
			 NULL,
			 NULL);
     if (ret) {
	 warnx ("krb5_sendauth: %s",
		krb5_get_err_text (context, ret));
	 return 1;
     }
     loop (s);
     return 0;
}
Exemple #14
0
OM_uint32
_gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context,
		    gss_const_name_t targetname, krb5_principal *out)
{
    krb5_const_principal p = (krb5_const_principal)targetname;
    krb5_error_code ret;
    char *hostname = NULL, *service;
    int type;
    const char *comp;

    *minor_status = 0;

    /* If its not a hostname */
    type = krb5_principal_get_type(context, p);
    comp = krb5_principal_get_comp_string(context, p, 0);
    if (type == KRB5_NT_SRV_HST || type == KRB5_NT_SRV_HST_NEEDS_CANON ||
	(type == KRB5_NT_UNKNOWN && comp != NULL && strcmp(comp, "host") == 0)) {
	if (p->name.name_string.len == 0)
	    return GSS_S_BAD_NAME;
	else if (p->name.name_string.len > 1)
	    hostname = p->name.name_string.val[1];

	service = p->name.name_string.val[0];

	ret = krb5_sname_to_principal(context,
				      hostname,
				      service,
				      KRB5_NT_SRV_HST,
				      out);
    } else {
	ret = krb5_copy_principal(context, p, out);
    }

    if (ret) {
	*minor_status = ret;
	return GSS_S_FAILURE;
    }

    return 0;
}
Exemple #15
0
krb5_error_code KRB5_CALLCONV
krb5_mk_req(krb5_context context, krb5_auth_context *auth_context,
	    krb5_flags ap_req_options, char *service, char *hostname,
	    krb5_data *in_data, krb5_ccache ccache, krb5_data *outbuf)
{
    krb5_error_code 	  retval;
    krb5_principal	  server;
    krb5_creds 		* credsp;
    krb5_creds 		  creds;

    retval = krb5_sname_to_principal(context, hostname, service,
				     KRB5_NT_SRV_HST, &server);
    if (retval)
      return retval;

    /* obtain ticket & session key */
    memset((char *)&creds, 0, sizeof(creds));
    if ((retval = krb5_copy_principal(context, server, &creds.server)))
	goto cleanup_princ;

    if ((retval = krb5_cc_get_principal(context, ccache, &creds.client)) != 0)
	goto cleanup_creds;

    if ((retval = krb5_get_credentials(context, 0,
				       ccache, &creds, &credsp)) != 0)
	goto cleanup_creds;

    retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
				  in_data, credsp, outbuf);

    krb5_free_creds(context, credsp);

cleanup_creds:
    krb5_free_cred_contents(context, &creds);

cleanup_princ:
    krb5_free_principal(context, server);

    return retval;
}
Exemple #16
0
/*
 * pg_krb5_sendauth -- client routine to send authentication information to
 *					   the server
 */
static int
pg_krb5_sendauth(PGconn *conn)
{
	krb5_error_code retval;
	int			ret;
	krb5_principal server;
	krb5_auth_context auth_context = NULL;
	krb5_error *err_ret = NULL;
	struct krb5_info info;

	info.pg_krb5_initialised = 0;

	if (!(conn->pghost && conn->pghost[0] != '\0'))
	{
		printfPQExpBuffer(&conn->errorMessage,
						  libpq_gettext("host name must be specified\n"));
		return STATUS_ERROR;
	}

	ret = pg_krb5_init(&conn->errorMessage, &info);
	if (ret != STATUS_OK)
		return ret;

	retval = krb5_sname_to_principal(info.pg_krb5_context, conn->pghost,
									 conn->krbsrvname,
									 KRB5_NT_SRV_HST, &server);
	if (retval)
	{
		printfPQExpBuffer(&conn->errorMessage,
						  "pg_krb5_sendauth: krb5_sname_to_principal: %s\n",
						  error_message(retval));
		pg_krb5_destroy(&info);
		return STATUS_ERROR;
	}

	/*
	 * libpq uses a non-blocking socket. But kerberos needs a blocking socket,
	 * and we have to block somehow to do mutual authentication anyway. So we
	 * temporarily make it blocking.
	 */
	if (!pg_set_block(conn->sock))
	{
		char		sebuf[256];

		printfPQExpBuffer(&conn->errorMessage,
						  libpq_gettext("could not set socket to blocking mode: %s\n"), pqStrerror(errno, sebuf, sizeof(sebuf)));
		krb5_free_principal(info.pg_krb5_context, server);
		pg_krb5_destroy(&info);
		return STATUS_ERROR;
	}

	retval = krb5_sendauth(info.pg_krb5_context, &auth_context,
					  (krb5_pointer) & conn->sock, (char *) conn->krbsrvname,
						   info.pg_krb5_client, server,
						   AP_OPTS_MUTUAL_REQUIRED,
						   NULL, 0,		/* no creds, use ccache instead */
						   info.pg_krb5_ccache, &err_ret, NULL, NULL);
	if (retval)
	{
		if (retval == KRB5_SENDAUTH_REJECTED && err_ret)
		{
#if defined(HAVE_KRB5_ERROR_TEXT_DATA)
			printfPQExpBuffer(&conn->errorMessage,
				  libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
							  (int) err_ret->text.length, err_ret->text.data);
#elif defined(HAVE_KRB5_ERROR_E_DATA)
			printfPQExpBuffer(&conn->errorMessage,
				  libpq_gettext("Kerberos 5 authentication rejected: %*s\n"),
							  (int) err_ret->e_data->length,
							  (const char *) err_ret->e_data->data);
#else
#error "bogus configuration"
#endif
		}
		else
		{
			printfPQExpBuffer(&conn->errorMessage,
							  "krb5_sendauth: %s\n", error_message(retval));
		}

		if (err_ret)
			krb5_free_error(info.pg_krb5_context, err_ret);

		ret = STATUS_ERROR;
	}

	krb5_free_principal(info.pg_krb5_context, server);

	if (!pg_set_noblock(conn->sock))
	{
		char		sebuf[256];

		printfPQExpBuffer(&conn->errorMessage,
		libpq_gettext("could not restore non-blocking mode on socket: %s\n"),
						  pqStrerror(errno, sebuf, sizeof(sebuf)));
		ret = STATUS_ERROR;
	}
	pg_krb5_destroy(&info);

	return ret;
}
Exemple #17
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_verify_init_creds(krb5_context context,
		       krb5_creds *creds,
		       krb5_principal ap_req_server,
		       krb5_keytab ap_req_keytab,
		       krb5_ccache *ccache,
		       krb5_verify_init_creds_opt *options)
{
    krb5_error_code ret;
    krb5_data req;
    krb5_ccache local_ccache = NULL;
    krb5_creds *new_creds = NULL;
    krb5_auth_context auth_context = NULL;
    krb5_principal server = NULL;
    krb5_keytab keytab = NULL;

    krb5_data_zero (&req);

    if (ap_req_server == NULL) {
	char local_hostname[MAXHOSTNAMELEN];

	if (gethostname (local_hostname, sizeof(local_hostname)) < 0) {
	    ret = errno;
	    krb5_set_error_message (context, ret, "gethostname: %s",
				    strerror(ret));
	    return ret;
	}

	ret = krb5_sname_to_principal (context,
				       local_hostname,
				       "host",
				       KRB5_NT_SRV_HST,
				       &server);
	if (ret)
	    goto cleanup;
    } else
	server = ap_req_server;

    if (ap_req_keytab == NULL) {
	ret = krb5_kt_default (context, &keytab);
	if (ret)
	    goto cleanup;
    } else
	keytab = ap_req_keytab;

    if (ccache && *ccache)
	local_ccache = *ccache;
    else {
	ret = krb5_cc_new_unique(context, krb5_cc_type_memory,
				 NULL, &local_ccache);
	if (ret)
	    goto cleanup;
	ret = krb5_cc_initialize (context,
				  local_ccache,
				  creds->client);
	if (ret)
	    goto cleanup;
	ret = krb5_cc_store_cred (context,
				  local_ccache,
				  creds);
	if (ret)
	    goto cleanup;
    }

    if (!krb5_principal_compare (context, server, creds->server)) {
	krb5_creds match_cred;

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

	match_cred.client = creds->client;
	match_cred.server = server;

	ret = krb5_get_credentials (context,
				    0,
				    local_ccache,
				    &match_cred,
				    &new_creds);
	if (ret) {
	    if (fail_verify_is_ok (context, options))
		ret = 0;
	    goto cleanup;
	}
	creds = new_creds;
    }

    ret = krb5_mk_req_extended (context,
				&auth_context,
				0,
				NULL,
				creds,
				&req);

    krb5_auth_con_free (context, auth_context);
    auth_context = NULL;

    if (ret)
	goto cleanup;

    ret = krb5_rd_req (context,
		       &auth_context,
		       &req,
		       server,
		       keytab,
		       0,
		       NULL);

    if (ret == KRB5_KT_NOTFOUND && fail_verify_is_ok (context, options))
	ret = 0;
cleanup:
    if (auth_context)
	krb5_auth_con_free (context, auth_context);
    krb5_data_free (&req);
    if (new_creds != NULL)
	krb5_free_creds (context, new_creds);
    if (ap_req_server == NULL && server)
	krb5_free_principal (context, server);
    if (ap_req_keytab == NULL && keytab)
	krb5_kt_close (context, keytab);
    if (local_ccache != NULL
	&&
	(ccache == NULL
	 || (ret != 0 && *ccache == NULL)))
	krb5_cc_destroy (context, local_ccache);

    if (ret == 0 && ccache != NULL && *ccache == NULL)
	*ccache = local_ccache;

    return ret;
}
Exemple #18
0
static void
add_slave (krb5_context context, krb5_keytab keytab, slave **root, int fd)
{
    krb5_principal server;
    krb5_error_code ret;
    slave *s;
    socklen_t addr_len;
    krb5_ticket *ticket = NULL;
    char hostname[128];

    s = malloc(sizeof(*s));
    if (s == NULL) {
	krb5_warnx (context, "add_slave: no memory");
	return;
    }
    s->name = NULL;
    s->ac = NULL;

    addr_len = sizeof(s->addr);
    s->fd = accept (fd, (struct sockaddr *)&s->addr, &addr_len);
    if (s->fd < 0) {
	krb5_warn (context, errno, "accept");
	goto error;
    }
    gethostname(hostname, sizeof(hostname));
    ret = krb5_sname_to_principal (context, hostname, IPROP_NAME,
				   KRB5_NT_SRV_HST, &server);
    if (ret) {
	krb5_warn (context, ret, "krb5_sname_to_principal");
	goto error;
    }

    ret = krb5_recvauth (context, &s->ac, &s->fd,
			 IPROP_VERSION, server, 0, keytab, &ticket);
    krb5_free_principal (context, server);
    if (ret) {
	krb5_warn (context, ret, "krb5_recvauth");
	goto error;
    }
    ret = krb5_unparse_name (context, ticket->client, &s->name);
    if (ret) {
	krb5_warn (context, ret, "krb5_unparse_name");
	goto error;
    }
    if (check_acl (context, s->name)) {
	krb5_warnx (context, "%s not in acl", s->name);
	goto error;
    }
    krb5_free_ticket (context, ticket);
    ticket = NULL;

    {
	slave *l = *root;

	while (l) {
	    if (strcmp(l->name, s->name) == 0)
		break;
	    l = l->next;
	}
	if (l) {
	    if (l->flags & SLAVE_F_DEAD) {
		remove_slave(context, l, root);
	    } else {
		krb5_warnx (context, "second connection from %s", s->name);
		goto error;
	    }
	}
    }

    krb5_warnx (context, "connection from %s", s->name);

    s->version = 0;
    s->flags = 0;
    slave_seen(s);
    s->next = *root;
    *root = s;
    return;
error:
    remove_slave(context, s, root);
}
Exemple #19
0
static void
get_tickets(krb5_context context)
{
    char *def_realm, *server;
    krb5_error_code retval;
    krb5_keytab keytab = NULL;
    krb5_principal server_princ = NULL;

    /* Figure out what tickets we'll be using to send. */
    retval = krb5_sname_to_principal(context, NULL, NULL, KRB5_NT_SRV_HST,
                                     &my_principal);
    if (retval) {
        com_err(progname, errno, _("while setting client principal name"));
        exit(1);
    }
    if (realm != NULL) {
        retval = krb5_set_principal_realm(context, my_principal, realm);
        if (retval) {
            com_err(progname, errno,
                    _("while setting client principal realm"));
            exit(1);
        }
    } else if (krb5_is_referral_realm(krb5_princ_realm(context,
                                                       my_principal))) {
        /* We're going to use this as a client principal, so it can't have the
         * referral realm.  Use the default realm instead. */
        retval = krb5_get_default_realm(context, &def_realm);
        if (retval) {
            com_err(progname, errno, _("while getting default realm"));
            exit(1);
        }
        retval = krb5_set_principal_realm(context, my_principal, def_realm);
        if (retval) {
            com_err(progname, errno,
                    _("while setting client principal realm"));
            exit(1);
        }
    }

    /* Construct the principal name for the slave host. */
    memset(&creds, 0, sizeof(creds));
    retval = krb5_sname_to_principal(context, slave_host, KPROP_SERVICE_NAME,
                                     KRB5_NT_SRV_HST, &server_princ);
    if (retval) {
        com_err(progname, errno, _("while setting server principal name"));
        exit(1);
    }
    retval = krb5_unparse_name_flags(context, server_princ,
                                     KRB5_PRINCIPAL_UNPARSE_NO_REALM, &server);
    if (retval) {
        com_err(progname, retval, _("while unparsing server name"));
        exit(1);
    }

    /* Fill in the client. */
    retval = krb5_copy_principal(context, my_principal, &creds.client);
    if (retval) {
        com_err(progname, retval, _("while copying client principal"));
        exit(1);
    }

    if (srvtab != NULL) {
        retval = krb5_kt_resolve(context, srvtab, &keytab);
        if (retval) {
            com_err(progname, retval, _("while resolving keytab"));
            exit(1);
        }
    }

    retval = krb5_get_init_creds_keytab(context, &creds, my_principal, keytab,
                                        0, server, NULL);
    if (retval) {
        com_err(progname, retval, _("while getting initial credentials\n"));
        exit(1);
    }

    if (keytab != NULL)
        krb5_kt_close(context, keytab);
    krb5_free_unparsed_name(context, server);
    krb5_free_principal(context, server_princ);
}
Exemple #20
0
int
do_krb5_login (int infd, struct auth_data *ap, const char **err_msg)
{
  krb5_auth_context auth_ctx = NULL;
  krb5_error_code status;
  krb5_data inbuf;
  krb5_data version;
  krb5_authenticator *authenticator;
  krb5_rcache rcache;
  krb5_keyblock *key;
  krb5_ticket *ticket;
  struct sockaddr_in laddr;
  int len;
  struct passwd *pwd;
  char *name;

  if (status = krb5_init_context (&ap->context))
    {
      syslog (LOG_ERR, "Error initializing krb5: %s", error_message (status));
      return status;
    }

  if ((status = krb5_auth_con_init (ap->context, &auth_ctx))
      || (status = krb5_auth_con_genaddrs (ap->context, auth_ctx, infd,
					   KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))
      || (status = krb5_auth_con_getrcache (ap->context, auth_ctx, &rcache)))
    return status;

  if (!rcache)
    {
      krb5_principal server;

      status = krb5_sname_to_principal (ap->context, 0, 0, KRB5_NT_SRV_HST,
					&server);
      if (status)
	return status;

      status = krb5_get_server_rcache (ap->context,
				       krb5_princ_component (ap->context,
							     server, 0),
				       &rcache);
      krb5_free_principal (ap->context, server);

      if (status)
	return status;

      status = krb5_auth_con_setrcache (ap->context, auth_ctx, rcache);
      if (status)
	return status;
    }

  len = sizeof (laddr);
  if (getsockname (infd, (struct sockaddr *) &laddr, &len))
    return errno;

  status = krb5_recvauth (ap->context, &auth_ctx, &infd, NULL, 0,
			  0, ap->keytab, &ticket);
  if (status)
    return status;

  if ((status = krb5_auth_con_getauthenticator (ap->context, auth_ctx,
						&authenticator)))
    return status;

  getstr (infd, &ap->lusername, NULL);
  getstr (infd, &ap->term, "TERM=");

  pwd = getpwnam (ap->lusername);
  if (pwd == NULL)
    {
      *err_msg = "getpwnam failed";
      syslog (LOG_ERR, "getpwnam failed: %m");
      return 1;
    }

  getstr (infd, &ap->rusername, NULL);

  if ((status = krb5_copy_principal (ap->context,
				     ticket->enc_part2->client, &ap->client)))
    return status;

  /*OK:: */
  if (ap->client && !krb5_kuserok (ap->context, ap->client, ap->lusername))
    return 1;

  krb5_unparse_name (ap->context, ap->client, &name);

  syslog (LOG_INFO | LOG_AUTH,
	  "%sKerberos V login from %s on %s\n",
	  (pwd->pw_uid == 0) ? "ROOT " : "", name, ap->hostname);
  free (name);

  return 0;
}
Exemple #21
0
/*
 * Store the given private key (key) and certificate (cert)
 * into the Kerberos 5 credentials cache.  The "lifetime"
 * of the certificate is also given in notBefore, and notAfter.
 */
int store_in_cc(RSA *key,
	BYTE 			*cert,
	DWORD 			cert_length,
	char 			*realm,
	ASN1_UTCTIME 		*notBefore,
	ASN1_UTCTIME 		*notAfter,
#if defined(KX509_LIB)
	char			*tkt_cache_name,
#endif
	char 			**err_msg)
{
	krb5_context		k5_context;
	krb5_ccache		cc;
	krb5_creds		fake_creds;
	DWORD			key_length;
	krb5_error_code		k5_rc		= 0;
	int			retcode		= KX509_STATUS_GOOD;
	BYTE			*ptr 		= NULL;
	BYTE			*memptr 	= NULL;


	/*
	 * Use fake_creds.ticket for private key and
	 * fake_creds.second_ticket for certificate
	 */

	memset(&fake_creds, '\0', sizeof(fake_creds));

	if (k5_rc = krb5_init_context(&k5_context))
	{
		log_printf("store_in_cc: unable to initialize Kerberos 5 context (%d)\n", k5_rc);
		*err_msg = "Error initializing kerberos 5 environment."; 
		return KX509_STATUS_CLNT_FIX;
	}

#if 0	/* DON'T NEED THIS, and it is a private function anyway... */
	if (k5_rc = krb5_set_default_realm(k5_context, realm))
	{
		log_printf("store_in_cc: failed to malloc space for k5 default_realm\n");
		*err_msg = "Try re-authenticating.  "
				"Hopefully temporary client-side problem";
		return KX509_STATUS_CLNT_FIX;
	}
#endif

#if defined(KX509_LIB)
	if (k5_rc = krb5_cc_resolve(k5_context, tkt_cache_name, &cc))
	{
		log_printf("store_in_cc: failed to resolve credential cache (%d)\n", k5_rc);
		*err_msg = "Try re-authenticating.  "
			"Could not resolve your credential cache name.";
		return KX509_STATUS_CLNT_FIX;
	}
#else
	if (k5_rc = krb5_cc_default(k5_context, &cc))
	{
		log_printf("store_in_cc: failed to resolve credential cache (%d)\n", k5_rc);
		*err_msg = "Try re-authenticating.  "
				"Could not resolve your credential cache name.";
		return KX509_STATUS_CLNT_FIX;
	}
#endif

#if defined(HAVE_HEIMDAL)
	if (k5_rc = krb5_make_principal(k5_context, &fake_creds.server,
						    realm,
						    KX509_CC_PRINCIPAL,
						    KX509_CC_INSTANCE,
						    NULL))
#else
	if (k5_rc = krb5_sname_to_principal(k5_context, KX509_CC_INSTANCE,
							KX509_CC_PRINCIPAL,
							KRB5_NT_UNKNOWN,
							&fake_creds.server))
#endif
	{
		log_printf("store_in_cc: unable to create server principal from sname (%d)\n",
				k5_rc);
		*err_msg = "Internal error with kerberos while creating fake server principal.";
		retcode = KX509_STATUS_CLNT_FIX;
		goto close_and_return;
	}

#if defined(CC_REMOVE_IMPLEMENTED)
	/*
	 * We really want to clear out any old private key/certificate entries
	 * from the credentials cache.  However, the function to do that is
	 * not defined...
	 */
	if (k5_rc = kx509_clear_old_certificates(k5_context, cc, fake_creds))
	{
		log_printf("store_in_cc: couldn't clear out old certificate "
			"from cred cache (%d)\n", k5_rc);
		*err_msg = "Error removing old certificate from your kerberos credentials cache.";
		retcode = KX509_STATUS_CLNT_FIX;
		goto close_and_return;
	}
#endif	/* CC_REMOVE_IMPLEMENTED */

	if (k5_rc = krb5_cc_get_principal(k5_context, cc, &fake_creds.client))
	{
		log_printf("store_in_cc: unable to create client principal from sname (%d)\n",
				k5_rc);
		*err_msg = "Internal error with kerberos while creating fake client principal.";
		retcode = KX509_STATUS_CLNT_FIX;
		goto close_and_return;
	}

	/*
	 * Get the DER-encoded length of the private key.
	 * Allocate storage to hold the private key and certificate.
	 */

	key_length = i2d_RSAPrivateKey(key, NULL);	/* Get DER-encoded len of Private Key */
	if (key_length <= 0)
	{
		log_printf("store_in_cc: unable to determine length of "
			"encoded private key (%d)\n", key_length);
		*err_msg = "Error determining encoded length of private key.";
		retcode = KX509_STATUS_CLNT_FIX;
		goto close_and_return;
	}

	ptr = Malloc(key_length + cert_length);
	if (!ptr)
	{
		log_printf("store_in_cc: error allocating %d bytes for "
			"private key (%d) and certificate (%d)\n", 
			key_length+cert_length, key_length, cert_length);
		*err_msg = "Error allocating storage for private key and certificate.";
		retcode = KX509_STATUS_CLNT_FIX;
		goto close_and_return;
	}

	memptr = ptr;	/* Save a ptr to the allocated area for later when we free it */

	fake_creds.ticket.data = (char *)ptr; 
	fake_creds.ticket.length = i2d_RSAPrivateKey(key, &ptr);

	/* Note that i2d_RSAPrivateKey() updates ptr!!! */
	memcpy(ptr, cert, cert_length);
	fake_creds.second_ticket.data = (char *)ptr;
	fake_creds.second_ticket.length = cert_length;

	/* Set up the ticket lifetime according to the certificate lifetime */
	fake_creds.times.starttime = utc2unix(notBefore, NULL);
	fake_creds.times.endtime = utc2unix(notAfter, NULL);

	/*
	 * Store the fake ticket (containing the private key
	 * and certificate) into the credentials cache.
	 */ 

#if defined(WRITE_CERT)
	/* Write the key-pair and certificate to file (code lifted from kxlist -p) */
	if (k5_rc = materialize_cert(k5_context, cc, &fake_creds))
#else	/* WRITE_CERT */
	/* Store the key-pair and certificate into the K5 credentials cache as a mock ticket */
	if (k5_rc = krb5_cc_store_cred(k5_context, cc, &fake_creds))
#endif	/* WRITE_CERT */
	{
		log_printf("store_in_cc: krb5_cc_store_cred returned %0d\n", k5_rc);
		*err_msg = "Try re-authenticating.  "
			"Currently unable to write your Kerberos credentials cache.";
		retcode = KX509_STATUS_CLNT_FIX;
		goto close_and_return;
	}

close_and_return:

	if (memptr)
	{
		Free(memptr);
		memptr = NULL;
	}

	krb5_cc_close(k5_context, cc);	/* ignore return code from close */

	return(retcode);
}
Exemple #22
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_auth_context auth_context;
    void *kadm_handle;
    kadm5_server_context *server_context;
    kadm5_config_params conf;
    int master_fd;
    krb5_ccache ccache;
    krb5_principal server;
    char **files;
    int optidx = 0;
    time_t reconnect_min;
    time_t backoff;
    time_t reconnect_max;
    time_t reconnect;
    time_t before = 0;

    const char *master;

    setprogname(argv[0]);

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

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

    ret = krb5_init_context(&context);
    if (ret)
	errx (1, "krb5_init_context failed: %d", ret);

    setup_signal();

    if (config_file == NULL) {
	asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context));
	if (config_file == NULL)
	    errx(1, "out of memory");
    }

    ret = krb5_prepend_config_files_default(config_file, &files);
    if (ret)
	krb5_err(context, 1, ret, "getting configuration files");

    ret = krb5_set_config_files(context, files);
    krb5_free_config_files(files);
    if (ret)
	krb5_err(context, 1, ret, "reading configuration files");

    argc -= optidx;
    argv += optidx;

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

    master = argv[0];

#ifdef SUPPORT_DETACH
    if (detach_from_console)
	daemon(0, 0);
#endif
    pidfile (NULL);
    krb5_openlog (context, "ipropd-slave", &log_facility);
    krb5_set_warn_dest(context, log_facility);

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

    time_before_lost = parse_time (server_time_lost,  "s");
    if (time_before_lost < 0)
	krb5_errx (context, 1, "couldn't parse time: %s", server_time_lost);

    memset(&conf, 0, sizeof(conf));
    if(realm) {
	conf.mask |= KADM5_CONFIG_REALM;
	conf.realm = realm;
    }
    ret = kadm5_init_with_password_ctx (context,
					KADM5_ADMIN_SERVICE,
					NULL,
					KADM5_ADMIN_SERVICE,
					&conf, 0, 0,
					&kadm_handle);
    if (ret)
	krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");

    server_context = (kadm5_server_context *)kadm_handle;

    ret = kadm5_log_init (server_context);
    if (ret)
	krb5_err (context, 1, ret, "kadm5_log_init");

    get_creds(context, keytab_str, &ccache, master);

    ret = krb5_sname_to_principal (context, master, IPROP_NAME,
				   KRB5_NT_SRV_HST, &server);
    if (ret)
	krb5_err (context, 1, ret, "krb5_sname_to_principal");

    auth_context = NULL;
    master_fd = -1;

    krb5_appdefault_time(context, config_name, NULL, "reconnect-min",
			 10, &reconnect_min);
    krb5_appdefault_time(context, config_name, NULL, "reconnect-max",
			 300, &reconnect_max);
    krb5_appdefault_time(context, config_name, NULL, "reconnect-backoff",
			 10, &backoff);
    reconnect = reconnect_min;

    while (!exit_flag) {
	time_t now, elapsed;
	int connected = FALSE;

	now = time(NULL);
	elapsed = now - before;

	if (elapsed < reconnect) {
	    time_t left = reconnect - elapsed;
	    krb5_warnx(context, "sleeping %d seconds before "
		       "retrying to connect", (int)left);
	    sleep(left);
	}
	before = now;

	master_fd = connect_to_master (context, master, port_str);
	if (master_fd < 0)
	    goto retry;

	reconnect = reconnect_min;

	if (auth_context) {
	    krb5_auth_con_free(context, auth_context);
	    auth_context = NULL;
	    krb5_cc_destroy(context, ccache);
	    get_creds(context, keytab_str, &ccache, master);
	}
	ret = krb5_sendauth (context, &auth_context, &master_fd,
			     IPROP_VERSION, NULL, server,
			     AP_OPTS_MUTUAL_REQUIRED, NULL, NULL,
			     ccache, NULL, NULL, NULL);
	if (ret) {
	    krb5_warn (context, ret, "krb5_sendauth");
	    goto retry;
	}

	krb5_warnx(context, "ipropd-slave started at version: %ld",
		   (long)server_context->log_context.version);

	ret = ihave (context, auth_context, master_fd,
		     server_context->log_context.version);
	if (ret)
	    goto retry;

	connected = TRUE;

	while (connected && !exit_flag) {
	    krb5_data out;
	    krb5_storage *sp;
	    int32_t tmp;
	    fd_set readset;
	    struct timeval to;

#ifndef NO_LIMIT_FD_SETSIZE
	    if (master_fd >= FD_SETSIZE)
		krb5_errx (context, 1, "fd too large");
#endif

	    FD_ZERO(&readset);
	    FD_SET(master_fd, &readset);

	    to.tv_sec = time_before_lost;
	    to.tv_usec = 0;

	    ret = select (master_fd + 1,
			  &readset, NULL, NULL, &to);
	    if (ret < 0) {
		if (errno == EINTR)
		    continue;
		else
		    krb5_err (context, 1, errno, "select");
	    }
	    if (ret == 0)
		krb5_errx (context, 1, "server didn't send a message "
			   "in %d seconds", time_before_lost);

	    ret = krb5_read_priv_message(context, auth_context, &master_fd, &out);
	    if (ret) {
		krb5_warn (context, ret, "krb5_read_priv_message");
		connected = FALSE;
		continue;
	    }

	    sp = krb5_storage_from_mem (out.data, out.length);
	    krb5_ret_int32 (sp, &tmp);
	    switch (tmp) {
	    case FOR_YOU :
		receive (context, sp, server_context);
		ret = ihave (context, auth_context, master_fd,
			     server_context->log_context.version);
		if (ret)
		    connected = FALSE;
		break;
	    case TELL_YOU_EVERYTHING :
		ret = receive_everything (context, master_fd, server_context,
					  auth_context);
		if (ret)
		    connected = FALSE;
		break;
	    case ARE_YOU_THERE :
		send_im_here (context, master_fd, auth_context);
		break;
	    case NOW_YOU_HAVE :
	    case I_HAVE :
	    case ONE_PRINC :
	    case I_AM_HERE :
	    default :
		krb5_warnx (context, "Ignoring command %d", tmp);
		break;
	    }
	    krb5_storage_free (sp);
	    krb5_data_free (&out);

	}
    retry:
	if (connected == FALSE)
	    krb5_warnx (context, "disconnected for server");
	if (exit_flag)
	    krb5_warnx (context, "got an exit signal");

	if (master_fd >= 0)
	    close(master_fd);

	reconnect += backoff;
	if (reconnect > reconnect_max)
	    reconnect = reconnect_max;
    }

    if (0);
#ifndef NO_SIGXCPU
    else if(exit_flag == SIGXCPU)
	krb5_warnx(context, "%s CPU time limit exceeded", getprogname());
#endif
    else if(exit_flag == SIGINT || exit_flag == SIGTERM)
	krb5_warnx(context, "%s terminated", getprogname());
    else
	krb5_warnx(context, "%s unexpected exit reason: %ld",
		       getprogname(), (long)exit_flag);
    
    return 0;
}
Exemple #23
0
static int
proto (int sock, const char *hostname, const char *service)
{
    krb5_auth_context auth_context;
    krb5_error_code status;
    krb5_principal server;
    krb5_data data;
    krb5_data packet;
    u_int32_t len, net_len;

    status = krb5_auth_con_init (context, &auth_context);
    if (status)
	krb5_err (context, 1, status, "krb5_auth_con_init");

    status = krb5_auth_con_setaddrs_from_fd (context,
					     auth_context,
					     &sock);
    if (status)
	krb5_err (context, 1, status, "krb5_auth_con_setaddrs_from_fd");

    status = krb5_sname_to_principal (context,
				      hostname,
				      service,
				      KRB5_NT_SRV_HST,
				      &server);
    if (status)
	krb5_err (context, 1, status, "krb5_sname_to_principal");

    status = krb5_sendauth (context,
			    &auth_context,
			    &sock,
			    VERSION,
			    NULL,
			    server,
			    AP_OPTS_MUTUAL_REQUIRED,
			    NULL,
			    NULL,
			    NULL,
			    NULL,
			    NULL,
			    NULL);
    if (status)
	krb5_err (context, 1, status, "krb5_sendauth");

    data.data   = "hej";
    data.length = 3;

    krb5_data_zero (&packet);

    status = krb5_mk_safe (context,
			   auth_context,
			   &data,
			   &packet,
			   NULL);
    if (status)
	krb5_err (context, 1, status, "krb5_mk_safe");

    len = packet.length;
    net_len = htonl(len);

    if (krb5_net_write (context, &sock, &net_len, 4) != 4)
	err (1, "krb5_net_write");
    if (krb5_net_write (context, &sock, packet.data, len) != len)
	err (1, "krb5_net_write");

    data.data   = "hemligt";
    data.length = 7;

    krb5_data_free (&packet);

    status = krb5_mk_priv (context,
			   auth_context,
			   &data,
			   &packet,
			   NULL);
    if (status)
	krb5_err (context, 1, status, "krb5_mk_priv");

    len = packet.length;
    net_len = htonl(len);

    if (krb5_net_write (context, &sock, &net_len, 4) != 4)
	err (1, "krb5_net_write");
    if (krb5_net_write (context, &sock, packet.data, len) != len)
	err (1, "krb5_net_write");
    return 0;
}
Exemple #24
0
/* call-seq:
 *   krb5.get_init_creds_keytab(principal = nil, keytab = nil, service = nil, ccache = nil)
 *
 * Acquire credentials for +principal+ from +keytab+ using +service+. If
 * no principal is specified, then a principal is derived from the service
 * name. If no service name is specified, kerberos defaults to "host".
 *
 * If no keytab file is provided, the default keytab file is used. This is
 * typically /etc/krb5.keytab.
 *
 * If +ccache+ is supplied and is a Kerberos::Krb5::CredentialsCache, the
 * resulting credentials will be stored in the credential cache.
 */
static VALUE rkrb5_get_init_creds_keytab(int argc, VALUE* argv, VALUE self){
  RUBY_KRB5* ptr;
  VALUE v_user, v_keytab_name, v_service, v_ccache;
  char* user;
  char* service;
  char keytab_name[MAX_KEYTAB_NAME_LEN];

  krb5_error_code kerror;
  krb5_get_init_creds_opt* opt;
  krb5_creds cred;

  Data_Get_Struct(self, RUBY_KRB5, ptr); 

  if(!ptr->ctx)
    rb_raise(cKrb5Exception, "no context has been established");

  kerror = krb5_get_init_creds_opt_alloc(ptr->ctx, &opt);
  if(kerror)
    rb_raise(cKrb5Exception, "krb5_get_init_creds_opt_alloc: %s", error_message(kerror));

  rb_scan_args(argc, argv, "04", &v_user, &v_keytab_name, &v_service, &v_ccache);

  // We need the service information for later.
  if(NIL_P(v_service)){
    service = NULL;
  }
  else{
    Check_Type(v_service, T_STRING);
    service = StringValueCStr(v_service);
  }

  // Convert the name (or service name) to a kerberos principal.
  if(NIL_P(v_user)){
    kerror = krb5_sname_to_principal(
      ptr->ctx,
      NULL,
      service,
      KRB5_NT_SRV_HST,
      &ptr->princ
    );

    if(kerror) {
      krb5_get_init_creds_opt_free(ptr->ctx, opt);
      rb_raise(cKrb5Exception, "krb5_sname_to_principal: %s", error_message(kerror));
    }
  }
  else{
    Check_Type(v_user, T_STRING);
    user = StringValueCStr(v_user);

    kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ); 

    if(kerror) {
      krb5_get_init_creds_opt_free(ptr->ctx, opt);
      rb_raise(cKrb5Exception, "krb5_parse_name: %s", error_message(kerror));
    }
  }

  // Use the default keytab if none is specified.
  if(NIL_P(v_keytab_name)){
    kerror = krb5_kt_default_name(ptr->ctx, keytab_name, MAX_KEYTAB_NAME_LEN);

    if(kerror) {
      krb5_get_init_creds_opt_free(ptr->ctx, opt);
      rb_raise(cKrb5Exception, "krb5_kt_default_name: %s", error_message(kerror));
    }
  }
  else{
    Check_Type(v_keytab_name, T_STRING);
    strncpy(keytab_name, StringValueCStr(v_keytab_name), MAX_KEYTAB_NAME_LEN);
  }

  kerror = krb5_kt_resolve(
    ptr->ctx,
    keytab_name,
    &ptr->keytab
  );

  if(kerror) {
    krb5_get_init_creds_opt_free(ptr->ctx, opt);
    rb_raise(cKrb5Exception, "krb5_kt_resolve: %s", error_message(kerror));
  }

  // Set the credential cache from the supplied Kerberos::Krb5::CredentialsCache
  if(!NIL_P(v_ccache)){
    RUBY_KRB5_CCACHE* ccptr;
    Data_Get_Struct(v_ccache, RUBY_KRB5_CCACHE, ccptr);

    kerror = krb5_get_init_creds_opt_set_out_ccache(ptr->ctx, opt, ccptr->ccache);
    if(kerror) {
      krb5_get_init_creds_opt_free(ptr->ctx, opt);
      rb_raise(cKrb5Exception, "krb5_get_init_creds_opt_set_out_ccache: %s", error_message(kerror));
    }
  }

  kerror = krb5_get_init_creds_keytab(
    ptr->ctx,
    &cred,
    ptr->princ,
    ptr->keytab,
    0,
    service,
    opt
  );

  if(kerror) {
    krb5_get_init_creds_opt_free(ptr->ctx, opt);
    rb_raise(cKrb5Exception, "krb5_get_init_creds_keytab: %s", error_message(kerror));
  }

  krb5_get_init_creds_opt_free(ptr->ctx, opt);

  return self; 
}
Exemple #25
0
int main(int argc, char **argv) {
	krb5_context context;
	krb5_error_code retval;
	krb5_principal server;
	krb5_keytab keytab = NULL;	/* Allow specification on command line*/
	extern int opterr, optind;
	extern char *optarg;
	int ch;
	char *progname, *cfgfile, *cmddir;
	char *cfgname = AFSADMCONFIGNAME;
	char *cfgdir = AFSADMDIR;
	char *service = AFSADM_SERVICE;

	/*********************************************************************/
	debug = 0;
	progname = *argv;

	/* open a log connection */
	openlog("afsadmd", LOG_PID, LOG_DAEMON);

	retval = krb5_init_context(&context);
	if (retval) {
		syslog(LOG_ERR, "while initializing krb5: %s", error_message(retval));
		exit(1);
	}

	/*
	 * Parse command line arguments
	 */
	opterr = 0;
	while ((ch = getopt(argc, argv, "dS:s:c:")) != EOF) {
		switch (ch) {
			case 'c':
				cfgdir = optarg;
				break;
			case 's':
				service = optarg;
				break;
			case 'S':
				if (retval = krb5_kt_resolve(context, optarg, &keytab)) {
					syslog(LOG_ERR, "while resolving keytab file %s: %s", optarg, error_message(retval));
					exit(2);
				}
				break;
			case 'd':
				debug++;
				break;
			case '?':
			default:
				usage(progname);
				exit(1);
				break;
		}
	}

	argc -= optind;
	argv += optind;


	if (retval = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST, &server)) {
		syslog(LOG_ERR, "while generating service name (%s): %s", service, error_message(retval));
		exit(1);
	}

	/******************************************************************/
	/*
	 * Config file
	 */

	if ((cfgfile = malloc(sizeof(char) * (strlen(cfgdir) + strlen(cfgname) + 2))) == NULL) {
		syslog(LOG_ERR, "%m: while allocating buffer for configuration filename");
		exit(1);
	}
	sprintf(cfgfile, "%s/%s", cfgdir, cfgname);

	/* cmddir = cfgdir/bin */
	if ((cmddir = malloc(sizeof(char) * (strlen(cfgdir) + 4))) == NULL) {
		syslog(LOG_ERR, "%m: while allocating buffer for configuration directory");
		exit(1);
	}
	sprintf(cmddir, "%s/bin", cfgdir);

	if (debug)
		syslog(LOG_DEBUG, "Parsing configfile %s", cfgfile);

	if (parse_config_file(cfgfile))
		exit(1);

	/*********************************************************************/

	do_krb5_comm(context, keytab, server, cmddir);

	free(cfgfile);
	free(cmddir);
	krb5_free_context(context);
	exit(0);
}
/*
 * call-seq:
 *   get_init_creds_keytab([principal][,keytab])
 *
 * Call krb5_get_init_creds_keytab() to get credentials based on a keytab.  With no parameters, gets the default principal (probably the username@DEFAULT_REALM) from the default keytab (as configured in /etc/krb5.conf).  With one parameter, get the named principal from the default keytab (as configured in /etc/krb5.conf).  With two parameters, get the named principal from the named keytab.  Returns true on success, raises Krb5Auth::Krb5::Exception on failure.
 */
static VALUE Krb5_get_init_creds_keytab(int argc, VALUE *argv, VALUE self)
{
  VALUE princ_val, keytab_val;
  char *princ;
  char *keytab_name;
  struct ruby_krb5 *kerb;
  krb5_error_code krbret;
  krb5_keytab keytab;

  keytab = NULL;

  rb_scan_args(argc, argv, "02", &princ_val, &keytab_val);

  princ = get_string_or_nil(princ_val);
  keytab_name = get_string_or_nil(keytab_val);

  Data_Get_Struct(self, struct ruby_krb5, kerb);
  if (!kerb) {
    NOSTRUCT_EXCEPT();
    return Qfalse;
  }

  if (keytab_name != NULL) {
    krbret = krb5_kt_resolve(kerb->ctx, keytab_name, &keytab);
    if (krbret) {
      goto failed_keytab;
    }
  }
  // implicit else: if we weren't passed a keytab name, just leave keytab as
  // NULL to use the default

  if (princ != NULL) {
    krbret = krb5_parse_name(kerb->ctx, princ, &kerb->princ);
  }
  else {
    // if we weren't passed a principal, we just get the default principal
    // (which is generally the hostname)
    krbret = krb5_sname_to_principal(kerb->ctx, NULL, NULL, KRB5_NT_SRV_HST,
				     &kerb->princ);
  }
  if (krbret) {
    goto failed_keytab;
  }

  krbret = krb5_get_init_creds_keytab(kerb->ctx, &kerb->creds, kerb->princ,
				      keytab, 0, NULL, NULL);
  if (krbret) {
    goto failed_keytab;
  }

  if (keytab)
    krb5_kt_close(kerb->ctx, keytab);

  return Qtrue;

 failed_keytab:
  if (keytab)
    krb5_kt_close(kerb->ctx, keytab);

  Krb5_register_error(krbret);

  // we will never reach here, since Krb5_register_error will rb_raise().  just
  // leave it to shut the compiler up
  return Qfalse;
}
Exemple #27
0
static int
proto (int sock, const char *hostname, const char *svc,
       char *message, size_t len)
{
    krb5_auth_context auth_context;
    krb5_error_code status;
    krb5_principal server;
    krb5_data data;
    krb5_data data_send;

    krb5_ccache     ccache;
    krb5_creds      creds;
    krb5_kdc_flags  flags;
    krb5_principal  principal;

    status = krb5_auth_con_init (context, &auth_context);
    if (status) {
	krb5_warn (context, status, "krb5_auth_con_init");
	return 1;
    }

    status = krb5_auth_con_setaddrs_from_fd (context,
					     auth_context,
					     &sock);
    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_auth_con_setaddr");
	return 1;
    }

    status = krb5_sname_to_principal (context,
				      hostname,
				      svc,
				      KRB5_NT_SRV_HST,
				      &server);
    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_sname_to_principal");
	return 1;
    }

    status = krb5_sendauth (context,
			    &auth_context,
			    &sock,
			    KF_VERSION_1,
			    NULL,
			    server,
			    AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,
			    NULL,
			    NULL,
			    NULL,
			    NULL,
			    NULL,
			    NULL);
    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn(context, status, "krb5_sendauth");
	return 1;
    }

    if (ccache_name == NULL)
	ccache_name = "";

    data_send.data   = (void *)remote_name;
    data_send.length = strlen(remote_name) + 1;
    status = krb5_write_priv_message(context, auth_context, &sock, &data_send);
    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_write_message");
	return 1;
    }
    data_send.data   = (void *)ccache_name;
    data_send.length = strlen(ccache_name)+1;
    status = krb5_write_priv_message(context, auth_context, &sock, &data_send);
    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_write_message");
	return 1;
    }

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

    status = krb5_cc_default (context, &ccache);
    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_cc_default");
	return 1;
    }

    status = krb5_cc_get_principal (context, ccache, &principal);
    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_cc_get_principal");
	return 1;
    }

    creds.client = principal;

    status = krb5_make_principal (context,
				  &creds.server,
				  principal->realm,
				  KRB5_TGS_NAME,
				  principal->realm,
				  NULL);

    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_make_principal");
	return 1;
    }

    creds.times.endtime = 0;

    flags.i = 0;
    flags.b.forwarded   = 1;
    flags.b.forwardable = forwardable;

    status = krb5_get_forwarded_creds (context,
				       auth_context,
				       ccache,
				       flags.i,
				       hostname,
				       &creds,
				       &data);
    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_get_forwarded_creds");
	return 1;
    }

    status = krb5_write_priv_message(context, auth_context, &sock, &data);

    if (status) {
	krb5_auth_con_free(context, auth_context);
	krb5_warn (context, status, "krb5_mk_priv");
	return 1;
    }

    krb5_data_free (&data);

    status = krb5_read_priv_message(context, auth_context, &sock, &data);
    krb5_auth_con_free(context, auth_context);
    if (status) {
	krb5_warn (context, status, "krb5_mk_priv");
	return 1;
    }
    if(data.length >= len) {
	krb5_warnx (context, "returned string is too long, truncating");
	memcpy(message, data.data, len);
	message[len - 1] = '\0';
    } else {
	memcpy(message, data.data, data.length);
	message[data.length] = '\0';
    }
    krb5_data_free (&data);

    return(strcmp(message, "ok"));
}
Exemple #28
0
/*
 * Function: socket_connection
 *
 * Purpose: Opens the network connection with the mail host, without
 * 	doing any sort of I/O with it or anything.
 *
 * Arguments:
 * 	host	The host to which to connect.
 *	flags	Option flags.
 *
 * Return value: A file descriptor indicating the connection, or -1
 * 	indicating failure, in which case an error has been copied
 * 	into pop_error.
 */
static int
socket_connection (char *host, int flags)
{
  struct addrinfo *res, *it;
  struct addrinfo hints;
  int ret;
  struct servent *servent;
  struct sockaddr_in addr;
  char found_port = 0;
  const char *service;
  int sock;
  char *realhost;
#ifdef KERBEROS
#ifdef KERBEROS5
  krb5_error_code rem;
  krb5_context kcontext = 0;
  krb5_auth_context auth_context = 0;
  krb5_ccache ccdef;
  krb5_principal client, server;
  krb5_error *err_ret;
  register char *cp;
#else
  KTEXT ticket;
  MSG_DAT msg_data;
  CREDENTIALS cred;
  Key_schedule schedule;
  int rem;
#endif /* KERBEROS5 */
#endif /* KERBEROS */

  int try_count = 0;
  int connect_ok;

#ifdef WINDOWSNT
  {
    WSADATA winsockData;
    if (WSAStartup (0x101, &winsockData) == 0)
      have_winsock = 1;
  }
#endif

  memset (&addr, 0, sizeof (addr));
  addr.sin_family = AF_INET;

  /** "kpop" service is  never used: look for 20060515 to see why **/
#ifdef KERBEROS
  service = (flags & POP_NO_KERBEROS) ? POP_SERVICE : KPOP_SERVICE;
#else
  service = POP_SERVICE;
#endif

#ifdef HESIOD
  if (! (flags & POP_NO_HESIOD))
    {
      servent = hes_getservbyname (service, "tcp");
      if (servent)
	{
	  addr.sin_port = servent->s_port;
	  found_port = 1;
	}
    }
#endif
  if (! found_port)
    {
      servent = getservbyname (service, "tcp");
      if (servent)
	{
	  addr.sin_port = servent->s_port;
	}
      else
	{
  /** "kpop" service is  never used: look for 20060515 to see why **/
#ifdef KERBEROS
	  addr.sin_port = htons ((flags & POP_NO_KERBEROS) ?
				POP_PORT : KPOP_PORT);
#else
	  addr.sin_port = htons (POP_PORT);
#endif
	}
    }

#define POP_SOCKET_ERROR "Could not create socket for POP connection: "

  sock = socket (PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    {
      snprintf (pop_error, ERROR_MAX, "%s%s",
		POP_SOCKET_ERROR, strerror (errno));
      return (-1);

    }

  memset (&hints, 0, sizeof (hints));
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_CANONNAME;
  hints.ai_family = AF_INET;
  do
    {
      ret = getaddrinfo (host, service, &hints, &res);
      try_count++;
      if (ret != 0 && (ret != EAI_AGAIN || try_count == 5))
	{
	  strcpy (pop_error, "Could not determine POP server's address");
	  return (-1);
	}
    } while (ret != 0);

  for (it = res; it; it = it->ai_next)
    if (it->ai_addrlen == sizeof addr)
      {
	struct sockaddr_in *in_a = (struct sockaddr_in *) it->ai_addr;
	addr.sin_addr = in_a->sin_addr;
	if (! connect (sock, (struct sockaddr *) &addr, sizeof addr))
	  break;
      }
  connect_ok = it != NULL;
  if (connect_ok)
    {
      realhost = alloca (strlen (it->ai_canonname) + 1);
      strcpy (realhost, it->ai_canonname);
    }
  freeaddrinfo (res);

#define CONNECT_ERROR "Could not connect to POP server: "

  if (! connect_ok)
    {
      CLOSESOCKET (sock);
      snprintf (pop_error, ERROR_MAX, "%s%s", CONNECT_ERROR, strerror (errno));
      return (-1);

    }

#ifdef KERBEROS

#define KRB_ERROR "Kerberos error connecting to POP server: "
  if (! (flags & POP_NO_KERBEROS))
    {
#ifdef KERBEROS5
      rem = krb5_init_context (&kcontext);
      if (rem)
	{
	krb5error:
	  if (auth_context)
	    krb5_auth_con_free (kcontext, auth_context);
	  if (kcontext)
	    krb5_free_context (kcontext);
	  snprintf (pop_error, ERROR_MAX, "%s%s",
		    KRB_ERROR, error_message (rem));
	  CLOSESOCKET (sock);
	  return (-1);
	}

      rem = krb5_auth_con_init (kcontext, &auth_context);
      if (rem)
	goto krb5error;

      rem = krb5_cc_default (kcontext, &ccdef);
      if (rem)
	goto krb5error;

      rem = krb5_cc_get_principal (kcontext, ccdef, &client);
      if (rem)
	goto krb5error;

      for (cp = realhost; *cp; cp++)
	*cp = c_tolower (*cp);

      rem = krb5_sname_to_principal (kcontext, realhost,
				     POP_SERVICE, FALSE, &server);
      if (rem)
	goto krb5error;

      rem = krb5_sendauth (kcontext, &auth_context,
			   (krb5_pointer) &sock, (char *) "KPOPV1.0",
			   client, server,
			  AP_OPTS_MUTUAL_REQUIRED,
			  0,	/* no checksum */
			  0,	/* no creds, use ccache instead */
			  ccdef,
			  &err_ret,
			  0,	/* don't need subsession key */
			  0);	/* don't need reply */
      krb5_free_principal (kcontext, server);
      if (rem)
	{
	  int pop_error_len = snprintf (pop_error, ERROR_MAX, "%s%s",
					KRB_ERROR, error_message (rem));
#if defined HAVE_KRB5_ERROR_TEXT
	  if (err_ret && err_ret->text.length)
	    {
	      int errlen = err_ret->text.length;
	      snprintf (pop_error + pop_error_len, ERROR_MAX - pop_error_len,
			" [server says '%.*s']", errlen, err_ret->text.data);
	    }
#elif defined HAVE_KRB5_ERROR_E_TEXT
	  if (err_ret && err_ret->e_text && **err_ret->e_text)
	    snprintf (pop_error + pop_error_len, ERROR_MAX - pop_error_len,
		      " [server says '%s']", *err_ret->e_text);
#endif
	  if (err_ret)
	    krb5_free_error (kcontext, err_ret);
	  krb5_auth_con_free (kcontext, auth_context);
	  krb5_free_context (kcontext);

	  CLOSESOCKET (sock);
	  return (-1);
	}
#else  /* ! KERBEROS5 */
      ticket = (KTEXT) malloc (sizeof (KTEXT_ST));
      rem = krb_sendauth (0L, sock, ticket, "pop", realhost,
			  (char *) krb_realmofhost (realhost),
			  (unsigned long) 0, &msg_data, &cred, schedule,
			  (struct sockaddr_in *) 0,
			  (struct sockaddr_in *) 0,
			  "KPOPV0.1");
      free ((char *) ticket);
      if (rem != KSUCCESS)
	{
	  snprintf (pop_error, ERROR_MAX, "%s%s", KRB_ERROR, krb_err_txt[rem]);
	  CLOSESOCKET (sock);
	  return (-1);
	}
#endif /* KERBEROS5 */
    }
#endif /* KERBEROS */

  return (sock);
} /* socket_connection */
Exemple #29
0
static int
propagate_database (krb5_context context, int type,
		    const char *database_name,
		    HDB *db, krb5_ccache ccache,
		    int optidx, int argc, char **argv)
{
    krb5_principal server;
    krb5_error_code ret;
    int i, failed = 0;

    for(i = optidx; i < argc; i++){
	krb5_auth_context auth_context;
	int fd;
	struct prop_data pd;
	krb5_data data;

	char *port, portstr[NI_MAXSERV];
	char *host = argv[i];

	port = strchr(host, ':');
	if(port == NULL) {
	    snprintf(portstr, sizeof(portstr), "%u",
		     ntohs(krb5_getportbyname (context, "hprop", "tcp",
					       HPROP_PORT)));
	    port = portstr;
	} else
	    *port++ = '\0';

	fd = open_socket(context, host, port);
	if(fd < 0) {
	    failed++;
	    krb5_warn (context, errno, "connect %s", host);
	    continue;
	}

	ret = krb5_sname_to_principal(context, argv[i],
				      HPROP_NAME, KRB5_NT_SRV_HST, &server);
	if(ret) {
	    failed++;
	    krb5_warn(context, ret, "krb5_sname_to_principal(%s)", host);
	    close(fd);
	    continue;
	}

        if (local_realm) {
            krb5_realm my_realm;
            krb5_get_default_realm(context,&my_realm);
            krb5_principal_set_realm(context,server,my_realm);
	    krb5_xfree(my_realm);
        }

	auth_context = NULL;
	ret = krb5_sendauth(context,
			    &auth_context,
			    &fd,
			    HPROP_VERSION,
			    NULL,
			    server,
			    AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,
			    NULL, /* in_data */
			    NULL, /* in_creds */
			    ccache,
			    NULL,
			    NULL,
			    NULL);

	krb5_free_principal(context, server);

	if(ret) {
	    failed++;
	    krb5_warn(context, ret, "krb5_sendauth (%s)", host);
	    close(fd);
	    goto next_host;
	}

	pd.context      = context;
	pd.auth_context = auth_context;
	pd.sock         = fd;

	ret = iterate (context, database_name, db, type, &pd);
	if (ret) {
	    krb5_warnx(context, "iterate to host %s failed", host);
	    failed++;
	    goto next_host;
	}

	krb5_data_zero (&data);
	ret = krb5_write_priv_message(context, auth_context, &fd, &data);
	if(ret) {
	    krb5_warn(context, ret, "krb5_write_priv_message");
	    failed++;
	    goto next_host;
	}

	ret = krb5_read_priv_message(context, auth_context, &fd, &data);
	if(ret) {
	    krb5_warn(context, ret, "krb5_read_priv_message: %s", host);
	    failed++;
	    goto next_host;
	} else
	    krb5_data_free (&data);

    next_host:
	krb5_auth_con_free(context, auth_context);
	close(fd);
    }
    if (failed)
	return 1;
    return 0;
}
Exemple #30
0
/* returns boolean */
static int DEFAULT_CC
k5_begin(struct k_opts *opts, struct k5_data *k5, struct user_info *u_info)
{
    krb5_error_code code = 0;

    code = krb5_init_context(&k5->ctx);

    if (code != 0)
    {
        g_printf("krb5_init_context failed in k5_begin\n");
        return 0;
    }

    if (opts->k5_cache_name)
    {
        code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc);

        if (code != 0)
        {
            g_printf("krb5_cc_resolve failed in k5_begin\n");
            return 0;
        }
    }
    else
    {
        code = krb5_cc_default(k5->ctx, &k5->cc);

        if (code != 0)
        {
            g_printf("krb5_cc_default failed in k5_begin\n");
            return 0;
        }
    }

    if (opts->principal_name)
    {
        /* Use specified name */
        code = krb5_parse_name(k5->ctx, opts->principal_name, &k5->me);

        if (code != 0)
        {
            g_printf("krb5_parse_name failed in k5_begin\n");
            return 0;
        }
    }
    else
    {
        /* No principal name specified */
        if (opts->action == INIT_KT)
        {
            /* Use the default host/service name */
            code = krb5_sname_to_principal(k5->ctx, NULL, NULL,
                                           KRB5_NT_SRV_HST, &k5->me);

            if (code != 0)
            {
                g_printf("krb5_sname_to_principal failed in k5_begin\n");
                return 0;
            }
        }
        else
        {
            /* Get default principal from cache if one exists */
            code = krb5_cc_get_principal(k5->ctx, k5->cc, &k5->me);

            if (code != 0)
            {
                code = krb5_parse_name(k5->ctx, u_info->name, &k5->me);

                if (code != 0)
                {
                    g_printf("krb5_parse_name failed in k5_begin\n");
                    return 0;
                }
            }
        }
    }

    code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);

    if (code != 0)
    {
        g_printf("krb5_unparse_name failed in k5_begin\n");
        return 0;
    }

    opts->principal_name = k5->name;
    return 1;
}