示例#1
0
int kadm5_create_magic_princs(kadm5_config_params *params,
			      krb5_context context)
{
     int retval;
     void *handle;
     
     retval = krb5_klog_init(context, "admin_server", progname, 0);
     if (retval)
	  return retval;
     if ((retval = kadm5_init(progname, NULL, NULL, params,
			      KADM5_STRUCT_VERSION,
			      KADM5_API_VERSION_2,
			      db5util_db_args,
			      &handle))) {
	  com_err(progname, retval, "while initializing the Kerberos admin interface");
	  return retval;
     }

     retval = add_admin_princs(handle, context, params->realm);

     kadm5_destroy(handle);

     krb5_klog_close(context);

     return retval;
}
示例#2
0
int main()
{
    kadm5_ret_t ret;
    char   *cp;
    int    x;
    void *server_handle;
    kadm5_server_handle_t handle;
    krb5_context context;

    ret = kadm5_init_krb5_context(&context);
    if (ret != 0) {
        com_err("test", ret, "context init");
        exit(2);
    }
    for(x = 0; x < TEST_NUM; x++) {
        ret = kadm5_init(context, "admin", "admin", KADM5_ADMIN_SERVICE, 0,
                         KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL,
                         &server_handle);
        if(ret != KADM5_OK) {
            com_err("test", ret, "init");
            exit(2);
        }
        handle = (kadm5_server_handle_t) server_handle;
        cp = strdup(strchr(handle->cache_name, ':') + 1);
        kadm5_destroy(server_handle);
        if(access(cp, F_OK) == 0) {
            puts("ticket cache not destroyed");
            exit(2);
        }
        free(cp);
    }
    krb5_free_context(context);
    exit(0);
}
示例#3
0
int main()
{
    kadm5_ret_t ret;
    krb5_keyblock  *keys[TEST_NUM];
    krb5_principal tprinc;
    krb5_keyblock  *newkey;
    krb5_context context;
    void *server_handle;

    int    x, i;

    kadm5_init_krb5_context(&context);

    krb5_parse_name(context, "testuser", &tprinc);
    ret = kadm5_init(context, "admin", "admin", KADM5_ADMIN_SERVICE, NULL,
                     KADM5_STRUCT_VERSION, KADM5_API_VERSION_3, NULL,
                     &server_handle);
    if(ret != KADM5_OK) {
        com_err("test", ret, "init");
        exit(2);
    }
    for(x = 0; x < TEST_NUM; x++) {
        kadm5_randkey_principal(server_handle, tprinc, &keys[x], NULL);
        for(i = 0; i < x; i++) {
            if (!memcmp(newkey->contents, keys[i]->contents, newkey->length))
                puts("match found");
        }
    }
    kadm5_destroy(server_handle);
    exit(0);
}
示例#4
0
int main()
{
    kadm5_ret_t ret;
    void *server_handle;
    kadm5_config_params params;
    krb5_context context;

    memset(&params, 0, sizeof(params));
    params.mask |= KADM5_CONFIG_NO_AUTH;
    ret = kadm5_init_krb5_context(&context);
    if (ret != 0) {
        com_err("init-test", ret, "while initializing krb5 context");
        exit(1);
    }
    ret = kadm5_init(context, "admin", "admin", NULL, &params,
                     KADM5_STRUCT_VERSION, KADM5_API_VERSION_3, NULL,
                     &server_handle);
    if (ret == KADM5_RPC_ERROR) {
        krb5_free_context(context);
        exit(0);
    }
    else if (ret != 0) {
        com_err("init-test", ret, "while initializing without auth");
        exit(1);
    } else {
        fprintf(stderr, "Unexpected success while initializing without auth!\n");
        (void) kadm5_destroy(server_handle);
        krb5_free_context(context);
        exit(1);
    }
}
示例#5
0
文件: srvutil.c 项目: jhutz/krb-rekey
void sess_finalize(struct rekey_session *sess) 
{
  OM_uint32 min;
  if (sess->state == REKEY_SESSION_SENDING)
    prtmsg("warning: session closed before reply sent");
  if (sess->ssl) {
    SSL_shutdown(sess->ssl);
    SSL_free(sess->ssl);
  }
  if (sess->kadm_handle)
    kadm5_destroy(sess->kadm_handle);
  if (sess->realm) {
#if defined(HAVE_KRB5_REALM)
    krb5_xfree(sess->realm);
#else
    krb5_free_default_realm(sess->kctx, sess->realm);
#endif
  }
  if (sess->princ)
    krb5_free_principal(sess->kctx, sess->princ);
  if (sess->kctx)
    krb5_free_context(sess->kctx);
  if (sess->gctx)
    (void)gss_delete_sec_context(&min, &sess->gctx, GSS_C_NO_BUFFER);
  if (sess->name)
    (void)gss_release_name(&min, &sess->name);
  if (sess->dbh)
    sqlite3_close(sess->dbh);
  free(sess->hostname);
  free(sess->plain_name);
  memset(&sess, 0, sizeof(sess));
}
示例#6
0
static void
add_users (const char *filename, unsigned n)
{
    krb5_error_code ret;
    int i;
    void *kadm_handle;
    krb5_context context;
    unsigned nwords;
    char **words;

    ret = krb5_init_context(&context);
    if (ret)
	errx (1, "krb5_init_context failed: %d", ret);
    ret = kadm5_s_init_with_password_ctx(context,
					 KADM5_ADMIN_SERVICE,
					 NULL,
					 KADM5_ADMIN_SERVICE,
					 NULL, 0, 0,
					 &kadm_handle);
    if(ret)
	krb5_err(context, 1, ret, "kadm5_init_with_password");

    nwords = read_words (filename, &words);

    for (i = 0; i < n; ++i)
	add_user (context, kadm_handle, nwords, words);
    kadm5_destroy(kadm_handle);
    krb5_free_context(context);
}
示例#7
0
文件: get.c 项目: appleorange1/bitrig
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;
}
示例#8
0
/*
 * Function: krb5_changepw
 *
 * Purpose: Initialize and call lower level routines to change a password
 *
 * Arguments:
 *
 *	princ_str	principal name to use, optional
 *	old_password 	old password
 *	new_password  	new password
 *
 * Returns:
 *                      exit status of PAM_SUCCESS for success
 *			1 principal unknown
 *			2 old password wrong
 *			3 cannot initialize admin server session
 *			4 new passwd mismatch or error trying to change pw
 *                      5 password not typed
 *                      6 misc error
 *                      7 incorrect usage
 *
 * Requires:
 *	Passwords cannot be more than 255 characters long.
 *
 * Modifies:
 *
 * Changes the principal's password.
 *
 */
