Пример #1
0
/*
 * call-seq:
 *   krb.set_default_realm(realm = nil)
 *
 * Sets the default realm to +realm+. If no argument is provided, then the
 * default realm in your krb5.conf file is used.
 */
static VALUE rkrb5_set_default_realm(int argc, VALUE* argv, VALUE self){
  RUBY_KRB5* ptr;
  VALUE v_realm;
  char* realm;
  krb5_error_code kerror;

  Data_Get_Struct(self, RUBY_KRB5, ptr); 

  rb_scan_args(argc, argv, "01", &v_realm); 

  if(NIL_P(v_realm)){
    realm = NULL;
  }
  else{
    Check_Type(v_realm, T_STRING);
    realm = StringValueCStr(v_realm);
  }

  kerror = krb5_set_default_realm(ptr->ctx, realm);

  if(kerror)
    rb_raise(cKrb5Exception, "krb5_set_default_realm: %s", error_message(kerror));

  return self;
}
Пример #2
0
/*
 * Serialize krb5_context.
 */
static krb5_error_code
ser_kcontext_test(krb5_context kcontext, int verbose)
{
    krb5_error_code	kret;
    profile_t		sprofile;
    char		dbname[128];

    snprintf(dbname, sizeof(dbname), "temp_%d", (int) getpid());
    sprofile = kcontext->profile;
    kcontext->profile = (profile_t) NULL;
    if (!(kret = ser_data(verbose, "> Context with no profile",
			  (krb5_pointer) kcontext,
			  KV5M_CONTEXT))) {
	kcontext->profile = sprofile;
	if (!(kret = ser_data(verbose, "> Context with no realm", 
			      (krb5_pointer) kcontext,
			      KV5M_CONTEXT)) &&
	    !(kret = krb5_set_default_realm(kcontext, "this.is.a.test"))) {
	    if (!(kret = ser_data(verbose, "> Context with default realm",
				  (krb5_pointer) kcontext,
				  KV5M_CONTEXT))) {
		if (verbose)
		    printf("* krb5_context test succeeded\n");
	    }
	}
    }
    if (kret)
	printf("* krb5_context test failed\n");
    return(kret);
}
Пример #3
0
krb5_error_code
smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx,
			    struct tevent_context *ev,
			    struct loadparm_context *lp_ctx,
			    krb5_context *_krb5_context)
{
	krb5_error_code ret;
	char **config_files;
	const char *config_file, *realm;
	krb5_context krb5_ctx;

	initialize_krb5_error_table();

	ret = krb5_init_context(&krb5_ctx);
	if (ret) {
		DEBUG(1,("krb5_init_context failed (%s)\n",
			 error_message(ret)));
		return ret;
	}

	config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf");
	if (!config_file) {
		krb5_free_context(krb5_ctx);
		return ENOMEM;
	}

	/* Use our local krb5.conf file by default */
	ret = krb5_prepend_config_files_default(config_file == NULL?"":config_file, &config_files);
	if (ret) {
		DEBUG(1,("krb5_prepend_config_files_default failed (%s)\n",
			 smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx)));
		krb5_free_context(krb5_ctx);
		return ret;
	}

	ret = krb5_set_config_files(krb5_ctx, config_files);
	krb5_free_config_files(config_files);
	if (ret) {
		DEBUG(1,("krb5_set_config_files failed (%s)\n",
			 smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx)));
		krb5_free_context(krb5_ctx);
		return ret;
	}

	realm = lp_realm(lp_ctx);
	if (realm != NULL) {
		ret = krb5_set_default_realm(krb5_ctx, realm);
		if (ret) {
			DEBUG(1,("krb5_set_default_realm failed (%s)\n",
				 smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx)));
			krb5_free_context(krb5_ctx);
			return ret;
		}
	}

	*_krb5_context = krb5_ctx;
	return 0;
}
Пример #4
0
static void
test_set_default_realm(krb5_context ctx, char *realm)
{
    krb5_error_code retval;

    retval = krb5_set_default_realm(ctx, realm);
    if (retval) {
        com_err("krb5_set_default_realm", retval, 0);
        return;
    }
    printf("krb5_set_default_realm(%s)\n", realm);
}
Пример #5
0
int
main(int argc, char **argv)
{
    krb5_context ctx, ctx2;
    krb5_plugin_initvt_fn *mods;
    const krb5_enctype etypes1[] = { ENCTYPE_DES3_CBC_SHA1, 0 };
    const krb5_enctype etypes2[] = { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
                                     ENCTYPE_AES256_CTS_HMAC_SHA1_96, 0 };
    krb5_prompt_type ptypes[] = { KRB5_PROMPT_TYPE_PASSWORD };

    /* Copy a default context and verify the result. */
    check(krb5_init_context(&ctx) == 0);
    check(krb5_copy_context(ctx, &ctx2) == 0);
    check_context(ctx2, ctx);
    krb5_free_context(ctx2);

    /* Set non-default values for all of the propagated fields in ctx. */
    ctx->allow_weak_crypto = TRUE;
    check(krb5_set_default_in_tkt_ktypes(ctx, etypes1) == 0);
    check(krb5_set_default_tgs_enctypes(ctx, etypes2) == 0);
    check(krb5_set_debugging_time(ctx, 1234, 5678) == 0);
    check(krb5_cc_set_default_name(ctx, "defccname") == 0);
    check(krb5_set_default_realm(ctx, "defrealm") == 0);
    ctx->clockskew = 18;
    ctx->kdc_req_sumtype = CKSUMTYPE_NIST_SHA;
    ctx->default_ap_req_sumtype = CKSUMTYPE_HMAC_SHA1_96_AES128;
    ctx->default_safe_sumtype = CKSUMTYPE_HMAC_SHA1_96_AES256;
    ctx->kdc_default_options = KDC_OPT_FORWARDABLE;
    ctx->library_options = 0;
    ctx->profile_secure = TRUE;
    ctx->udp_pref_limit = 2345;
    ctx->use_conf_ktypes = TRUE;
    ctx->ignore_acceptor_hostname = TRUE;
    ctx->dns_canonicalize_hostname = CANONHOST_FALSE;
    free(ctx->plugin_base_dir);
    check((ctx->plugin_base_dir = strdup("/a/b/c/d")) != NULL);

    /* Also set some of the non-propagated fields. */
    ctx->prompt_types = ptypes;
    check(k5_plugin_load_all(ctx, PLUGIN_INTERFACE_PWQUAL, &mods) == 0);
    k5_plugin_free_modules(ctx, mods);
    k5_setmsg(ctx, ENOMEM, "nooooooooo");
    krb5_set_trace_callback(ctx, trace, ctx);

    /* Copy the intentionally messy context and verify the result. */
    check(krb5_copy_context(ctx, &ctx2) == 0);
    check_context(ctx2, ctx);
    krb5_free_context(ctx2);

    krb5_free_context(ctx);
    return 0;
}
Пример #6
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_default_realms (krb5_context context,
                         krb5_realm **realms)
{
    if (context->default_realms == NULL) {
        krb5_error_code ret = krb5_set_default_realm (context, NULL);
        if (ret)
            return KRB5_CONFIG_NODEFREALM;
    }

    return krb5_copy_host_realm (context,
                                 context->default_realms,
                                 realms);
}
Пример #7
0
fnasso_error fnasso_kdc_init(fnasso_context *ctx)
{
	F_BEGIN();
	krb5_error_code kerberos_error;
	krb5_context *context;
	
	if (!ctx->kdc)
	{
		ctx->kdc = (fnasso_kdc*) calloc(1, sizeof(fnasso_kdc));
	}

	if (!ctx->kdc->kctx)
	{
		context = ctx->kdc->kctx = (krb5_context *) malloc(sizeof (krb5_context));

		kerberos_error = krb5_init_context(context);
		if (kerberos_error)
		{
			fnasso_kdc_free(ctx);
			E_RETURN(FNASSO_ERR_EXTERNAL, "krb5_init_context", error_message(kerberos_error));
		}
		DEBUG("krb5_init_context OK");
	}
	else
	{
		context = ctx->kdc->kctx;
		DEBUG("context allready initialized");
	}


	// Setup the right roaming kerberos realm
	if (ctx->roaming_realm)
	{
		EVENT("found kerberos roaming realm (%s), overwriting default realm", ctx->roaming_realm);
		kerberos_error = krb5_set_default_realm(*context, ctx->roaming_realm);
		if (kerberos_error)
		{
			fnasso_kdc_free(ctx);
			E_RETURN(FNASSO_ERR_EXTERNAL, "krb5_set_default_realm", error_message(kerberos_error));
		}
		DEBUG("krb5_set_default_realm OK");
	}
	else
	{
		WARN("default realm not found in context, using default realm from /etc/krb5.conf");
	}

	RETURN(FNASSO_ERR_NONE);
}
int
main(int argc, char **argv)
{
    struct testcase *t;
    krb5_context context;
    krb5_error_code ret;
    int val = 0;

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

    /* to enable realm-less principal name above */

    krb5_set_default_realm(context, "");

    for (t = tests; t->principal_name; ++t) {
	krb5_keyblock key;
	krb5_principal principal;
	int i;

	ret = krb5_parse_name (context, t->principal_name, &principal);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_parse_name %s",
		      t->principal_name);
	ret = krb5_string_to_key (context, t->enctype, t->password,
				  principal, &key);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_string_to_key");
	krb5_free_principal (context, principal);
	if (memcmp (key.keyvalue.data, t->res, key.keyvalue.length) != 0) {
	    const unsigned char *p = key.keyvalue.data;

	    printf ("string_to_key(%s, %s) failed\n",
		    t->principal_name, t->password);
	    printf ("should be: ");
	    for (i = 0; i < key.keyvalue.length; ++i)
		printf ("%02x", t->res[i]);
	    printf ("\nresult was: ");
	    for (i = 0; i < key.keyvalue.length; ++i)
		printf ("%02x", p[i]);
	    printf ("\n");
	    val = 1;
	}
	krb5_free_keyblock_contents(context, &key);
    }
    krb5_free_context(context);
    return val;
}
Пример #9
0
static krb5_context
e2k_kerberos_context_new (const char *domain)
{
	krb5_context ctx;
	char *realm;

	if (krb5_init_context (&ctx) != 0)
		return NULL;

	realm = g_ascii_strup (domain, strlen (domain));
	krb5_set_default_realm (ctx, realm);
	g_free (realm);

	return ctx;
}
Пример #10
0
void ceo_krb5_init() {
    krb5_error_code retval;

    set_com_err_hook(com_err_hk);

    debug("krb5: initializing context");

    retval = krb5_init_context(&context);
    if (retval)
        com_err(prog, retval, "while initializing krb5");

    retval = krb5_set_default_realm(context, krb5_realm);
    if (retval)
        com_err(prog, retval, "while setting default realm");
}
Пример #11
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_default_realm(krb5_context context,
		       krb5_realm *realm)
{
    krb5_error_code ret;
    char *res;

    if (context->default_realms == NULL
	|| context->default_realms[0] == NULL) {
	krb5_clear_error_message(context);
	ret = krb5_set_default_realm (context, NULL);
	if (ret)
	    return ret;
    }

    res = strdup (context->default_realms[0]);
    if (res == NULL)
	return krb5_enomem(context);
    *realm = res;
    return 0;
}
Пример #12
0
fnasso_error fnasso_context_set_roaming_realm(fnasso_context *ctx, const char* roaming_realm)
{
	F_BEGIN();
	krb5_error_code kerberos_error;
	if (!ctx) E_RETURN(FNASSO_ERR_NO_CONTEXT_SUPPLIED);

	if (!roaming_realm)
	{
		if (ctx->roaming_realm) free(ctx->roaming_realm);
		ctx->roaming_realm = NULL;
		EVENT("roaming realm restored to default realm in /etc/krb5.conf");
	}
	else
	{
		if (strlen(roaming_realm))
		{
			ctx->roaming_realm = (char *) realloc(ctx->roaming_realm, strlen(roaming_realm) + 1);
			strcpy(ctx->roaming_realm, roaming_realm);
			EVENT("roaming realm is now (%s)", ctx->roaming_realm);
		}
		else
		{
			E_RETURN(FNASSO_ERR_NO_ROAMING_REALM);
		}
	}

	if (ctx->kdc && ctx->kdc->kctx)
	{
		EVENT("updating current KDC default realm");
		kerberos_error = krb5_set_default_realm(*ctx->kdc->kctx, ctx->roaming_realm);
		if (kerberos_error)
		{
			fnasso_kdc_free(ctx);
			E_RETURN(FNASSO_ERR_EXTERNAL, "krb5_set_default_realm", error_message(kerberos_error));
		}
		DEBUG("krb5_set_default_realm OK");
	}

	RETURN(FNASSO_ERR_NONE);
}
Пример #13
0
int
afscp_SetDefaultRealm(const char *realmname)
{
    char *newdefrealm;

#ifdef HAVE_KERBEROS
    /* krb5_error_code k5ec; */
    krb5_context k5con;
    int code;

    if (realmname == NULL) {
	if (defrealm != NULL)
	    free(defrealm);
	defrealm = NULL;
	return 0;
    }

    code = krb5_init_context(&k5con);	/* see aklog.c main() */
    if (code != 0) {
	return -1;
    }
    /* k5ec = */
    krb5_set_default_realm(k5con, realmname);
    /* if (k5ec != KRB5KDC_ERR_NONE) {
     * com_err("libafscp", k5ec, "k5ec = %d (compared to KRB5KDC_ERR_NONE = %d)", k5ec, KRB5KDC_ERR_NONE);
     * return -1;
     * } */
    /* krb5_set_default_realm() is returning 0 on success, not KRB5KDC_ERR_NONE */
#endif /* HAVE_KERBEROS */

    newdefrealm = strdup(realmname);
    if (newdefrealm == NULL) {
	return -1;
    }
    if (defrealm != NULL)
	free(defrealm);
    defrealm = newdefrealm;
    return 0;
}
Пример #14
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_default_realm(krb5_context context,
                       krb5_realm *realm)
{
    krb5_error_code ret;
    char *res;

    if (context->default_realms == NULL
            || context->default_realms[0] == NULL) {
        krb5_clear_error_message(context);
        ret = krb5_set_default_realm (context, NULL);
        if (ret)
            return ret;
    }

    res = strdup (context->default_realms[0]);
    if (res == NULL) {
        krb5_set_error_message(context, ENOMEM,
                               N_("malloc: out of memory", ""));
        return ENOMEM;
    }
    *realm = res;
    return 0;
}
Пример #15
0
NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
			   const char *realm,
			   time_t time_offset,
			   const DATA_BLOB *ticket,
			   char **principal,
			   struct PAC_DATA **pac_data,
			   DATA_BLOB *ap_rep,
			   DATA_BLOB *session_key,
			   bool use_replay_cache)
{
	NTSTATUS sret = NT_STATUS_LOGON_FAILURE;
	NTSTATUS pac_ret;
	DATA_BLOB auth_data;
	krb5_context context = NULL;
	krb5_auth_context auth_context = NULL;
	krb5_data packet;
	krb5_ticket *tkt = NULL;
	krb5_rcache rcache = NULL;
	krb5_keyblock *keyblock = NULL;
	time_t authtime;
	krb5_error_code ret = 0;
	int flags = 0;	
	krb5_principal host_princ = NULL;
	krb5_const_principal client_principal = NULL;
	char *host_princ_s = NULL;
	bool auth_ok = False;
	bool got_auth_data = False;
	struct named_mutex *mutex = NULL;

	ZERO_STRUCT(packet);
	ZERO_STRUCT(auth_data);

	*principal = NULL;
	*pac_data = NULL;
	*ap_rep = data_blob_null;
	*session_key = data_blob_null;

	initialize_krb5_error_table();
	ret = krb5_init_context(&context);
	if (ret) {
		DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret)));
		return NT_STATUS_LOGON_FAILURE;
	}

	if (time_offset != 0) {
		krb5_set_real_time(context, time(NULL) + time_offset, 0);
	}

	ret = krb5_set_default_realm(context, realm);
	if (ret) {
		DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret)));
		goto out;
	}

	/* This whole process is far more complex than I would
           like. We have to go through all this to allow us to store
           the secret internally, instead of using /etc/krb5.keytab */

	ret = krb5_auth_con_init(context, &auth_context);
	if (ret) {
		DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret)));
		goto out;
	}

	krb5_auth_con_getflags( context, auth_context, &flags );
	if ( !use_replay_cache ) {
		/* Disable default use of a replay cache */
		flags &= ~KRB5_AUTH_CONTEXT_DO_TIME;
		krb5_auth_con_setflags( context, auth_context, flags );
	}

	if (asprintf(&host_princ_s, "%s$", global_myname()) == -1) {
		goto out;
	}

	strlower_m(host_princ_s);
	ret = smb_krb5_parse_name(context, host_princ_s, &host_princ);
	if (ret) {
		DEBUG(1,("ads_verify_ticket: smb_krb5_parse_name(%s) failed (%s)\n",
					host_princ_s, error_message(ret)));
		goto out;
	}


	if ( use_replay_cache ) {
		
		/* Lock a mutex surrounding the replay as there is no 
		   locking in the MIT krb5 code surrounding the replay 
		   cache... */

		mutex = grab_named_mutex(talloc_tos(), "replay cache mutex",
					 10);
		if (mutex == NULL) {
			DEBUG(1,("ads_verify_ticket: unable to protect "
				 "replay cache with mutex.\n"));
			ret = KRB5_CC_IO;
			goto out;
		}

		/* JRA. We must set the rcache here. This will prevent 
		   replay attacks. */
		
		ret = krb5_get_server_rcache(context, 
					     krb5_princ_component(context, host_princ, 0), 
					     &rcache);
		if (ret) {
			DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache "
				 "failed (%s)\n", error_message(ret)));
			goto out;
		}

		ret = krb5_auth_con_setrcache(context, auth_context, rcache);
		if (ret) {
			DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache "
				 "failed (%s)\n", error_message(ret)));
			goto out;
		}
	}

	/* Try secrets.tdb first and fallback to the krb5.keytab if
	   necessary */

	auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ,
					    ticket, &tkt, &keyblock, &ret);

	if (!auth_ok &&
	    (ret == KRB5KRB_AP_ERR_TKT_NYV ||
	     ret == KRB5KRB_AP_ERR_TKT_EXPIRED ||
	     ret == KRB5KRB_AP_ERR_SKEW)) {
		goto auth_failed;
	}

	if (!auth_ok && lp_use_kerberos_keytab()) {
		auth_ok = ads_keytab_verify_ticket(context, auth_context, 
						   ticket, &tkt, &keyblock, &ret);
	}

	if ( use_replay_cache ) {		
		TALLOC_FREE(mutex);
#if 0
		/* Heimdal leaks here, if we fix the leak, MIT crashes */
		if (rcache) {
			krb5_rc_close(context, rcache);
		}
#endif
	}	

 auth_failed:
	if (!auth_ok) {
		DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n", 
			 error_message(ret)));
		/* Try map the error return in case it's something like
		 * a clock skew error.
		 */
		sret = krb5_to_nt_status(ret);
		if (NT_STATUS_IS_OK(sret) || NT_STATUS_EQUAL(sret,NT_STATUS_UNSUCCESSFUL)) {
			sret = NT_STATUS_LOGON_FAILURE;
		}
		DEBUG(10,("ads_verify_ticket: returning error %s\n",
			nt_errstr(sret) ));
		goto out;
	} 
	
	authtime = get_authtime_from_tkt(tkt);
	client_principal = get_principal_from_tkt(tkt);

	ret = krb5_mk_rep(context, auth_context, &packet);
	if (ret) {
		DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n",
			error_message(ret)));
		goto out;
	}

	*ap_rep = data_blob(packet.data, packet.length);
	if (packet.data) {
		kerberos_free_data_contents(context, &packet);
		ZERO_STRUCT(packet);
	}

	get_krb5_smb_session_key(context, auth_context, session_key, True);
	dump_data_pw("SMB session key (from ticket)\n", session_key->data, session_key->length);