static int
krb5_changepw(
	pam_handle_t *pamh,
	char *princ_str,
	char *old_password,
	char *new_password,
	int debug)
{
	kadm5_ret_t		code;
	krb5_principal 		princ = 0;
	char 			msg_ret[1024], admin_realm[1024];
	char			kprinc[2*MAXHOSTNAMELEN];
	char			*cpw_service;
	kadm5_principal_ent_rec principal_entry;
	kadm5_policy_ent_rec	policy_entry;
	void 			*server_handle;
	krb5_context		context;
	kadm5_config_params	params;

	(void) memset((char *)&params, 0, sizeof (params));
	(void) memset(&principal_entry, 0, sizeof (principal_entry));
	(void) memset(&policy_entry, 0, sizeof (policy_entry));

	if (code = krb5_init_context(&context)) {
		return (6);
	}

	if ((code = get_kmd_kuser(context, (const char *)princ_str, kprinc,
		2*MAXHOSTNAMELEN)) != 0) {
		return (code);
	}

	/* Need to get a krb5_principal struct */

	code = krb5_parse_name(context, kprinc, &princ);

	if (code != 0) {
		return (MISC_EXIT_STATUS);
	}

	if (strlen(old_password) == 0) {
		krb5_free_principal(context, princ);
		return (5);
	}

	(void) snprintf(admin_realm, sizeof (admin_realm), "%s",
		krb5_princ_realm(context, princ)->data);
	params.mask |= KADM5_CONFIG_REALM;
	params.realm = admin_realm;


	if (kadm5_get_cpw_host_srv_name(context, admin_realm, &cpw_service)) {
		syslog(LOG_ERR,
			dgettext(TEXT_DOMAIN,
				"PAM-KRB5 (password):unable to get host based "
				"service name for realm %s\n"),
			admin_realm);
		return (3);
	}

	code = kadm5_init_with_password(kprinc, old_password, cpw_service,
					&params, KADM5_STRUCT_VERSION,
					KADM5_API_VERSION_2, &server_handle);
	free(cpw_service);
	if (code != 0) {
		if (debug)
			syslog(LOG_DEBUG,
			    "PAM-KRB5 (password): changepw: "
			    "init_with_pw failed:  (%s)", error_message(code));
		krb5_free_principal(context, princ);
		return ((code == KADM5_BAD_PASSWORD) ? 2 : 3);
	}

	code = kadm5_chpass_principal_util(server_handle, princ,
					new_password,
					NULL /* don't need pw back */,
					msg_ret,
					sizeof (msg_ret));

	if (code) {
		char msgs[2][PAM_MAX_MSG_SIZE];

		(void) snprintf(msgs[0], PAM_MAX_MSG_SIZE, "%s",
			dgettext(TEXT_DOMAIN,
				"Kerberos password not changed: "));
		(void) snprintf(msgs[1], PAM_MAX_MSG_SIZE, "%s", msg_ret);

		display_msgs(pamh, PAM_ERROR_MSG, 2, msgs);
	}

	krb5_free_principal(context, princ);

	(void) kadm5_destroy(server_handle);

	if (debug)
		syslog(LOG_DEBUG,
		    "PAM-KRB5 (password): changepw: end %d", code);

	if (code == KRB5_LIBOS_CANTREADPWD)
		return (5);
	else if (code)
		return (4);
	else
		return (PAM_SUCCESS);
}
示例#9
0
int
krb5_verifypw(
	pam_handle_t *pamh,
	char 	*princ_str,
	char	*old_password,
	boolean_t disp_flag,
	int debug)
{
	kadm5_ret_t		code;
	krb5_principal 		princ = 0;
	char 			admin_realm[1024];
	char			kprinc[2*MAXHOSTNAMELEN];
	char			*cpw_service;
	kadm5_principal_ent_rec principal_entry;
	kadm5_policy_ent_rec	 policy_entry;
	void 			*server_handle;
	krb5_context		context;
	kadm5_config_params	params;
#define	MSG_ROWS		5
	char			msgs[MSG_ROWS][PAM_MAX_MSG_SIZE];

	(void) memset((char *)&params, 0, sizeof (params));
	(void) memset(&principal_entry, 0, sizeof (principal_entry));
	(void) memset(&policy_entry, 0, sizeof (policy_entry));

	if (code = krb5_init_context(&context)) {
		return (6);
	}

	if ((code = get_kmd_kuser(context, (const char *)princ_str, kprinc,
		2*MAXHOSTNAMELEN)) != 0) {
		return (code);
	}

	/* Need to get a krb5_principal struct */

	code = krb5_parse_name(context, kprinc, &princ);

	if (code != 0) {
		return (MISC_EXIT_STATUS);
	}

	if (strlen(old_password) == 0) {
		krb5_free_principal(context, princ);
		return (5);
	}

	(void) strlcpy(admin_realm,
		    krb5_princ_realm(context, princ)->data,
		    sizeof (admin_realm));

	params.mask |= KADM5_CONFIG_REALM;
	params.realm = admin_realm;


	if (kadm5_get_cpw_host_srv_name(context, admin_realm, &cpw_service)) {
		syslog(LOG_ERR,
		    dgettext(TEXT_DOMAIN,
			"PAM-KRB5 (password): unable to get host based "
			"service name for realm %s\n"),
			admin_realm);
		return (3);
	}

	code = kadm5_init_with_password(kprinc, old_password, cpw_service,
					&params, KADM5_STRUCT_VERSION,
					KADM5_API_VERSION_2, &server_handle);
	if (code != 0) {
		if (debug)
			syslog(LOG_DEBUG,
			    "PAM-KRB5: krb5_verifypw: init_with_pw"
			    " failed: (%s)", error_message(code));
		krb5_free_principal(context, princ);
		return ((code == KADM5_BAD_PASSWORD) ? 2 : 3);
	}

	if (disp_flag &&
	    _kadm5_get_kpasswd_protocol(server_handle) == KRB5_CHGPWD_RPCSEC) {
		/*
		 * Note: copy of this exists in login
		 * (kverify.c/get_verified_in_tkt).
		 */

		code = kadm5_get_principal(server_handle, princ,
						&principal_entry,
						KADM5_PRINCIPAL_NORMAL_MASK);
		if (code != 0) {
			krb5_free_principal(context, princ);
			(void) kadm5_destroy(server_handle);
			return ((code == KADM5_UNK_PRINC) ? 1 :
				MISC_EXIT_STATUS);
		}

		if ((principal_entry.aux_attributes & KADM5_POLICY) != 0) {
			code = kadm5_get_policy(server_handle,
						principal_entry.policy,
						&policy_entry);
			if (code != 0) {
				/*
				 * doesn't matter which error comes back,
				 * there's no nice recovery or need to
				 * differentiate to the user
				 */
				(void) kadm5_free_principal_ent(server_handle,
							&principal_entry);
				krb5_free_principal(context, princ);
				(void) kadm5_destroy(server_handle);
				return (MISC_EXIT_STATUS);
			}

			(void) snprintf(msgs[0], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN, "POLICY_EXPLANATION:"));
			(void) snprintf(msgs[1], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN,
					"Principal string is %s"), princ_str);
			(void) snprintf(msgs[2], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN, "Policy Name is  %s"),
				principal_entry.policy);
			(void) snprintf(msgs[3], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN,
					"Minimum password length is %d"),
					policy_entry.pw_min_length);
			(void) snprintf(msgs[4], PAM_MAX_MSG_SIZE,
				dgettext(TEXT_DOMAIN,
					"Minimum password classes is %d"),
					policy_entry.pw_min_classes);
			display_msgs(pamh, PAM_TEXT_INFO, MSG_ROWS, msgs);

			if (code = kadm5_free_principal_ent(server_handle,
							    &principal_entry)) {
				(void) kadm5_free_policy_ent(server_handle,
							&policy_entry);
				krb5_free_principal(context, princ);
				(void) kadm5_destroy(server_handle);
				return (MISC_EXIT_STATUS);
			}
			if (code = kadm5_free_policy_ent(server_handle,
							&policy_entry)) {
				krb5_free_principal(context, princ);

				(void) kadm5_destroy(server_handle);
				return (MISC_EXIT_STATUS);
			}
		} else {
			/*
			 * kpasswd *COULD* output something here to encourage
			 * the choice of good passwords, in the absence of
			 * an enforced policy.
			 */
			if (code = kadm5_free_principal_ent(server_handle,
							    &principal_entry)) {
				krb5_free_principal(context, princ);
				(void) kadm5_destroy(server_handle);
				return (MISC_EXIT_STATUS);
			}
		}
	}
	krb5_free_principal(context, princ);

	(void) kadm5_destroy(server_handle);

	return (0);
}
示例#10
0
文件: kerberos.c 项目: jdreed/moira
/* Modify Kerberos principal */
long modify_kerberos(char *username, int activate)
{ 
  void *kadm_server_handle = NULL;
  krb5_context context = NULL;
  kadm5_ret_t status;
  krb5_principal princ;
  kadm5_principal_ent_rec dprinc;
  kadm5_policy_ent_rec defpol;
  kadm5_config_params realm_params;
  char admin_princ[256];
  long mask = 0;
#ifdef KERBEROS_TEST_REALM
  char ubuf[256];

  sprintf(admin_princ, "moira/%s@%s", hostname, KERBEROS_TEST_REALM);
  sprintf(ubuf, "%s@%s", username, KERBEROS_TEST_REALM);
  username = ubuf;
  realm_params.realm = KERBEROS_TEST_REALM;
  realm_params.mask = KADM5_CONFIG_REALM;
#else
  strcpy(admin_princ, MOIRA_SVR_PRINCIPAL);
  realm_params.mask = 0;
#endif

  status = krb5_init_context(&context);
  if (status)
    return status;

  memset(&princ, 0, sizeof(princ));
  memset(&dprinc, 0, sizeof(dprinc));

  status = krb5_parse_name(context, username, &princ);
  if (status)
    return status;

  status = kadm5_init_with_skey(admin_princ, NULL, KADM5_ADMIN_SERVICE,
                                &realm_params, KADM5_STRUCT_VERSION,
                                KADM5_API_VERSION_2, NULL,
                                &kadm_server_handle);
  if (status)
    goto cleanup;

  status = kadm5_get_principal(kadm_server_handle, princ, &dprinc, KADM5_PRINCIPAL_NORMAL_MASK);
  if (status)
    goto cleanup;

  mask |= KADM5_ATTRIBUTES;
  if (activate == 2)
    {
      /* Force password change */
      dprinc.attributes |= KRB5_KDB_REQUIRES_PWCHANGE;
      dprinc.attributes &= ~KRB5_KDB_DISALLOW_ALL_TIX;
    }
  else if (activate == 1)
    {
      /* Enable principal */
      dprinc.attributes &= ~KRB5_KDB_DISALLOW_ALL_TIX;
      dprinc.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
    }
  else
    {
      /* Disable principal */
      dprinc.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
      dprinc.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE;
    }

  status = kadm5_modify_principal(kadm_server_handle, &dprinc, mask);

 cleanup:
  krb5_free_principal(context, princ);
  kadm5_free_principal_ent(kadm_server_handle, &dprinc);
  if (kadm_server_handle)
    kadm5_destroy(kadm_server_handle);

  return status;
}
示例#11
0
static void
change (krb5_auth_context auth_context,
        krb5_principal admin_principal,
        uint16_t version,
        int s,
        struct sockaddr *sa,
        int sa_size,
        krb5_data *in_data)
{
    krb5_error_code ret;
    char *client = NULL, *admin = NULL;
    const char *pwd_reason;
    kadm5_config_params conf;
    void *kadm5_handle = NULL;
    krb5_principal principal = NULL;
    krb5_data *pwd_data = NULL;
    char *tmp;
    ChangePasswdDataMS chpw;

    memset (&conf, 0, sizeof(conf));
    memset(&chpw, 0, sizeof(chpw));

    if (version == KRB5_KPASSWD_VERS_CHANGEPW) {
        ret = krb5_copy_data(context, in_data, &pwd_data);
        if (ret) {
            krb5_warn (context, ret, "krb5_copy_data");
            reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED,
                        "out out memory copying password");
            return;
        }
        principal = admin_principal;
    } else if (version == KRB5_KPASSWD_VERS_SETPW) {
        size_t len;

        ret = decode_ChangePasswdDataMS(in_data->data, in_data->length,
                                        &chpw, &len);
        if (ret) {
            krb5_warn (context, ret, "decode_ChangePasswdDataMS");
            reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED,
                        "malformed ChangePasswdData");
            return;
        }


        ret = krb5_copy_data(context, &chpw.newpasswd, &pwd_data);
        if (ret) {
            krb5_warn (context, ret, "krb5_copy_data");
            reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED,
                        "out out memory copying password");
            goto out;
        }

        if (chpw.targname == NULL && chpw.targrealm != NULL) {
            krb5_warn (context, ret, "kadm5_init_with_password_ctx");
            reply_priv (auth_context, s, sa, sa_size,
                        KRB5_KPASSWD_MALFORMED,
                        "targrealm but not targname");
            goto out;
        }

        if (chpw.targname) {
            krb5_principal_data princ;

            princ.name = *chpw.targname;
            princ.realm = *chpw.targrealm;
            if (princ.realm == NULL) {
                ret = krb5_get_default_realm(context, &princ.realm);

                if (ret) {
                    krb5_warnx (context,
                                "kadm5_init_with_password_ctx: "
                                "failed to allocate realm");
                    reply_priv (auth_context, s, sa, sa_size,
                                KRB5_KPASSWD_SOFTERROR,
                                "failed to allocate realm");
                    goto out;
                }
            }
            ret = krb5_copy_principal(context, &princ, &principal);
            if (*chpw.targrealm == NULL)
                free(princ.realm);
            if (ret) {
                krb5_warn(context, ret, "krb5_copy_principal");
                reply_priv(auth_context, s, sa, sa_size,
                           KRB5_KPASSWD_HARDERROR,
                           "failed to allocate principal");
                goto out;
            }
        } else
            principal = admin_principal;
    } else {
        krb5_warnx (context, "kadm5_init_with_password_ctx: unknown proto");
        reply_priv (auth_context, s, sa, sa_size,
                    KRB5_KPASSWD_HARDERROR,
                    "Unknown protocol used");
        return;
    }

    ret = krb5_unparse_name (context, admin_principal, &admin);
    if (ret) {
        krb5_warn (context, ret, "unparse_name failed");
        reply_priv (auth_context, s, sa, sa_size,
                    KRB5_KPASSWD_HARDERROR, "out of memory error");
        goto out;
    }

    conf.realm = principal->realm;
    conf.mask |= KADM5_CONFIG_REALM;

    ret = kadm5_init_with_password_ctx(context,
                                       admin,
                                       NULL,
                                       KADM5_ADMIN_SERVICE,
                                       &conf, 0, 0,
                                       &kadm5_handle);
    if (ret) {
        krb5_warn (context, ret, "kadm5_init_with_password_ctx");
        reply_priv (auth_context, s, sa, sa_size, 2,
                    "Internal error");
        goto out;
    }

    ret = krb5_unparse_name(context, principal, &client);
    if (ret) {
        krb5_warn (context, ret, "unparse_name failed");
        reply_priv (auth_context, s, sa, sa_size,
                    KRB5_KPASSWD_HARDERROR, "out of memory error");
        goto out;
    }

    /*
     * Check password quality if not changing as administrator
     */

    if (krb5_principal_compare(context, admin_principal, principal) == TRUE) {

        pwd_reason = kadm5_check_password_quality (context, principal,
                     pwd_data);
        if (pwd_reason != NULL ) {
            krb5_warnx (context,
                        "%s didn't pass password quality check with error: %s",
                        client, pwd_reason);
            reply_priv (auth_context, s, sa, sa_size,
                        KRB5_KPASSWD_SOFTERROR, pwd_reason);
            goto out;
        }
        krb5_warnx (context, "Changing password for %s", client);
    } else {
        ret = _kadm5_acl_check_permission(kadm5_handle, KADM5_PRIV_CPW,
                                          principal);
        if (ret) {
            krb5_warn (context, ret,
                       "Check ACL failed for %s for changing %s password",
                       admin, client);
            reply_priv (auth_context, s, sa, sa_size,
                        KRB5_KPASSWD_HARDERROR, "permission denied");
            goto out;
        }
        krb5_warnx (context, "%s is changing password for %s", admin, client);
    }

    ret = krb5_data_realloc(pwd_data, pwd_data->length + 1);
    if (ret) {
        krb5_warn (context, ret, "malloc: out of memory");
        reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_HARDERROR,
                    "Internal error");
        goto out;
    }
    tmp = pwd_data->data;
    tmp[pwd_data->length - 1] = '\0';

    ret = kadm5_s_chpass_principal_cond (kadm5_handle, principal, tmp);
    krb5_free_data (context, pwd_data);
    pwd_data = NULL;
    if (ret) {
        const char *str = krb5_get_error_message(context, ret);
        krb5_warnx(context, "kadm5_s_chpass_principal_cond: %s", str);
        reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR,
                    str ? str : "Internal error");
        krb5_free_error_message(context, str);
        goto out;
    }
    reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SUCCESS,
                "Password changed");
out:
    free_ChangePasswdDataMS(&chpw);
    if (principal != admin_principal)
        krb5_free_principal(context, principal);
    if (admin)
        free(admin);
    if (client)
        free(client);
    if (pwd_data)
        krb5_free_data(context, pwd_data);
    if (kadm5_handle)
        kadm5_destroy (kadm5_handle);
}
示例#12
0
bool
kerberos_expire_password(const char *principal, time_t expires)
{
    char *path, *user;
    const char *realm;
    krb5_context ctx;
    krb5_principal admin = NULL;
    krb5_principal princ = NULL;
    krb5_error_code code;
    kadm5_config_params params;
    kadm5_principal_ent_rec ent;
    void *handle;
    bool okay = false;

    /* Set up for making our call. */
    path = test_file_path("config/admin-keytab");
    if (path == NULL)
        return false;
    code = krb5_init_context(&ctx);
    if (code != 0)
        bail_krb5(ctx, code, "error initializing Kerberos");
    admin = kerberos_keytab_principal(ctx, path);
    realm = krb5_principal_get_realm(ctx, admin);
    code = krb5_set_default_realm(ctx, realm);
    if (code != 0)
        bail_krb5(ctx, code, "cannot set default realm");
    code = krb5_unparse_name(ctx, admin, &user);
    if (code != 0)
        bail_krb5(ctx, code, "cannot unparse admin principal");
    code = krb5_parse_name(ctx, principal, &princ);
    if (code != 0)
        bail_krb5(ctx, code, "cannot parse principal %s", principal);

    /*
     * If the actual kadmin calls fail, we may be built with MIT Kerberos
     * against a Heimdal server or vice versa.  Return false to skip the
     * tests.
     */
    memset(&params, 0, sizeof(params));
    params.realm = (char *) realm;
    params.mask = KADM5_CONFIG_REALM;
    code = kadm5_init_with_skey_ctx(ctx, user, path, KADM5_ADMIN_SERVICE,
                                    &params, KADM5_STRUCT_VERSION,
                                    KADM5_API_VERSION, &handle);
    if (code != 0) {
        diag_krb5(ctx, code, "error initializing kadmin");
        goto done;
    }
    memset(&ent, 0, sizeof(ent));
    ent.principal = princ;
    ent.pw_expiration = expires;
    code = kadm5_modify_principal(handle, &ent, KADM5_PW_EXPIRATION);
    if (code == 0)
        okay = true;
    else
        diag_krb5(ctx, code, "error setting password expiration");

done:
    kadm5_destroy(handle);
    krb5_free_unparsed_name(ctx, user);
    krb5_free_principal(ctx, admin);
    krb5_free_principal(ctx, princ);
    krb5_free_context(ctx);
    test_file_path_free(path);
    return okay;
}
示例#13
0
int
main(int argc, char *argv[])
{
    OM_uint32 minor_status;
    gss_buffer_desc in_buf;
    gss_OID nt_krb5_name_oid = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME;
    auth_gssapi_name names[4];
    kadm5_config_params params;
    verto_ctx *vctx;
    const char *pid_file = NULL;
    char **db_args = NULL, **tmpargs;
    int ret, i, db_args_size = 0, strong_random = 1, proponly = 0;

    setlocale(LC_ALL, "");
    setvbuf(stderr, NULL, _IONBF, 0);

    names[0].name = names[1].name = names[2].name = names[3].name = NULL;
    names[0].type = names[1].type = names[2].type = names[3].type =
        nt_krb5_name_oid;

    progname = (strrchr(argv[0], '/') != NULL) ? strrchr(argv[0], '/') + 1 :
        argv[0];

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

    argc--, argv++;
    while (argc) {
        if (strcmp(*argv, "-x") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            db_args_size++;
            tmpargs = realloc(db_args, sizeof(char *) * (db_args_size + 1));
            if (tmpargs == NULL) {
                fprintf(stderr, _("%s: cannot initialize. Not enough "
                                  "memory\n"), progname);
                exit(1);
            }
            db_args = tmpargs;
            db_args[db_args_size - 1] = *argv;
            db_args[db_args_size] = NULL;
        } else if (strcmp(*argv, "-r") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            params.realm = *argv;
            params.mask |= KADM5_CONFIG_REALM;
            argc--, argv++;
            continue;
        } else if (strcmp(*argv, "-m") == 0) {
            params.mkey_from_kbd = 1;
            params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
        } else if (strcmp(*argv, "-nofork") == 0) {
            nofork = 1;
#ifdef USE_PASSWORD_SERVER
        } else if (strcmp(*argv, "-passwordserver") == 0) {
            kadm5_set_use_password_server();
#endif
#ifndef DISABLE_IPROP
        } else if (strcmp(*argv, "-proponly") == 0) {
            proponly = 1;
#endif
        } else if (strcmp(*argv, "-port") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            params.kadmind_port = atoi(*argv);
            params.mask |= KADM5_CONFIG_KADMIND_PORT;
        } else if (strcmp(*argv, "-P") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            pid_file = *argv;
        } else if (strcmp(*argv, "-W") == 0) {
            strong_random = 0;
        } else if (strcmp(*argv, "-p") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            kdb5_util = *argv;
        } else if (strcmp(*argv, "-F") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            dump_file = *argv;
        } else if (strcmp(*argv, "-K") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            kprop = *argv;
        } else if (strcmp(*argv, "-k") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            kprop_port = *argv;
        } else {
            break;
        }
        argc--, argv++;
    }

    if (argc != 0)
        usage();

    ret = kadm5_init_krb5_context(&context);
    if (ret) {
        fprintf(stderr, _("%s: %s while initializing context, aborting\n"),
                progname, error_message(ret));
        exit(1);
    }

    krb5_klog_init(context, "admin_server", progname, 1);

    ret = kadm5_init(context, "kadmind", NULL, NULL, &params,
                     KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, db_args,
                     &global_server_handle);
    if (ret)
        fail_to_start(ret, _("initializing"));

    ret = kadm5_get_config_params(context, 1, &params, &params);
    if (ret)
        fail_to_start(ret, _("getting config parameters"));
    if (!(params.mask & KADM5_CONFIG_REALM))
        fail_to_start(0, _("Missing required realm configuration"));
    if (!(params.mask & KADM5_CONFIG_ACL_FILE))
        fail_to_start(0, _("Missing required ACL file configuration"));

    ret = setup_loop(proponly, &vctx);
    if (ret)
        fail_to_start(ret, _("initializing network"));

    names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
    names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
    if (names[0].name == NULL || names[1].name == NULL)
        fail_to_start(0, _("Cannot build GSSAPI auth names"));

    ret = setup_kdb_keytab();
    if (ret)
        fail_to_start(0, _("Cannot set up KDB keytab"));

    if (svcauth_gssapi_set_names(names, 2) == FALSE)
        fail_to_start(0, _("Cannot set GSSAPI authentication names"));

    /* if set_names succeeded, this will too */
    in_buf.value = names[1].name;
    in_buf.length = strlen(names[1].name) + 1;
    (void)gss_import_name(&minor_status, &in_buf, nt_krb5_name_oid,
                          &gss_changepw_name);

    svcauth_gssapi_set_log_badauth2_func(log_badauth, NULL);
    svcauth_gssapi_set_log_badverf_func(log_badverf, NULL);
    svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL);

    svcauth_gss_set_log_badauth2_func(log_badauth, NULL);
    svcauth_gss_set_log_badverf_func(log_badverf, NULL);
    svcauth_gss_set_log_miscerr_func(log_miscerr, NULL);

    if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE)
        fail_to_start(0, _("Cannot initialize GSSAPI service name"));

    ret = acl_init(context, params.acl_file);
    if (ret)
        fail_to_start(ret, _("initializing ACL file"));

    if (!nofork && daemon(0, 0) != 0)
        fail_to_start(errno, _("spawning daemon process"));
    if (pid_file != NULL) {
        ret = write_pid_file(pid_file);
        if (ret)
            fail_to_start(ret, _("creating PID file"));
    }

    krb5_klog_syslog(LOG_INFO, _("Seeding random number generator"));
    ret = krb5_c_random_os_entropy(context, strong_random, NULL);
    if (ret)
        fail_to_start(ret, _("getting random seed"));

    if (params.iprop_enabled == TRUE) {
        ulog_set_role(context, IPROP_MASTER);

        ret = ulog_map(context, params.iprop_logfile, params.iprop_ulogsize);
        if (ret)
            fail_to_start(ret, _("mapping update log"));

        if (nofork) {
            fprintf(stderr,
                    _("%s: create IPROP svc (PROG=%d, VERS=%d)\n"),
                    progname, KRB5_IPROP_PROG, KRB5_IPROP_VERS);
        }
    }

    if (kprop_port == NULL)
        kprop_port = getenv("KPROP_PORT");

    krb5_klog_syslog(LOG_INFO, _("starting"));
    if (nofork)
        fprintf(stderr, _("%s: starting...\n"), progname);

    verto_run(vctx);
    krb5_klog_syslog(LOG_INFO, _("finished, exiting"));

    /* Clean up memory, etc */
    svcauth_gssapi_unset_names();
    kadm5_destroy(global_server_handle);
    loop_free(vctx);
    acl_finish(context);
    (void)gss_release_name(&minor_status, &gss_changepw_name);
    (void)gss_release_name(&minor_status, &gss_oldchangepw_name);
    for (i = 0; i < 4; i++)
        free(names[i].name);

    krb5_klog_close(context);
    krb5_free_context(context);
    exit(2);
}
示例#14
0
static krb5_error_code
change_entry (krb5_keytab keytab,
	      krb5_principal principal, krb5_kvno kvno,
	      const char *realm, const char *admin_server, int server_port)
{
    krb5_error_code ret;
    kadm5_config_params conf;
    void *kadm_handle;
    char *client_name;
    krb5_keyblock *keys;
    int num_keys;
    int i;

    ret = krb5_unparse_name (context, principal, &client_name);
    if (ret) {
	krb5_warn (context, ret, "krb5_unparse_name");
	return ret;
    }

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

    if(realm == NULL)
	realm = krb5_principal_get_realm(context, principal);
    conf.realm = strdup(realm);
    if (conf.realm == NULL) {
	free (client_name);
	krb5_set_error_message(context, ENOMEM, "malloc failed");
	return ENOMEM;
    }
    conf.mask |= KADM5_CONFIG_REALM;

    if (admin_server) {
	conf.admin_server = strdup(admin_server);
	if (conf.admin_server == NULL) {
	    free(client_name);
	    free(conf.realm);
	    krb5_set_error_message(context, ENOMEM, "malloc failed");
	    return ENOMEM;
	}	
	conf.mask |= KADM5_CONFIG_ADMIN_SERVER;
    }

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

    ret = kadm5_init_with_skey_ctx (context,
				    client_name,
				    keytab_string,
				    KADM5_ADMIN_SERVICE,
				    &conf, 0, 0,
				    &kadm_handle);
    free(conf.admin_server);
    free(conf.realm);
    if (ret) {
	krb5_warn (context, ret,
		   "kadm5_c_init_with_skey_ctx: %s:", client_name);
	free (client_name);
	return ret;
    }
    ret = kadm5_randkey_principal (kadm_handle, principal, &keys, &num_keys);
    kadm5_destroy (kadm_handle);
    if (ret) {
	krb5_warn(context, ret, "kadm5_randkey_principal: %s:", client_name);
	free (client_name);
	return ret;
    }
    free (client_name);
    for (i = 0; i < num_keys; ++i) {
	krb5_keytab_entry new_entry;

	new_entry.principal = principal;
	new_entry.timestamp = time (NULL);
	new_entry.vno = kvno + 1;
	new_entry.keyblock  = keys[i];

	ret = krb5_kt_add_entry (context, keytab, &new_entry);
	if (ret)
	    krb5_warn (context, ret, "krb5_kt_add_entry");
	krb5_free_keyblock_contents (context, &keys[i]);
    }
    return ret;
}
示例#15
0
static int
fetch_princ_entry(
	krb5_module_data_t *kmd,
	char *princ_str,
	kadm5_principal_ent_rec *prent,	/* out */
	int debug)