#if 0
	file_save("/tmp/ticket.dat", ticket->data, ticket->length);
#endif

	/* continue when no PAC is retrieved or we couldn't decode the PAC 
	   (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, or
	   Kerberos tickets encrypted using a DES key) - Guenther */

	got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt);
	if (!got_auth_data) {
		DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n"));
	}

	if (got_auth_data) {
		pac_ret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data);
		if (!NT_STATUS_IS_OK(pac_ret)) {
			DEBUG(3,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(pac_ret)));
			*pac_data = NULL;
		}
		data_blob_free(&auth_data);
	}

#if 0
#if defined(HAVE_KRB5_TKT_ENC_PART2)
	/* MIT */
	if (tkt->enc_part2) {
		file_save("/tmp/authdata.dat",
			  tkt->enc_part2->authorization_data[0]->contents,
			  tkt->enc_part2->authorization_data[0]->length);
	}
#else
	/* Heimdal */
	if (tkt->ticket.authorization_data) {
		file_save("/tmp/authdata.dat",
			  tkt->ticket.authorization_data->val->ad_data.data,
			  tkt->ticket.authorization_data->val->ad_data.length);
	}
#endif
#endif

	if ((ret = smb_krb5_unparse_name(context, client_principal, principal))) {
		DEBUG(3,("ads_verify_ticket: smb_krb5_unparse_name failed (%s)\n", 
			 error_message(ret)));
		sret = NT_STATUS_LOGON_FAILURE;
		goto out;
	}

	sret = NT_STATUS_OK;

 out:

	TALLOC_FREE(mutex);

	if (!NT_STATUS_IS_OK(sret)) {
		data_blob_free(&auth_data);
	}

	if (!NT_STATUS_IS_OK(sret)) {
		data_blob_free(ap_rep);
	}

	if (host_princ) {
		krb5_free_principal(context, host_princ);
	}

	if (keyblock) {
		krb5_free_keyblock(context, keyblock);
	}

	if (tkt != NULL) {
		krb5_free_ticket(context, tkt);
	}

	SAFE_FREE(host_princ_s);

	if (auth_context) {
		krb5_auth_con_free(context, auth_context);
	}

	if (context) {
		krb5_free_context(context);
	}

	return sret;
}
Пример #16
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    char **files;
    int optidx = 0;
    int i;
    krb5_log_facility *logfacility;
    krb5_keytab keytab;
    krb5_socket_t sfd = rk_INVALID_SOCKET;

    setprogname(argv[0]);

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

    if (getarg(args, num_args, argc, argv, &optidx)) {
	warnx("error at argument `%s'", argv[optidx]);
	usage(1);
    }

    if (help_flag)
	usage (0);

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

    argc -= optidx;
    argv += optidx;

    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");

    ret = krb5_openlog(context, "kadmind", &logfacility);
    if (ret)
	krb5_err(context, 1, ret, "krb5_openlog");
    ret = krb5_set_warn_dest(context, logfacility);
    if (ret)
	krb5_err(context, 1, ret, "krb5_set_warn_dest");

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

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

    kadm5_setup_passwd_quality_check (context, check_library, check_function);

    for (i = 0; i < policy_libraries.num_strings; i++) {
	ret = kadm5_add_passwd_quality_verifier(context,
						policy_libraries.strings[i]);
	if (ret)
	    krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier");
    }
    ret = kadm5_add_passwd_quality_verifier(context, NULL);
    if (ret)
	krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier");

    if(debug_flag) {
	int debug_port;
	
	if(port_str == NULL)
	    debug_port = krb5_getportbyname (context, "kerberos-adm",
					     "tcp", 749);
	else
	    debug_port = htons(atoi(port_str));
	mini_inetd(debug_port, &sfd);
    } else {
#ifdef _WIN32
	pidfile(NULL);
	start_server(context, port_str);
#else
	struct sockaddr_storage __ss;
	struct sockaddr *sa = (struct sockaddr *)&__ss;
	socklen_t sa_size = sizeof(__ss);

	/*
	 * Check if we are running inside inetd or not, if not, start
	 * our own server.
	 */

	if(roken_getsockname(STDIN_FILENO, sa, &sa_size) < 0 &&
	   rk_SOCK_ERRNO == ENOTSOCK) {
	    pidfile(NULL);
	    start_server(context, port_str);
	}
#endif /* _WIN32 */
	sfd = STDIN_FILENO;
    }

    if(realm)
	krb5_set_default_realm(context, realm); /* XXX */

    kadmind_loop(context, keytab, sfd);

    return 0;
}
Пример #17
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    char **files;
    int optidx = 0;
    int e, i;
    krb5_log_facility *logfacility;
    krb5_keytab keytab;

    setprogname(argv[0]);

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

    while((e = getarg(args, num_args, argc, argv, &optidx)))
	warnx("error at argument `%s'", argv[optidx]);

    if (help_flag)
	usage (0);

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

    argc -= optidx;
    argv += optidx;

    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");
    
    ret = krb5_openlog(context, "kadmind", &logfacility);
    if (ret)
	krb5_err(context, 1, ret, "krb5_openlog");
    ret = krb5_set_warn_dest(context, logfacility);
    if (ret)
	krb5_err(context, 1, ret, "krb5_set_warn_dest");

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

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

    kadm5_setup_passwd_quality_check (context, check_library, check_function);

    for (i = 0; i < policy_libraries.num_strings; i++) {
	ret = kadm5_add_passwd_quality_verifier(context, 
						policy_libraries.strings[i]);
	if (ret)
	    krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier");
    }
    ret = kadm5_add_passwd_quality_verifier(context, NULL);
    if (ret)
	krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier");

    {
	int fd = 0;
	struct sockaddr_storage __ss;
	struct sockaddr *sa = (struct sockaddr *)&__ss;
	socklen_t sa_size = sizeof(__ss);
	krb5_auth_context ac = NULL;
	int debug_port;

	if(debug_flag) {
	    if(port_str == NULL)
		debug_port = krb5_getportbyname (context, "kerberos-adm", 
						 "tcp", 749);
	    else
		debug_port = htons(atoi(port_str));
	    mini_inetd(debug_port);
	} else if(roken_getsockname(STDIN_FILENO, sa, &sa_size) < 0 && 
		   errno == ENOTSOCK) {
	    parse_ports(context, port_str ? port_str : "+");
	    pidfile(NULL);
	    start_server(context);
	}
	if(realm)
	    krb5_set_default_realm(context, realm); /* XXX */
	kadmind_loop(context, ac, keytab, fd);
    }
    return 0;
}
Пример #18
0
/*
 * Initialize a realm control structure from the alternate profile or from
 * the specified defaults.
 *
 * After we're complete here, the essence of the realm is embodied in the
 * realm data and we should be all set to begin operation for that realm.
 */