{
	kadm5_ret_t		code;
	krb5_principal 		princ = 0;
	char 			admin_realm[1024];
	char			kprinc[2*MAXHOSTNAMELEN];
	char			*cpw_service, *password;
	void 			*server_handle;
	krb5_context		context;
	kadm5_config_params	params;

	password = kmd->password;
	context = kmd->kcontext;

	if ((code = get_kmd_kuser(context, (const char *)princ_str,
	    kprinc, 2*MAXHOSTNAMELEN)) != 0) {
		return (code);
	}

	code = krb5_parse_name(context, kprinc, &princ);
	if (code != 0) {
		return (PAM_SYSTEM_ERR);
	}

	if (strlen(password) == 0) {
		krb5_free_principal(context, princ);
		if (debug)
			__pam_log(LOG_AUTH | LOG_DEBUG,
			    "PAM-KRB5 (acct): fetch_princ_entry: pwlen=0");
		return (PAM_AUTH_ERR);
	}

	(void) strlcpy(admin_realm,
		    krb5_princ_realm(context, princ)->data,
		    sizeof (admin_realm));

	(void) memset((char *)&params, 0, sizeof (params));
	params.mask |= KADM5_CONFIG_REALM;
	params.realm = admin_realm;

	if (kadm5_get_cpw_host_srv_name(context, admin_realm, &cpw_service)) {
		__pam_log(LOG_AUTH | LOG_ERR,
			"PAM-KRB5 (acct):  unable to get host based "
			"service name for realm '%s'",
			admin_realm);
		krb5_free_principal(context, princ);
		return (PAM_SYSTEM_ERR);
	}

	code = kadm5_init_with_password(kprinc, password, cpw_service,
					&params, KADM5_STRUCT_VERSION,
					KADM5_API_VERSION_2, NULL,
					&server_handle);
	if (code != 0) {
		if (debug)
			__pam_log(LOG_AUTH | LOG_DEBUG,
			    "PAM-KRB5 (acct): fetch_princ_entry: "
			    "init_with_pw failed: code = %d", code);
		krb5_free_principal(context, princ);
		return ((code == KADM5_BAD_PASSWORD) ?
			PAM_AUTH_ERR : PAM_SYSTEM_ERR);
	}

	if (_kadm5_get_kpasswd_protocol(server_handle) != KRB5_CHGPWD_RPCSEC) {
		if (debug)
			__pam_log(LOG_AUTH | LOG_DEBUG,
			    "PAM-KRB5 (acct): fetch_princ_entry: "
			    "non-RPCSEC_GSS chpw server, can't get "
			    "princ entry");
		(void) kadm5_destroy(server_handle);
		krb5_free_principal(context, princ);
		return (PAM_SYSTEM_ERR);
	}

	code = kadm5_get_principal(server_handle, princ, prent,
				KADM5_PRINCIPAL_NORMAL_MASK);

	if (code != 0) {
		(void) kadm5_destroy(server_handle);
		krb5_free_principal(context, princ);
		return ((code == KADM5_UNK_PRINC) ?
			PAM_USER_UNKNOWN : PAM_SYSTEM_ERR);
	}

	(void) kadm5_destroy(server_handle);
	krb5_free_principal(context, princ);

	return (PAM_SUCCESS);
}
示例#16
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;
}
示例#17
0
文件: setkey-test.c 项目: PADL/krb5
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_keytab kt;
    krb5_keytab_entry ktent;
    krb5_encrypt_block eblock;
    krb5_creds my_creds;
    krb5_get_init_creds_opt *opt;
    kadm5_principal_ent_rec princ_ent;
    krb5_principal princ, server;
    char pw[16];
    char *whoami, *principal, *authprinc, *authpwd;
    krb5_data pwdata;
    void *handle;
    int ret, test, encnum;
    unsigned int i;

    whoami = argv[0];

    if (argc < 2 || argc > 4) {
        fprintf(stderr, "Usage: %s principal [authuser] [authpwd]\n", whoami);
        exit(1);
    }
    principal = argv[1];
    authprinc = (argc > 2) ? argv[2] : argv[0];
    authpwd = (argc > 3) ? argv[3] : NULL;

    /*
     * Setup.  Initialize data structures, open keytab, open connection
     * to kadm5 server.
     */

    memset(&context, 0, sizeof(context));
    kadm5_init_krb5_context(&context);

    ret = krb5_parse_name(context, principal, &princ);
    if (ret) {
        com_err(whoami, ret, "while parsing principal name %s", principal);
        exit(1);
    }

    if((ret = krb5_build_principal_ext(context, &server,
                                       krb5_princ_realm(kcontext, princ)->length,
                                       krb5_princ_realm(kcontext, princ)->data,
                                       tgtname.length, tgtname.data,
                                       krb5_princ_realm(kcontext, princ)->length,
                                       krb5_princ_realm(kcontext, princ)->data,
                                       0))) {
        com_err(whoami, ret, "while building server name");
        exit(1);
    }

    ret = krb5_kt_default(context, &kt);
    if (ret) {
        com_err(whoami, ret, "while opening keytab");
        exit(1);
    }

    ret = kadm5_init(context, authprinc, authpwd, KADM5_ADMIN_SERVICE, NULL,
                     KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL,
                     &handle);
    if (ret) {
        com_err(whoami, ret, "while initializing connection");
        exit(1);
    }

    /* these pw's don't need to be secure, just different every time */
    SRAND((RAND_TYPE)time((void *) NULL));
    pwdata.data = pw;
    pwdata.length = sizeof(pw);

    /*
     * For each test:
     *
     * For each enctype in the test, construct a random password/key.
     * Assign all keys to principal with kadm5_setkey_principal.  Add
     * each key to the keytab, and acquire an initial ticket with the
     * keytab (XXX can I specify the kvno explicitly?).  If
     * krb5_get_init_creds_keytab succeeds, then the keys were set
     * successfully.
     */
    for (test = 0; tests[test] != NULL; test++) {
        krb5_keyblock *testp = tests[test];
        kadm5_key_data *extracted;
        int n_extracted, match;
        printf("+ Test %d:\n", test);

        for (encnum = 0; testp[encnum].magic != -1; encnum++) {
            for (i = 0; i < sizeof(pw); i++)
                pw[i] = (RAND() % 26) + '0'; /* XXX */

            krb5_use_enctype(context, &eblock, testp[encnum].enctype);
            ret = krb5_string_to_key(context, &eblock, &testp[encnum],
                                     &pwdata, NULL);
            if (ret) {
                com_err(whoami, ret, "while converting string to key");
                exit(1);
            }
        }

        /* now, encnum == # of keyblocks in testp */
        ret = kadm5_setkey_principal(handle, princ, testp, encnum);
        if (ret) {
            com_err(whoami, ret, "while setting keys");
            exit(1);
        }

        ret = kadm5_get_principal(handle, princ, &princ_ent, KADM5_KVNO);
        if (ret) {
            com_err(whoami, ret, "while retrieving principal");
            exit(1);
        }

        ret = kadm5_get_principal_keys(handle, princ, 0, &extracted,
                                       &n_extracted);
        if (ret) {
            com_err(whoami, ret, "while extracting keys");
            exit(1);
        }

        for (encnum = 0; testp[encnum].magic != -1; encnum++) {
            printf("+   enctype %d\n", testp[encnum].enctype);

            for (match = 0; match < n_extracted; match++) {
                if (extracted[match].key.enctype == testp[encnum].enctype)
                    break;
            }
            if (match >= n_extracted) {
                com_err(whoami, KRB5_WRONG_ETYPE, "while matching enctypes");
                exit(1);
            }
            if (extracted[match].key.length != testp[encnum].length ||
                memcmp(extracted[match].key.contents, testp[encnum].contents,
                       testp[encnum].length) != 0) {
                com_err(whoami, KRB5_KDB_NO_MATCHING_KEY, "verifying keys");
                exit(1);
            }

            memset(&ktent, 0, sizeof(ktent));
            ktent.principal = princ;
            ktent.key = testp[encnum];
            ktent.vno = princ_ent.kvno;

            ret = krb5_kt_add_entry(context, kt, &ktent);
            if (ret) {
                com_err(whoami, ret, "while adding keytab entry");
                exit(1);
            }

            memset(&my_creds, 0, sizeof(my_creds));
            my_creds.client = princ;
            my_creds.server = server;

            ktypes[0] = testp[encnum].enctype;
            ret = krb5_get_init_creds_opt_alloc(context, &opt);
            if (ret) {
                com_err(whoami, ret, "while allocating gic opts");
                exit(1);
            }
            krb5_get_init_creds_opt_set_etype_list(opt, ktypes, 1);
            ret = krb5_get_init_creds_keytab(context, &my_creds, princ,
                                             kt, 0, NULL /* in_tkt_service */,
                                             opt);
            krb5_get_init_creds_opt_free(context, opt);
            if (ret) {
                com_err(whoami, ret, "while acquiring initial ticket");
                exit(1);
            }
            krb5_free_cred_contents(context, &my_creds);

            /* since I can't specify enctype explicitly ... */
            ret = krb5_kt_remove_entry(context, kt, &ktent);
            if (ret) {
                com_err(whoami, ret, "while removing keytab entry");
                exit(1);
            }
        }

        (void)kadm5_free_kadm5_key_data(context, n_extracted, extracted);
    }

    ret = krb5_kt_close(context, kt);
    if (ret) {
        com_err(whoami, ret, "while closing keytab");
        exit(1);
    }

    ret = kadm5_destroy(handle);
    if (ret) {
        com_err(whoami, ret, "while closing kadmin connection");
        exit(1);
    }

    krb5_free_principal(context, princ);
    krb5_free_principal(context, server);
    krb5_free_context(context);
    return 0;
}