static krb5_error_code
init_realm(kdc_realm_t *rdp, char *realm, char *def_mpname,
           krb5_enctype def_enctype, char *def_udp_ports, char *def_tcp_ports,
           krb5_boolean def_manual, krb5_boolean def_restrict_anon,
           char **db_args, char *no_refrls, char *host_based_srvcs)
{
    krb5_error_code     kret;
    krb5_boolean        manual;
    krb5_realm_params   *rparams;
    int                 kdb_open_flags;
    krb5_kvno       mkvno = IGNORE_VNO;

    memset(rdp, 0, sizeof(kdc_realm_t));
    if (!realm) {
        kret = EINVAL;
        goto whoops;
    }

    rdp->realm_name = strdup(realm);
    if (rdp->realm_name == NULL) {
        kret = ENOMEM;
        goto whoops;
    }
    kret = krb5int_init_context_kdc(&rdp->realm_context);
    if (kret) {
        kdc_err(NULL, kret, _("while getting context for realm %s"), realm);
        goto whoops;
    }

    kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name,
                                  &rparams);
    if (kret) {
        kdc_err(rdp->realm_context, kret, _("while reading realm parameters"));
        goto whoops;
    }

    /* Handle profile file name */
    if (rparams && rparams->realm_profile) {
        rdp->realm_profile = strdup(rparams->realm_profile);
        if (!rdp->realm_profile) {
            kret = ENOMEM;
            goto whoops;
        }
    }

    /* Handle master key name */
    if (rparams && rparams->realm_mkey_name)
        rdp->realm_mpname = strdup(rparams->realm_mkey_name);
    else
        rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) :
            strdup(KRB5_KDB_M_NAME);
    if (!rdp->realm_mpname) {
        kret = ENOMEM;
        goto whoops;
    }

    /* Handle KDC ports */
    if (rparams && rparams->realm_kdc_ports)
        rdp->realm_ports = strdup(rparams->realm_kdc_ports);
    else
        rdp->realm_ports = strdup(def_udp_ports);
    if (!rdp->realm_ports) {
        kret = ENOMEM;
        goto whoops;
    }
    if (rparams && rparams->realm_kdc_tcp_ports)
        rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports);
    else
        rdp->realm_tcp_ports = strdup(def_tcp_ports);
    if (!rdp->realm_tcp_ports) {
        kret = ENOMEM;
        goto whoops;
    }
    /* Handle stash file */
    if (rparams && rparams->realm_stash_file) {
        rdp->realm_stash = strdup(rparams->realm_stash_file);
        if (!rdp->realm_stash) {
            kret = ENOMEM;
            goto whoops;
        }
        manual = FALSE;
    } else
        manual = def_manual;

    if (rparams && rparams->realm_restrict_anon_valid)
        rdp->realm_restrict_anon = rparams->realm_restrict_anon;
    else
        rdp->realm_restrict_anon = def_restrict_anon;

    /* Handle master key type */
    if (rparams && rparams->realm_enctype_valid)
        rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype;
    else
        rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN;

    /* Handle reject-bad-transit flag */
    if (rparams && rparams->realm_reject_bad_transit_valid)
        rdp->realm_reject_bad_transit = rparams->realm_reject_bad_transit;
    else
        rdp->realm_reject_bad_transit = 1;

    /* Handle ticket maximum life */
    rdp->realm_maxlife = (rparams && rparams->realm_max_life_valid) ?
        rparams->realm_max_life : KRB5_KDB_MAX_LIFE;

    /* Handle ticket renewable maximum life */
    rdp->realm_maxrlife = (rparams && rparams->realm_max_rlife_valid) ?
        rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE;

    /* Handle KDC referrals */
    kret = handle_referral_params(rparams, no_refrls, host_based_srvcs, rdp);
    if (kret == ENOMEM)
        goto whoops;

    if (rparams)
        krb5_free_realm_params(rdp->realm_context, rparams);

    /*
     * We've got our parameters, now go and setup our realm context.
     */

    /* Set the default realm of this context */
    if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) {
        kdc_err(rdp->realm_context, kret,
                _("while setting default realm to %s"), realm);
        goto whoops;
    }

    /* first open the database  before doing anything */
    kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC;
    if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) {
        kdc_err(rdp->realm_context, kret,
                _("while initializing database for realm %s"), realm);
        goto whoops;
    }

    /* Assemble and parse the master key name */
    if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname,
                                        rdp->realm_name, (char **) NULL,
                                        &rdp->realm_mprinc))) {
        kdc_err(rdp->realm_context, kret,
                _("while setting up master key name %s for realm %s"),
                rdp->realm_mpname, realm);
        goto whoops;
    }

    /*
     * Get the master key (note, may not be the most current mkey).
     */
    if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc,
                                   rdp->realm_mkey.enctype, manual,
                                   FALSE, rdp->realm_stash,
                                   &mkvno, NULL, &rdp->realm_mkey))) {
        kdc_err(rdp->realm_context, kret,
                _("while fetching master key %s for realm %s"),
                rdp->realm_mpname, realm);
        goto whoops;
    }

    if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc,
                                        &rdp->realm_mkey, mkvno, &rdp->mkey_list))) {
        kdc_err(rdp->realm_context, kret,
                _("while fetching master keys list for realm %s"), realm);
        goto whoops;
    }


    /* Set up the keytab */
    if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL,
                                   &rdp->realm_keytab))) {
        kdc_err(rdp->realm_context, kret,
                _("while resolving kdb keytab for realm %s"), realm);
        goto whoops;
    }

    /* Preformat the TGS name */
    if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc,
                                     strlen(realm), realm, KRB5_TGS_NAME,
                                     realm, (char *) NULL))) {
        kdc_err(rdp->realm_context, kret,
                _("while building TGS name for realm %s"), realm);
        goto whoops;
    }

    if (!rkey_init_done) {
        krb5_data seed;
        /*
         * If all that worked, then initialize the random key
         * generators.
         */

        seed.length = rdp->realm_mkey.length;
        seed.data = (char *)rdp->realm_mkey.contents;

        if ((kret = krb5_c_random_add_entropy(rdp->realm_context,
                                              KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
            goto whoops;

        rkey_init_done = 1;
    }
whoops:
    /*
     * If we choked, then clean up any dirt we may have dropped on the floor.
     */
    if (kret) {

        finish_realm(rdp);
    }
    return(kret);
}
Пример #19
0
/*
 * Initialize a realm control structure from the alternate profile or from
 * the specified defaults.
 *
 * After we're complete here, the essence of the realm is embodied in the
 * realm data and we should be all set to begin operation for that realm.
 */
static  krb5_error_code
init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm,
           char *def_mpname, krb5_enctype def_enctype, char *def_udp_listen,
           char *def_tcp_listen, krb5_boolean def_manual,
           krb5_boolean def_restrict_anon, char **db_args, char *no_referral,
           char *hostbased)
{
    krb5_error_code     kret;
    krb5_boolean        manual;
    int                 kdb_open_flags;
    char                *svalue = NULL;
    const char          *hierarchy[4];
    krb5_kvno       mkvno = IGNORE_VNO;

    memset(rdp, 0, sizeof(kdc_realm_t));
    if (!realm) {
        kret = EINVAL;
        goto whoops;
    }
    hierarchy[0] = KRB5_CONF_REALMS;
    hierarchy[1] = realm;
    hierarchy[3] = NULL;

    rdp->realm_name = strdup(realm);
    if (rdp->realm_name == NULL) {
        kret = ENOMEM;
        goto whoops;
    }
    kret = krb5int_init_context_kdc(&rdp->realm_context);
    if (kret) {
        kdc_err(NULL, kret, _("while getting context for realm %s"), realm);
        goto whoops;
    }
    if (time_offset != 0)
        (void)krb5_set_time_offsets(rdp->realm_context, time_offset, 0);

    /* Handle master key name */
    hierarchy[2] = KRB5_CONF_MASTER_KEY_NAME;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_mpname)) {
        rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) :
            strdup(KRB5_KDB_M_NAME);
    }
    if (!rdp->realm_mpname) {
        kret = ENOMEM;
        goto whoops;
    }

    /* Handle KDC addresses/ports */
    hierarchy[2] = KRB5_CONF_KDC_LISTEN;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_listen)) {
        /* Try the old kdc_ports configuration option. */
        hierarchy[2] = KRB5_CONF_KDC_PORTS;
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_listen))
            rdp->realm_listen = strdup(def_udp_listen);
    }
    if (!rdp->realm_listen) {
        kret = ENOMEM;
        goto whoops;
    }
    hierarchy[2] = KRB5_CONF_KDC_TCP_LISTEN;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE,
                              &rdp->realm_tcp_listen)) {
        /* Try the old kdc_tcp_ports configuration option. */
        hierarchy[2] = KRB5_CONF_KDC_TCP_PORTS;
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE,
                                  &rdp->realm_tcp_listen))
            rdp->realm_tcp_listen = strdup(def_tcp_listen);
    }
    if (!rdp->realm_tcp_listen) {
        kret = ENOMEM;
        goto whoops;
    }
    /* Handle stash file */
    hierarchy[2] = KRB5_CONF_KEY_STASH_FILE;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_stash))
        manual = def_manual;
    else
        manual = FALSE;

    hierarchy[2] = KRB5_CONF_RESTRICT_ANONYMOUS_TO_TGT;
    if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
                               &rdp->realm_restrict_anon))
        rdp->realm_restrict_anon = def_restrict_anon;

    /* Handle master key type */
    hierarchy[2] = KRB5_CONF_MASTER_KEY_TYPE;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &svalue) ||
        krb5_string_to_enctype(svalue, &rdp->realm_mkey.enctype))
        rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN;
    free(svalue);
    svalue = NULL;

    /* Handle reject-bad-transit flag */
    hierarchy[2] = KRB5_CONF_REJECT_BAD_TRANSIT;
    if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
                                &rdp->realm_reject_bad_transit))
        rdp->realm_reject_bad_transit = TRUE;

    /* Handle assume des-cbc-crc is supported for session keys */
    hierarchy[2] = KRB5_CONF_DES_CRC_SESSION_SUPPORTED;
    if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
                               &rdp->realm_assume_des_crc_sess))
        rdp->realm_assume_des_crc_sess = TRUE;

    /* Handle ticket maximum life */
    hierarchy[2] = KRB5_CONF_MAX_LIFE;
    if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &rdp->realm_maxlife))
        rdp->realm_maxlife = KRB5_KDB_MAX_LIFE;

    /* Handle ticket renewable maximum life */
    hierarchy[2] = KRB5_CONF_MAX_RENEWABLE_LIFE;
    if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &rdp->realm_maxrlife))
        rdp->realm_maxrlife = KRB5_KDB_MAX_RLIFE;

    /* Handle KDC referrals */
    hierarchy[2] = KRB5_CONF_NO_HOST_REFERRAL;
    (void)krb5_aprof_get_string_all(aprof, hierarchy, &svalue);
    kret = combine(no_referral, svalue, &rdp->realm_no_referral);
    if (kret)
        goto whoops;
    free(svalue);
    svalue = NULL;

    hierarchy[2] = KRB5_CONF_HOST_BASED_SERVICES;
    (void)krb5_aprof_get_string_all(aprof, hierarchy, &svalue);
    kret = combine(hostbased, svalue, &rdp->realm_hostbased);
    if (kret)
        goto whoops;
    free(svalue);
    svalue = NULL;

    /*
     * We've got our parameters, now go and setup our realm context.
     */

    /* Set the default realm of this context */
    if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) {
        kdc_err(rdp->realm_context, kret,
                _("while setting default realm to %s"), realm);
        goto whoops;
    }

    /* first open the database  before doing anything */
    kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC;
    if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) {
        kdc_err(rdp->realm_context, kret,
                _("while initializing database for realm %s"), realm);
        goto whoops;
    }

    /* Assemble and parse the master key name */
    if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname,
                                        rdp->realm_name, (char **) NULL,
                                        &rdp->realm_mprinc))) {
        kdc_err(rdp->realm_context, kret,
                _("while setting up master key name %s for realm %s"),
                rdp->realm_mpname, realm);
        goto whoops;
    }

    /*
     * Get the master key (note, may not be the most current mkey).
     */
    if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc,
                                   rdp->realm_mkey.enctype, manual,
                                   FALSE, rdp->realm_stash,
                                   &mkvno, NULL, &rdp->realm_mkey))) {
        kdc_err(rdp->realm_context, kret,
                _("while fetching master key %s for realm %s"),
                rdp->realm_mpname, realm);
        goto whoops;
    }

    if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc,
                                        &rdp->realm_mkey))) {
        kdc_err(rdp->realm_context, kret,
                _("while fetching master keys list for realm %s"), realm);
        goto whoops;
    }


    /* Set up the keytab */
    if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL,
                                   &rdp->realm_keytab))) {
        kdc_err(rdp->realm_context, kret,
                _("while resolving kdb keytab for realm %s"), realm);
        goto whoops;
    }

    /* Preformat the TGS name */
    if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc,
                                     strlen(realm), realm, KRB5_TGS_NAME,
                                     realm, (char *) NULL))) {
        kdc_err(rdp->realm_context, kret,
                _("while building TGS name for realm %s"), realm);
        goto whoops;
    }

    if (!rkey_init_done) {
        krb5_data seed;
        /*
         * If all that worked, then initialize the random key
         * generators.
         */

        seed.length = rdp->realm_mkey.length;
        seed.data = (char *)rdp->realm_mkey.contents;

        if ((kret = krb5_c_random_add_entropy(rdp->realm_context,
                                              KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
            goto whoops;

        rkey_init_done = 1;
    }
whoops:
    /*
     * If we choked, then clean up any dirt we may have dropped on the floor.
     */
    if (kret) {

        finish_realm(rdp);
    }
    return(kret);
}
Пример #20
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);
}
Пример #21
0
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_set_sec_context_option
           (OM_uint32 *minor_status,
            gss_ctx_id_t *context_handle,
            const gss_OID desired_object,
            const gss_buffer_t value)
{
    krb5_context context;
    OM_uint32 maj_stat;

    GSSAPI_KRB5_INIT (&context);

    if (value == GSS_C_NO_BUFFER) {
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) {
	gsskrb5_ctx ctx;
	int flag;

	if (*context_handle == GSS_C_NO_CONTEXT) {
	    *minor_status = EINVAL;
	    return GSS_S_NO_CONTEXT;
	}

	maj_stat = get_bool(minor_status, value, &flag);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;

	ctx = (gsskrb5_ctx)*context_handle;
	HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
	if (flag)
	    ctx->more_flags |= COMPAT_OLD_DES3;
	else
	    ctx->more_flags &= ~COMPAT_OLD_DES3;
	ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
	return GSS_S_COMPLETE;
    } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) {
	int flag;

	maj_stat = get_bool(minor_status, value, &flag);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;

	krb5_set_dns_canonicalize_hostname(context, flag);
	return GSS_S_COMPLETE;

    } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) {
	char *str;

	maj_stat = get_string(minor_status, value, &str);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;

	maj_stat = _gsskrb5_register_acceptor_identity(minor_status, str);
	free(str);

	return maj_stat;

    } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) {
	char *str;

	maj_stat = get_string(minor_status, value, &str);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;
	if (str == NULL) {
	    *minor_status = 0;
	    return GSS_S_CALL_INACCESSIBLE_READ;
	}

	krb5_set_default_realm(context, str);
	free(str);

	*minor_status = 0;
	return GSS_S_COMPLETE;

    } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) {

	*minor_status = EINVAL;
	return GSS_S_FAILURE;

    } else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) {
	char *str;

	maj_stat = get_string(minor_status, value, &str);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;
	if (str == NULL) {
	    *minor_status = 0;
	    return GSS_S_CALL_INACCESSIBLE_READ;
	}

	*minor_status = krb5_cc_set_default_name(context, str);
	free(str);
	if (*minor_status)
	    return GSS_S_FAILURE;

	return GSS_S_COMPLETE;
    } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) {
	OM_uint32 offset;
	time_t t;

	maj_stat = get_int32(minor_status, value, &offset);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;

	t = time(NULL) + offset;

	krb5_set_real_time(context, t, 0);

	*minor_status = 0;
	return GSS_S_COMPLETE;
    } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_TIME_OFFSET_X)) {
	krb5_timestamp sec;
	int32_t usec;
	time_t t;

	t = time(NULL);

	krb5_us_timeofday (context, &sec, &usec);

	maj_stat = set_int32(minor_status, value, sec - t);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;

	*minor_status = 0;
	return GSS_S_COMPLETE;
    } else if (gss_oid_equal(desired_object, GSS_KRB5_PLUGIN_REGISTER_X)) {
	struct gsskrb5_krb5_plugin c;

	if (value->length != sizeof(c)) {
	    *minor_status = EINVAL;
	    return GSS_S_FAILURE;
	}
	memcpy(&c, value->value, sizeof(c));
	krb5_plugin_register(context, c.type, c.name, c.symbol);

	*minor_status = 0;
	return GSS_S_COMPLETE;
    }

    *minor_status = EINVAL;
    return GSS_S_FAILURE;
}
Пример #22
0
int
kt_get(struct get_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    krb5_keytab keytab;
    void *kadm_handle = NULL;
    krb5_enctype *etypes = NULL;
    size_t netypes = 0;
    size_t i;
    int a, j;
    unsigned int failed = 0;

    if((keytab = ktutil_open_keytab()) == NULL)
	return 1;

    if(opt->realm_string)
	krb5_set_default_realm(context, opt->realm_string);

    if (opt->enctypes_strings.num_strings != 0) {

	etypes = malloc (opt->enctypes_strings.num_strings * sizeof(*etypes));
	if (etypes == NULL) {
	    krb5_warnx(context, "malloc failed");
	    goto out;
	}
	netypes = opt->enctypes_strings.num_strings;
	for(i = 0; i < netypes; i++) {
	    ret = krb5_string_to_enctype(context,
					 opt->enctypes_strings.strings[i],
					 &etypes[i]);
	    if(ret) {
		krb5_warnx(context, "unrecognized enctype: %s",
			   opt->enctypes_strings.strings[i]);
		goto out;
	    }
	}
    }


    for(a = 0; a < argc; a++){
	krb5_principal princ_ent;
	kadm5_principal_ent_rec princ;
	int mask = 0;
	krb5_keyblock *keys;
	int n_keys;
	int created = 0;
	krb5_keytab_entry entry;

	ret = krb5_parse_name(context, argv[a], &princ_ent);
	if (ret) {
	    krb5_warn(context, ret, "can't parse principal %s", argv[a]);
	    failed++;
	    continue;
	}
	memset(&princ, 0, sizeof(princ));
	princ.principal = princ_ent;
	mask |= KADM5_PRINCIPAL;
	princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
	mask |= KADM5_ATTRIBUTES;
	princ.princ_expire_time = 0;
	mask |= KADM5_PRINC_EXPIRE_TIME;

	if(kadm_handle == NULL) {
	    const char *r;
	    if(opt->realm_string != NULL)
		r = opt->realm_string;
	    else
		r = krb5_principal_get_realm(context, princ_ent);
	    kadm_handle = open_kadmin_connection(opt->principal_string,
						 r,
						 opt->admin_server_string,
						 opt->server_port_integer);
	    if(kadm_handle == NULL)
		break;
	}

	ret = kadm5_create_principal(kadm_handle, &princ, mask, "x");
	if(ret == 0)
	    created = 1;
	else if(ret != KADM5_DUP) {
	    krb5_warn(context, ret, "kadm5_create_principal(%s)", argv[a]);
	    krb5_free_principal(context, princ_ent);
	    failed++;
	    continue;
	}
	ret = kadm5_randkey_principal(kadm_handle, princ_ent, &keys, &n_keys);
	if (ret) {
	    krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[a]);
	    krb5_free_principal(context, princ_ent);
	    failed++;
	    continue;
	}

	ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
			      KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
	if (ret) {
	    krb5_warn(context, ret, "kadm5_get_principal(%s)", argv[a]);
	    for (j = 0; j < n_keys; j++)
		krb5_free_keyblock_contents(context, &keys[j]);
	    krb5_free_principal(context, princ_ent);
	    failed++;
	    continue;
	}
	if(!created && (princ.attributes & KRB5_KDB_DISALLOW_ALL_TIX))
	    krb5_warnx(context, "%s: disallow-all-tix flag set - clearing", argv[a]);
	princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
	mask = KADM5_ATTRIBUTES;
	if(created) {
	    princ.kvno = 1;
	    mask |= KADM5_KVNO;
	}
	ret = kadm5_modify_principal(kadm_handle, &princ, mask);
	if (ret) {
	    krb5_warn(context, ret, "kadm5_modify_principal(%s)", argv[a]);
	    for (j = 0; j < n_keys; j++)
		krb5_free_keyblock_contents(context, &keys[j]);
	    krb5_free_principal(context, princ_ent);
	    failed++;
	    continue;
	}
	for(j = 0; j < n_keys; j++) {
	    int do_add = TRUE;

	    if (netypes) {
		size_t k;

		do_add = FALSE;
		for (k = 0; k < netypes; ++k)
		    if (keys[j].keytype == etypes[k]) {
			do_add = TRUE;
			break;
		    }
	    }
	    if (do_add) {
		entry.principal = princ_ent;
		entry.vno = princ.kvno;
		entry.keyblock = keys[j];
		entry.timestamp = time (NULL);
		ret = krb5_kt_add_entry(context, keytab, &entry);
		if (ret)
		    krb5_warn(context, ret, "krb5_kt_add_entry");
	    }
	    krb5_free_keyblock_contents(context, &keys[j]);
	}

	kadm5_free_principal_ent(kadm_handle, &princ);
	krb5_free_principal(context, princ_ent);
    }
 out:
    free(etypes);
    if (kadm_handle)
	kadm5_destroy(kadm_handle);
    krb5_kt_close(context, keytab);
    return ret != 0 || failed > 0;
}
Пример #23
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);
}
OM_uint32
_gsskrb5_set_sec_context_option
           (OM_uint32 *minor_status,
            gss_ctx_id_t *context_handle,
            const gss_OID desired_object,
            const gss_buffer_t value)
{
    OM_uint32 maj_stat;

    GSSAPI_KRB5_INIT ();

    if (value == GSS_C_NO_BUFFER) {
	*minor_status = EINVAL;
	return GSS_S_FAILURE;
    }

    if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) {
	gsskrb5_ctx ctx;
	int flag;

	if (*context_handle == GSS_C_NO_CONTEXT) {
	    *minor_status = EINVAL;
	    return GSS_S_NO_CONTEXT;
	}

	maj_stat = get_bool(minor_status, value, &flag);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;

	ctx = (gsskrb5_ctx)*context_handle;
	HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
	if (flag)
	    ctx->more_flags |= COMPAT_OLD_DES3;
	else
	    ctx->more_flags &= ~COMPAT_OLD_DES3;
	ctx->more_flags |= COMPAT_OLD_DES3_SELECTED;
	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
	return GSS_S_COMPLETE;
    } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) {
	int flag;

	maj_stat = get_bool(minor_status, value, &flag);
	if (maj_stat != GSS_S_COMPLETE)
	    return maj_stat;

	krb5_set_dns_canonicalize_hostname(_gsskrb5_context, flag);
	return GSS_S_COMPLETE;

    } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) {
	char *str;

	if (value == NULL || value->length == 0) {
	    str = NULL;
	} else {
	    str = malloc(value->length + 1);
	    if (str) {
		*minor_status = 0;
		return GSS_S_UNAVAILABLE;
	    }
	    memcpy(str, value->value, value->length);
	    str[value->length] = '\0';
	}

	_gsskrb5_register_acceptor_identity(str);
	free(str);

	*minor_status = 0;
	return GSS_S_COMPLETE;

    } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) {
	char *str;

	if (value == NULL || value->length == 0) {
	    *minor_status = 0;
	    return GSS_S_CALL_INACCESSIBLE_READ;
	}
	str = malloc(value->length + 1);
	if (str) {
	    *minor_status = 0;
	    return GSS_S_UNAVAILABLE;
	}
	memcpy(str, value->value, value->length);
	str[value->length] = '\0';

	krb5_set_default_realm(_gsskrb5_context, str);
	free(str);

	*minor_status = 0;
	return GSS_S_COMPLETE;

    } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) {

	if (value == NULL || value->length == 0) {
	    krb5_set_send_to_kdc_func(_gsskrb5_context, NULL, NULL);
	} else {
	    struct gsskrb5_send_to_kdc c;

	    if (value->length != sizeof(c)) {
		*minor_status = EINVAL;
		return GSS_S_FAILURE;
	    }
	    memcpy(&c, value->value, sizeof(c));
	    krb5_set_send_to_kdc_func(_gsskrb5_context,
				      (krb5_send_to_kdc_func)c.func, 
				      c.ptr);
	}

	*minor_status = 0;
	return GSS_S_COMPLETE;
    }


    *minor_status = EINVAL;
    return GSS_S_FAILURE;
}
Пример #25
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    char **files;
    kadm5_config_params conf;
    int optidx = 0;
    int exit_status = 0;

    setprogname(argv[0]);

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

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

    if (help_flag)
	usage (0);

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

    argc -= optidx;
    argv += optidx;

    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");

    memset(&conf, 0, sizeof(conf));
    if(realm) {
	krb5_set_default_realm(context, realm); /* XXX should be fixed
						   some other way */
	conf.realm = realm;
	conf.mask |= KADM5_CONFIG_REALM;
    }

    if (admin_server) {
	conf.admin_server = admin_server;
	conf.mask |= KADM5_CONFIG_ADMIN_SERVER;
    }

    if (server_port) {
	conf.kadmind_port = htons(server_port);
	conf.mask |= KADM5_CONFIG_KADMIND_PORT;
    }

    if (keyfile) {
	conf.stash_file = keyfile;
	conf.mask |= KADM5_CONFIG_STASH_FILE;
    }

    if(local_flag) {
	int i;

	kadm5_setup_passwd_quality_check (context,
					  check_library, check_function);

	for (i = 0; i < policy_libraries.num_strings; i++) {
	    ret = kadm5_add_passwd_quality_verifier(context,
						    policy_libraries.strings[i]);
	    if (ret)
		krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier");
	}
	ret = kadm5_add_passwd_quality_verifier(context, NULL);
	if (ret)
	    krb5_err(context, 1, ret, "kadm5_add_passwd_quality_verifier");

	ret = kadm5_s_init_with_password_ctx(context,
					     KADM5_ADMIN_SERVICE,
					     NULL,
					     KADM5_ADMIN_SERVICE,
					     &conf, 0, 0,
					     &kadm_handle);
    } else if (mit_flag) {
	ret = kadm5_mit_init_with_password_ctx(context,
					       client_name,
					       NULL,
					       &conf, 0, 0,
					       &kadm_handle);
    } else if (ad_flag) {
	if (client_name == NULL)
	    krb5_errx(context, 1, "keytab mode require principal name");
	ret = kadm5_ad_init_with_password_ctx(context,
					      client_name,
					      NULL,
					      KADM5_ADMIN_SERVICE,
					      &conf, 0, 0,
					      &kadm_handle);
    } else if (keytab) {
	if (client_name == NULL)
	    krb5_errx(context, 1, "keytab mode require principal name");
        ret = kadm5_c_init_with_skey_ctx(context,
					 client_name,
					 keytab,
					 KADM5_ADMIN_SERVICE,
                                         &conf, 0, 0,
                                         &kadm_handle);
    } else
	ret = kadm5_c_init_with_password_ctx(context,
					     client_name,
					     NULL,
					     KADM5_ADMIN_SERVICE,
					     &conf, 0, 0,
					     &kadm_handle);

    if(ret)
	krb5_err(context, 1, ret, "kadm5_init_with_password");

    signal(SIGINT, SIG_IGN); /* ignore signals for now, the sl command
                                parser will handle SIGINT its own way;
                                we should really take care of this in
                                each function, f.i `get' might be
                                interruptable, but not `create' */
    if (argc != 0) {
	ret = sl_command (commands, argc, argv);
	if(ret == -1)
	    krb5_warnx (context, "unrecognized command: %s", argv[0]);
	else if (ret == -2)
	    ret = 0;
	if(ret != 0)
	    exit_status = 1;
    } else {
	while(!exit_seen) {
	    ret = sl_command_loop(commands, "kadmin> ", NULL);
	    if (ret == -2)
		exit_seen = 1;
	    else if (ret != 0)
		exit_status = 1;
	}
    }

    kadm5_destroy(kadm_handle);
    krb5_free_context(context);
    return exit_status;
}
Пример #26
0
static void
test_enterprise(krb5_context context)
{
    krb5_error_code ret;
    char *unparsed;
    krb5_principal p;

    ret = krb5_set_default_realm(context, "SAMBA.ORG");
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    ret = krb5_parse_name_flags(context, "[email protected]@WIN.SU.SE",
				KRB5_PRINCIPAL_PARSE_ENTERPRISE, &p);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name_flags");

    ret = krb5_unparse_name(context, p, &unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name");

    krb5_free_principal(context, p);

    if (strcmp(unparsed, "lha\\@[email protected]") != 0)
	krb5_errx(context, 1, "enterprise name failed 1");
    free(unparsed);

    /*
     *
     */

    ret = krb5_parse_name_flags(context, "lha\\@[email protected]",
				KRB5_PRINCIPAL_PARSE_ENTERPRISE, &p);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name_flags");

    ret = krb5_unparse_name(context, p, &unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name");

    krb5_free_principal(context, p);
    if (strcmp(unparsed, "lha\\@su.se\\@[email protected]") != 0)
	krb5_errx(context, 1, "enterprise name failed 2: %s", unparsed);
    free(unparsed);

    /*
     *
     */

    ret = krb5_parse_name_flags(context, "lha\\@[email protected]", 0, &p);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name_flags");

    ret = krb5_unparse_name(context, p, &unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name");

    krb5_free_principal(context, p);
    if (strcmp(unparsed, "lha\\@[email protected]") != 0)
	krb5_errx(context, 1, "enterprise name failed 3");
    free(unparsed);

    /*
     *
     */

    ret = krb5_parse_name_flags(context, "*****@*****.**",
				KRB5_PRINCIPAL_PARSE_ENTERPRISE, &p);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name_flags");

    ret = krb5_unparse_name(context, p, &unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name");

    krb5_free_principal(context, p);
    if (strcmp(unparsed, "lha\\@[email protected]") != 0)
	krb5_errx(context, 1, "enterprise name failed 2: %s", unparsed);
    free(unparsed);
}
Пример #27
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache ccache = NULL;
    HDB *db = NULL;
    int optidx = 0;

    int type, exit_code;

    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)
	exit(1);

    /* We may be reading an old database encrypted with a DES master key. */
    ret = krb5_allow_weak_crypto(context, 1);
    if(ret)
        krb5_err(context, 1, ret, "krb5_allow_weak_crypto");

    if(local_realm)
	krb5_set_default_realm(context, local_realm);

    if(encrypt_flag && decrypt_flag)
	krb5_errx(context, 1,
		  "only one of `--encrypt' and `--decrypt' is meaningful");

    if(source_type != NULL) {
	type = parse_source_type(source_type);
	if(type == 0)
	    krb5_errx(context, 1, "unknown source type `%s'", source_type);
    } else
	type = HPROP_HEIMDAL;

    if(!to_stdout)
	get_creds(context, &ccache);

    if(decrypt_flag || encrypt_flag) {
	ret = hdb_read_master_key(context, mkeyfile, &mkey5);
	if(ret && ret != ENOENT)
	    krb5_err(context, 1, ret, "hdb_read_master_key");
	if(ret)
	    krb5_errx(context, 1, "No master key file found");
    }

    switch(type) {
    case HPROP_MIT_DUMP:
	if (database == NULL)
	    krb5_errx(context, 1, "no dump file specified");
	break;
    case HPROP_HEIMDAL:
	ret = hdb_create (context, &db, database);
	if(ret)
	    krb5_err(context, 1, ret, "hdb_create: %s", database);
	ret = db->hdb_open(context, db, O_RDONLY, 0);
	if(ret)
	    krb5_err(context, 1, ret, "db->hdb_open");
	break;
    default:
	krb5_errx(context, 1, "unknown dump type `%d'", type);
	break;
    }

    if (to_stdout)
	exit_code = dump_database (context, type, database, db);
    else
	exit_code = propagate_database (context, type, database,
					db, ccache, optidx, argc, argv);

    if(ccache != NULL)
	krb5_cc_destroy(context, ccache);

    if(db != NULL)
	(*db->hdb_destroy)(context, db);

    krb5_free_context(context);
    return exit_code;
}
Пример #28
0
static int
CommandProc(struct cmd_syndesc *as, void *arock)
{
    krb5_principal princ = 0;
    char *cell, *pname, **hrealms, *service;
    char service_temp[MAXKTCREALMLEN + 20];
    krb5_creds incred[1], mcred[1], *outcred = 0, *afscred;
    krb5_ccache cc = 0;
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
    krb5_get_init_creds_opt *gic_opts;
#else
    krb5_get_init_creds_opt gic_opts[1];
#endif
    char *tofree = NULL, *outname;
    int code;
    char *what;
    int i, dosetpag, evil, noprdb, id;
#ifdef AFS_RXK5
    int authtype;
#endif
    krb5_data enc_part[1];
    krb5_prompter_fct pf = NULL;
    char *pass = 0;
    void *pa = 0;
    struct kp_arg klog_arg[1];

    char passwd[BUFSIZ];
    struct afsconf_cell cellconfig[1];

    static char rn[] = "klog";	/*Routine name */
    static int Pipe = 0;	/* reading from a pipe */
    static int Silent = 0;	/* Don't want error messages */

    int writeTicketFile = 0;	/* write ticket file to /tmp */

    service = 0;
    memset(incred, 0, sizeof *incred);
    /* blow away command line arguments */
    for (i = 1; i < zero_argc; i++)
	memset(zero_argv[i], 0, strlen(zero_argv[i]));
    zero_argc = 0;
    memset(klog_arg, 0, sizeof *klog_arg);

    /* first determine quiet flag based on -silent switch */
    Silent = (as->parms[aSILENT].items ? 1 : 0);

    if (Silent) {
	afs_set_com_err_hook(silent_errors);
    }

    if ((code = krb5_init_context(&k5context))) {
	afs_com_err(rn, code, "while initializing Kerberos 5 library");
	KLOGEXIT(code);
    }
    if ((code = rx_Init(0))) {
	afs_com_err(rn, code, "while initializing rx");
	KLOGEXIT(code);
    }
    initialize_U_error_table();
    /*initialize_krb5_error_table();*/
    initialize_RXK_error_table();
    initialize_KTC_error_table();
    initialize_ACFG_error_table();
    /* initialize_rx_error_table(); */
    if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
	afs_com_err(rn, 0, "can't get afs configuration (afsconf_Open(%s))",
	    AFSDIR_CLIENT_ETC_DIRPATH);
	KLOGEXIT(1);
    }

    /*
     * Enable DES enctypes, which are currently still required for AFS.
     * krb5_allow_weak_crypto is MIT Kerberos 1.8.  krb5_enctype_enable is
     * Heimdal.
     */
#if defined(HAVE_KRB5_ENCTYPE_ENABLE)
    i = krb5_enctype_valid(k5context, ETYPE_DES_CBC_CRC);
    if (i)
        krb5_enctype_enable(k5context, ETYPE_DES_CBC_CRC);
#elif defined(HAVE_KRB5_ALLOW_WEAK_CRYPTO)
    krb5_allow_weak_crypto(k5context, 1);
#endif

    /* Parse remaining arguments. */

    dosetpag = !! as->parms[aSETPAG].items;
    Pipe = !! as->parms[aPIPE].items;
    writeTicketFile = !! as->parms[aTMP].items;
    noprdb = !! as->parms[aNOPRDB].items;
    evil = (always_evil&1) || !! as->parms[aUNWRAP].items;

#ifdef AFS_RXK5
    authtype = 0;
    if (as->parms[aK5].items)
	authtype |= FORCE_RXK5;
    if (as->parms[aK4].items)
	authtype |= FORCE_RXKAD;
    if (!authtype)
	authtype |= env_afs_rxk5_default();
#endif

    cell = as->parms[aCELL].items ? as->parms[aCELL].items->data : 0;
    if ((code = afsconf_GetCellInfo(tdir, cell, "afsprot", cellconfig))) {
	if (cell)
	    afs_com_err(rn, code, "Can't get cell information for '%s'", cell);
	else
	    afs_com_err(rn, code, "Can't get determine local cell!");
	KLOGEXIT(code);
    }

    if (as->parms[aKRBREALM].items) {
	code = krb5_set_default_realm(k5context,
		as->parms[aKRBREALM].items->data);
	if (code) {
	    afs_com_err(rn, code, "Can't make <%s> the default realm",
		as->parms[aKRBREALM].items->data);
	    KLOGEXIT(code);
	}
    }
    else if ((code = krb5_get_host_realm(k5context, cellconfig->hostName[0], &hrealms))) {
	afs_com_err(rn, code, "Can't get realm for host <%s> in cell <%s>\n",
		cellconfig->hostName[0], cellconfig->name);
	KLOGEXIT(code);
    } else {
	if (hrealms && *hrealms) {
	    code = krb5_set_default_realm(k5context,
		    *hrealms);
	    if (code) {
		afs_com_err(rn, code, "Can't make <%s> the default realm",
		    *hrealms);
		KLOGEXIT(code);
	    }
	}
	if (hrealms) krb5_free_host_realm(k5context, hrealms);
    }

    id = getuid();
    if (as->parms[aPRINCIPAL].items) {
	pname = as->parms[aPRINCIPAL].items->data;
    } else {
	/* No explicit name provided: use Unix uid. */
	struct passwd *pw;
	pw = getpwuid(id);
	if (pw == 0) {
	    afs_com_err(rn, 0,
		"Can't figure out your name from your user id (%d).", id);
	    if (!Silent)
		fprintf(stderr, "%s: Try providing the user name.\n", rn);
	    KLOGEXIT(1);
	}
	pname = pw->pw_name;
    }
    code = krb5_parse_name(k5context, pname, &princ);
    if (code) {
	afs_com_err(rn, code, "Can't parse principal <%s>", pname);
	KLOGEXIT(code);
    }

    if (as->parms[aPASSWORD].items) {
	/*
	 * Current argument is the desired password string.  Remember it in
	 * our local buffer, and zero out the argument string - anyone can
	 * see it there with ps!
	 */
	strncpy(passwd, as->parms[aPASSWORD].items->data, sizeof(passwd));
	memset(as->parms[aPASSWORD].items->data, 0,
	       strlen(as->parms[aPASSWORD].items->data));
	pass = passwd;
    }

    /* Get the password if it wasn't provided. */
    if (!pass) {
	if (Pipe) {
	    strncpy(passwd, getpipepass(), sizeof(passwd));
	    pass = passwd;
	} else {
	    pf = klog_prompter;
	    pa = klog_arg;
	}
    }

    service = 0;
#ifdef AFS_RXK5
    if (authtype & FORCE_RXK5) {
	tofree = get_afs_krb5_svc_princ(cellconfig);
	snprintf(service_temp, sizeof service_temp, "%s", tofree);
    } else
#endif
    snprintf (service_temp, sizeof service_temp, "afs/%s", cellconfig->name);

    klog_arg->pp = &pass;
    klog_arg->pstore = passwd;
    klog_arg->allocated = sizeof(passwd);
    /* XXX should allow k5 to prompt in most cases -- what about expired pw?*/
#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
    code = krb5_get_init_creds_opt_alloc(k5context, &gic_opts);
    if (code) {
	afs_com_err(rn, code, "Can't allocate get_init_creds options");
	KLOGEXIT(code);
    }
#else
    krb5_get_init_creds_opt_init(gic_opts);
#endif

    for (;;) {
        code = krb5_get_init_creds_password(k5context,
	    incred,
	    princ,
	    pass,
	    pf,	/* prompter */
	    pa,	/* data */
	    0,	/* start_time */
	    0,	/* in_tkt_service */
	    gic_opts);
	if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
            break;
    }
    memset(passwd, 0, sizeof(passwd));
    if (code) {
	char *r = 0;
	if (krb5_get_default_realm(k5context, &r))
	    r = 0;
	if (r)
	    afs_com_err(rn, code, "Unable to authenticate in realm %s", r);
	else
	    afs_com_err(rn, code, "Unable to authenticate to use cell %s",
		cellconfig->name);
	if (r) free(r);
	KLOGEXIT(code);
    }

    for (;;writeTicketFile = 0) {
        if (writeTicketFile) {
            what = "getting default ccache";
            code = krb5_cc_default(k5context, &cc);
        } else {
            what = "krb5_cc_resolve";
            code = krb5_cc_resolve(k5context, "MEMORY:core", &cc);
            if (code) goto Failed;
        }
        what = "initializing ccache";
        code = krb5_cc_initialize(k5context, cc, princ);
        if (code) goto Failed;
        what = "writing Kerberos ticket file";
        code = krb5_cc_store_cred(k5context, cc, incred);
        if (code) goto Failed;
        if (writeTicketFile)
            fprintf(stderr,
                    "Wrote ticket file to %s\n",
                    krb5_cc_get_name(k5context, cc));
        break;
      Failed:
        if (code)
            afs_com_err(rn, code, "%s", what);
        if (writeTicketFile) {
            if (cc) {
                krb5_cc_close(k5context, cc);
                cc = 0;
            }
            continue;
        }
        KLOGEXIT(code);
    }

    for (service = service_temp;;service = "afs") {
        memset(mcred, 0, sizeof *mcred);
        mcred->client = princ;
        code = krb5_parse_name(k5context, service, &mcred->server);
        if (code) {
            afs_com_err(rn, code, "Unable to parse service <%s>\n", service);
            KLOGEXIT(code);
        }
        if (tofree) { free(tofree); tofree = 0; }
        if (!(code = krb5_unparse_name(k5context, mcred->server, &outname)))
            tofree = outname;
        else outname = service;
        code = krb5_get_credentials(k5context, 0, cc, mcred, &outcred);
        krb5_free_principal(k5context, mcred->server);
        if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN || service != service_temp) break;
#ifdef AFS_RXK5
        if (authtype & FORCE_RXK5)
            break;
#endif
    }
    afscred = outcred;

    if (code) {
	afs_com_err(rn, code, "Unable to get credentials to use %s", outname);
	KLOGEXIT(code);
    }

#ifdef AFS_RXK5
    if (authtype & FORCE_RXK5) {
	struct ktc_principal aserver[1];
	int viceid = 555;

	memset(aserver, 0, sizeof *aserver);
	strncpy(aserver->cell, cellconfig->name, MAXKTCREALMLEN-1);
	code = ktc_SetK5Token(k5context, aserver, afscred, viceid, dosetpag);
	if (code) {
	    afs_com_err(rn, code, "Unable to store tokens for cell %s\n",
		cellconfig->name);
	    KLOGEXIT(1);
	}
    } else
#endif
    {
	struct ktc_principal aserver[1], aclient[1];
	struct ktc_token atoken[1];

	memset(atoken, 0, sizeof *atoken);
	if (evil) {
	    size_t elen = enc_part->length;
	    atoken->kvno = RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY;
	    if (afs_krb5_skip_ticket_wrapper(afscred->ticket.data,
			afscred->ticket.length, (char **) &enc_part->data,
			&elen)) {
		afs_com_err(rn, 0, "Can't unwrap %s AFS credential",
		    cellconfig->name);
		KLOGEXIT(1);
	    }
	} else {
	    atoken->kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
	    *enc_part = afscred->ticket;
	}
	atoken->startTime = afscred->times.starttime;
	atoken->endTime = afscred->times.endtime;
	if (tkt_DeriveDesKey(get_creds_enctype(afscred),
			     get_cred_keydata(afscred),
			     get_cred_keylen(afscred), &atoken->sessionKey)) {
	    afs_com_err(rn, 0,
			"Cannot derive DES key from enctype %i of length %u",
			get_creds_enctype(afscred),
			(unsigned)get_cred_keylen(afscred));
	    KLOGEXIT(1);
	}
	memcpy(atoken->ticket, enc_part->data,
	    atoken->ticketLen = enc_part->length);
	memset(aserver, 0, sizeof *aserver);
	strncpy(aserver->name, "afs", 4);
	strncpy(aserver->cell, cellconfig->name, MAXKTCREALMLEN-1);
	memset(aclient, 0, sizeof *aclient);
	i = realm_len(k5context, afscred->client);
	if (i > MAXKTCREALMLEN-1) i = MAXKTCREALMLEN-1;
	memcpy(aclient->cell, realm_data(k5context, afscred->client), i);
	if (!noprdb) {
	    int viceid = 0;
	    k5_to_k4_name(k5context, afscred->client, aclient);
	    code = whoami(atoken, cellconfig, aclient, &viceid);
	    if (code) {
		afs_com_err(rn, code, "Can't get your viceid for cell %s", cellconfig->name);
		*aclient->name = 0;
	    } else
		snprintf(aclient->name, MAXKTCNAMELEN-1, "AFS ID %d", viceid);
	}
	if (!*aclient->name)
	    k5_to_k4_name(k5context, afscred->client, aclient);
	code = ktc_SetToken(aserver, atoken, aclient, dosetpag);
	if (code) {
	    afs_com_err(rn, code, "Unable to store tokens for cell %s\n",
		cellconfig->name);
	    KLOGEXIT(1);
	}
    }

    krb5_free_principal(k5context, princ);
    krb5_free_cred_contents(k5context, incred);
    if (outcred) krb5_free_creds(k5context, outcred);
    if (cc)
	krb5_cc_close(k5context, cc);
    if (tofree) free(tofree);

    return 0;
}
Пример #29
0
static void
test_princ(krb5_context context)
{
    const char *princ = "*****@*****.**";
    const char *princ_short = "lha";
    const char *noquote;
    krb5_error_code ret;
    char *princ_unparsed;
    char *princ_reformed = NULL;
    const char *realm;

    krb5_principal p, p2;

    ret = krb5_parse_name(context, princ, &p);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    ret = krb5_unparse_name(context, p, &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (strcmp(princ, princ_unparsed)) {
	krb5_errx(context, 1, "%s != %s", princ, princ_unparsed);
    }

    free(princ_unparsed);

    ret = krb5_unparse_name_flags(context, p,
				  KRB5_PRINCIPAL_UNPARSE_NO_REALM,
				  &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (strcmp(princ_short, princ_unparsed))
	krb5_errx(context, 1, "%s != %s", princ_short, princ_unparsed);
    free(princ_unparsed);

    realm = krb5_principal_get_realm(context, p);

    if (asprintf(&princ_reformed, "%s@%s", princ_short, realm) < 0 || princ_reformed == NULL)
	errx(1, "malloc");

    ret = krb5_parse_name(context, princ_reformed, &p2);
    free(princ_reformed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (!krb5_principal_compare(context, p, p2)) {
	krb5_errx(context, 1, "p != p2");
    }

    krb5_free_principal(context, p2);

    ret = krb5_set_default_realm(context, "SU.SE");
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    ret = krb5_unparse_name_flags(context, p,
				  KRB5_PRINCIPAL_UNPARSE_SHORT,
				  &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (strcmp(princ_short, princ_unparsed))
	krb5_errx(context, 1, "'%s' != '%s'", princ_short, princ_unparsed);
    free(princ_unparsed);

    ret = krb5_parse_name(context, princ_short, &p2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (!krb5_principal_compare(context, p, p2))
	krb5_errx(context, 1, "p != p2");
    krb5_free_principal(context, p2);

    ret = krb5_unparse_name(context, p, &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (strcmp(princ, princ_unparsed))
	krb5_errx(context, 1, "'%s' != '%s'", princ, princ_unparsed);
    free(princ_unparsed);

    ret = krb5_set_default_realm(context, "SAMBA.ORG");
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    ret = krb5_parse_name(context, princ_short, &p2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (krb5_principal_compare(context, p, p2))
	krb5_errx(context, 1, "p == p2");

    if (!krb5_principal_compare_any_realm(context, p, p2))
	krb5_errx(context, 1, "(ignoring realms) p != p2");

    ret = krb5_unparse_name(context, p2, &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (strcmp(princ, princ_unparsed) == 0)
	krb5_errx(context, 1, "%s == %s", princ, princ_unparsed);
    free(princ_unparsed);

    krb5_free_principal(context, p2);

    ret = krb5_parse_name(context, princ, &p2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (!krb5_principal_compare(context, p, p2))
	krb5_errx(context, 1, "p != p2");

    ret = krb5_unparse_name(context, p2, &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (strcmp(princ, princ_unparsed))
	krb5_errx(context, 1, "'%s' != '%s'", princ, princ_unparsed);
    free(princ_unparsed);

    krb5_free_principal(context, p2);

    ret = krb5_unparse_name_flags(context, p,
				  KRB5_PRINCIPAL_UNPARSE_SHORT,
				  &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name_short");

    if (strcmp(princ, princ_unparsed) != 0)
	krb5_errx(context, 1, "'%s' != '%s'", princ, princ_unparsed);
    free(princ_unparsed);

    ret = krb5_unparse_name(context, p, &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name_short");

    if (strcmp(princ, princ_unparsed))
	krb5_errx(context, 1, "'%s' != '%s'", princ, princ_unparsed);
    free(princ_unparsed);

    ret = krb5_parse_name_flags(context, princ,
				KRB5_PRINCIPAL_PARSE_NO_REALM,
				&p2);
    if (!ret)
	krb5_err(context, 1, ret, "Should have failed to parse %s a "
		 "short name", princ);

    ret = krb5_parse_name_flags(context, princ_short,
				KRB5_PRINCIPAL_PARSE_NO_REALM,
				&p2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    ret = krb5_unparse_name_flags(context, p2,
				  KRB5_PRINCIPAL_UNPARSE_NO_REALM,
				  &princ_unparsed);
    krb5_free_principal(context, p2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name_norealm");

    if (strcmp(princ_short, princ_unparsed))
	krb5_errx(context, 1, "'%s' != '%s'", princ_short, princ_unparsed);
    free(princ_unparsed);

    ret = krb5_parse_name_flags(context, princ_short,
				KRB5_PRINCIPAL_PARSE_REQUIRE_REALM,
				&p2);
    if (!ret)
	krb5_err(context, 1, ret, "Should have failed to parse %s "
		 "because it lacked a realm", princ_short);

    ret = krb5_parse_name_flags(context, princ,
				KRB5_PRINCIPAL_PARSE_REQUIRE_REALM,
				&p2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    if (!krb5_principal_compare(context, p, p2))
	krb5_errx(context, 1, "p != p2");

    ret = krb5_unparse_name_flags(context, p2,
				  KRB5_PRINCIPAL_UNPARSE_NO_REALM,
				  &princ_unparsed);
    krb5_free_principal(context, p2);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name_norealm");

    if (strcmp(princ_short, princ_unparsed))
	krb5_errx(context, 1, "'%s' != '%s'", princ_short, princ_unparsed);
    free(princ_unparsed);

    krb5_free_principal(context, p);

    /* test quoting */

    princ = "test\\ [email protected]";
    noquote = "test [email protected]";

    ret = krb5_parse_name_flags(context, princ, 0, &p);
    if (ret)
	krb5_err(context, 1, ret, "krb5_parse_name");

    ret = krb5_unparse_name_flags(context, p, 0, &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name_flags");

    if (strcmp(princ, princ_unparsed))
	krb5_errx(context, 1, "q '%s' != '%s'", princ, princ_unparsed);
    free(princ_unparsed);

    ret = krb5_unparse_name_flags(context, p, KRB5_PRINCIPAL_UNPARSE_DISPLAY,
				  &princ_unparsed);
    if (ret)
	krb5_err(context, 1, ret, "krb5_unparse_name_flags");

    if (strcmp(noquote, princ_unparsed))
	krb5_errx(context, 1, "nq '%s' != '%s'", noquote, princ_unparsed);
    free(princ_unparsed);

    krb5_free_principal(context, p);
}
Пример #30
0
int
main(int argc, char **argv)
{
    struct testcase *t;
    krb5_context context;
    krb5_error_code ret;
    int val = 0;

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

    /* to enable realm-less principal name above */

    krb5_set_default_realm(context, "");

    for (t = tests; t->input_string; ++t) {
	krb5_principal princ;
	int i, j;
	char name_buf[1024];
	char *s;

	ret = krb5_parse_name(context, t->input_string, &princ);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_parse_name %s",
		      t->input_string);
	if (strcmp (t->realm, princ->realm) != 0) {
	    printf ("wrong realm (\"%s\" should be \"%s\")"
		    " for \"%s\"\n",
		    princ->realm, t->realm,
		    t->input_string);
	    val = 1;
	}

	if (t->ncomponents != princ->name.name_string.len) {
	    printf ("wrong number of components (%u should be %u)"
		    " for \"%s\"\n",
		    princ->name.name_string.len, t->ncomponents,
		    t->input_string);
	    val = 1;
	} else {
	    for (i = 0; i < t->ncomponents; ++i) {
		if (strcmp(t->comp_val[i],
			   princ->name.name_string.val[i]) != 0) {
		    printf ("bad component %d (\"%s\" should be \"%s\")"
			    " for \"%s\"\n",
			    i,
			    princ->name.name_string.val[i],
			    t->comp_val[i],
			    t->input_string);
		    val = 1;
		}
	    }
	}
	for (j = 0; j < strlen(t->output_string); ++j) {
	    ret = krb5_unparse_name_fixed(context, princ,
					  name_buf, j);
	    if (ret != ERANGE) {
		printf ("unparse_name %s with length %d should have failed\n",
			t->input_string, j);
		val = 1;
		break;
	    }
	}
	ret = krb5_unparse_name_fixed(context, princ,
				      name_buf, sizeof(name_buf));
	if (ret)
	    krb5_err (context, 1, ret, "krb5_unparse_name_fixed");

	if (strcmp (t->output_string, name_buf) != 0) {
	    printf ("failed comparing the re-parsed"
		    " (\"%s\" should be \"%s\")\n",
		    name_buf, t->output_string);
	    val = 1;
	}

	ret = krb5_unparse_name(context, princ, &s);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_unparse_name");

	if (strcmp (t->output_string, s) != 0) {
	    printf ("failed comparing the re-parsed"
		    " (\"%s\" should be \"%s\"\n",
		    s, t->output_string);
	    val = 1;
	}
	free(s);

	if (!t->realmp) {
	    for (j = 0; j < strlen(t->input_string); ++j) {
		ret = krb5_unparse_name_fixed_short(context, princ,
						    name_buf, j);
		if (ret != ERANGE) {
		    printf ("unparse_name_short %s with length %d"
			    " should have failed\n",
			    t->input_string, j);
		    val = 1;
		    break;
		}
	    }
	    ret = krb5_unparse_name_fixed_short(context, princ,
						name_buf, sizeof(name_buf));
	    if (ret)
		krb5_err (context, 1, ret, "krb5_unparse_name_fixed");

	    if (strcmp (t->input_string, name_buf) != 0) {
		printf ("failed comparing the re-parsed"
			" (\"%s\" should be \"%s\")\n",
			name_buf, t->input_string);
		val = 1;
	    }

	    ret = krb5_unparse_name_short(context, princ, &s);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_unparse_name_short");

	    if (strcmp (t->input_string, s) != 0) {
		printf ("failed comparing the re-parsed"
			" (\"%s\" should be \"%s\"\n",
			s, t->input_string);
		val = 1;
	    }
	    free(s);
	}
	krb5_free_principal (context, princ);
    }
    krb5_free_context(context);
    return val;
}