Beispiel #1
0
static krb5_error_code
v5_convert(krb5_context context, krb5_ccache id,
	   krb5_creds *cred, uid_t uid,
	   const char *cell,
	   struct kafs_token *kt)
{
    krb5_error_code ret;
    char *c, *val;

    c = strdup(cell);
    if (c == NULL)
	return ENOMEM;
    _kafs_foldup(c, c);
    krb5_appdefault_string (context, "libkafs",
			    c,
			    "afs-use-524", "2b", &val);
    free(c);

    if (strcasecmp(val, "local") == 0 ||
	strcasecmp(val, "2b") == 0)
	ret = v5_to_kt(cred, uid, kt, 1);
    else
	ret = v5_to_kt(cred, uid, kt, 0);

    free(val);
    return ret;
}
Beispiel #2
0
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_appdefault_time(krb5_context context, const char *appname,
		     krb5_const_realm realm, const char *option,
		     time_t def_val, time_t *ret_val)
{
    krb5_deltat t;
    char *val;

    krb5_appdefault_string(context, appname, realm, option, NULL, &val);
    if (val == NULL) {
	*ret_val = def_val;
	return;
    }
    if (krb5_string_to_deltat(val, &t))
	*ret_val = def_val;
    else
	*ret_val = t;
    free(val);
}
Beispiel #3
0
/*
 * Load a string option from Kerberos appdefaults.  Takes the Kerberos
 * context, the option, and the result location.
 *
 * This requires an annoying workaround because one cannot specify a default
 * value of NULL with MIT Kerberos, since MIT Kerberos unconditionally calls
 * strdup on the default value.  There's also no way to determine if memory
 * allocation failed while parsing or while setting the default value, so we
 * don't return an error code.
 */
void
sync_config_string(krb5_context ctx, const char *opt, char **result)
{
    realm_type realm;
    char *value = NULL;

    /* Obtain the string from [appdefaults]. */
    realm = default_realm(ctx);
    krb5_appdefault_string(ctx, "krb5-sync", realm, opt, "", &value);
    free_default_realm(ctx, realm);

    /* If we got something back, store it in result. */
    if (value != NULL) {
        if (value[0] != '\0') {
            free(*result);
            *result = strdup(value);
        }
        krb5_free_string(ctx, value);
    }
}
Beispiel #4
0
static krb5_error_code
v5_convert(krb5_context context, krb5_ccache id,
	   krb5_creds *cred, uid_t uid,
	   const char *cell,
	   struct kafs_token *kt)
{
    krb5_error_code ret;
    char *c, *val;

    c = strdup(cell);
    if (c == NULL)
	return ENOMEM;
    _kafs_foldup(c, c);
    krb5_appdefault_string (context, "libkafs",
			    c,
			    "afs-use-524", "2b", &val);
    free(c);

    if (strcasecmp(val, "local") == 0 ||
	strcasecmp(val, "2b") == 0)
	ret = v5_to_kt(cred, uid, kt, 1);
    else if(strcasecmp(val, "yes") == 0 ||
	    strcasecmp(val, "true") == 0 ||
	    atoi(val)) {
	struct credentials cred4;
	
	if (id == NULL)
	    ret = krb524_convert_creds_kdc(context, cred, &cred4);
	else
	    ret = krb524_convert_creds_kdc_ccache(context, id, cred, &cred4);
	if (ret)
	    goto out;

	ret = _kafs_v4_to_kt(&cred4, uid, kt);
    } else
	ret = v5_to_kt(cred, uid, kt, 0);

 out:
    free(val);
    return ret;
}
Beispiel #5
0
/*
 * Load a list option from Kerberos appdefaults.  Takes the Kerberos context,
 * the option, and the result location.  The option is read as a string and
 * the split on spaces and tabs into a list.
 *
 * This requires an annoying workaround because one cannot specify a default
 * value of NULL with MIT Kerberos, since MIT Kerberos unconditionally calls
 * strdup on the default value.  There's also no way to determine if memory
 * allocation failed while parsing or while setting the default value.
 */
krb5_error_code
sync_config_list(krb5_context ctx, const char *opt, struct vector **result)
{
    realm_type realm;
    char *value = NULL;

    /* Obtain the string from [appdefaults]. */
    realm = default_realm(ctx);
    krb5_appdefault_string(ctx, "krb5-sync", realm, opt, "", &value);
    free_default_realm(ctx, realm);

    /* If we got something back, store it in result. */
    if (value != NULL) {
        if (value[0] != '\0') {
            *result = sync_vector_split_multi(value, " \t", *result);
            if (*result == NULL)
                return sync_error_system(ctx, "cannot allocate memory");
        }
        krb5_free_string(ctx, value);
    }
    return 0;
}
Beispiel #6
0
static char *
get_user_realm(krb5_context context)
{
    krb5_error_code ret;
    char *user_realm = NULL;

    /*
     * If memory allocation fails, we don't try to use the wrong realm,
     * that will trigger misleading error messages complicate support.
     */
    krb5_appdefault_string(context, "kinit", NULL, "user_realm", "",
			   &user_realm);
    if (user_realm == NULL) {
	ret = krb5_enomem(context);
	krb5_err(context, 1, ret, "krb5_appdefault_string");
    }

    if (*user_realm == 0) {
	free(user_realm);
	user_realm = NULL;
    }

    return user_realm;
}
Beispiel #7
0
int is_admin(struct rekey_session *sess)
{
  static int ldap_initialized=0;
  char *username=NULL;
  LDAP *l=NULL;
  int v, ssl_hard=LDAP_OPT_X_TLS_HARD, rc, ret=0;
  struct timeval tv;
  LDAPMessage *response=NULL;
  char *reason, *filter;
  char *ldap_url, *ldap_base, *ldap_filter, *ldap_binddn;
  char *ldap_pwfile, *ldap_cacertdir;
  char ldap_pwbuf[257];
#ifdef HAVE_KRB5_REALM
  krb5_realm *realm;
#else
  krb5_data rdata;
  krb5_data *realm = &rdata;
#endif
#if !defined(LDAP_OPT_X_TLS_PROTOCOL_MIN)
  SSL_CTX *sslctx;
#endif

  if (!princ_ncomp_eq(sess->kctx, sess->princ, 2) ||
      !compare_princ_comp(sess->kctx, sess->princ, 1, "admin")) {
    goto freeall;
  }

  if (!(username=dup_comp_string(sess->kctx, sess->princ, 0))) {
    prtmsg("Failed to extract username for admin check");
    goto freeall;
  }

#ifdef HAVE_KRB5_REALM
  realm=sess->realm;
#else
  rdata.data=sess->realm;
  rdata.length=strlen(sess->realm);
#endif
  krb5_appdefault_string(sess->kctx, "rekey", realm, "ldap_uri", LDAP_URI, &ldap_url);
  krb5_appdefault_string(sess->kctx, "rekey", realm, "ldap_base", LDAP_BASEDN, &ldap_base);
  krb5_appdefault_string(sess->kctx, "rekey", realm, "ldap_filter", USER_INGROUP_FILTER, &ldap_filter);
  krb5_appdefault_string(sess->kctx, "rekey", realm, "ldap_binddn", LDAP_BINDDN, &ldap_binddn);
  krb5_appdefault_string(sess->kctx, "rekey", realm, "ldap_pwfile", LDAP_PWFILE, &ldap_pwfile);
  krb5_appdefault_string(sess->kctx, "rekey", realm, "ldap_cacertdir", "/etc/andy/ldapcerts", &ldap_cacertdir);

  if (strlen(ldap_pwfile) > 0) {
    int fd=open(ldap_pwfile, O_RDONLY);
    ssize_t rsize;
    if (fd < 0) {
      prtmsg("Failed to open LDAP password file %s: %s", ldap_pwfile, strerror(errno));
      goto freeall;
    }
    rsize=read(fd, ldap_pwbuf, 256);
    if (rsize < 0) {
      prtmsg("Failed to read from LDAP password file %s: %s", ldap_pwfile, strerror(errno));
      goto freeall;
    }
    if (rsize > 255) {
      prtmsg("LDAP password file %s is too large. limit to 255 characters", ldap_pwfile);
      goto freeall;
    }
    while(rsize > 0 && isspace(ldap_pwbuf[rsize-1]))
      rsize--;
    ldap_pwbuf[rsize]=0;
  }
  if (!ldap_initialized) {
    LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ssl_hard);
    LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_CACERTDIR, ldap_cacertdir);
    LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, "HIGH:!ADH:!eNULL:-SSLv2");
#if defined(LDAP_OPT_X_TLS_PROTOCOL_MIN)
    v=LDAP_OPT_X_TLS_PROTOCOL_TLS1_0;
    LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_PROTOCOL_MIN, &v);
#else
    extern int ldap_pvt_tls_init();
    extern int ldap_pvt_tls_init_def_ctx( int is_server );
    ldap_pvt_tls_init();
    ldap_pvt_tls_init_def_ctx(0);
    LDAP_GET_OPTION(NULL, LDAP_OPT_X_TLS_CTX, &sslctx);
    if (sslctx) {
      SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2);
      SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv3);
    }
#endif
    ldap_initialized=1;
  }
  errno=0;
  rc = ldap_initialize(&l, ldap_url);

  
  if (rc!=LDAP_SUCCESS)
  {
    prtmsg("Failed to initialize ldap for %s: %s%s%s", ldap_url,
	   ldap_err2string(rc),(errno==0)?"":": ",
	   (errno==0)?"":strerror(errno));
    goto freeall;
  }
  v=LDAP_VERSION3;
  LDAP_SET_OPTION(l, LDAP_OPT_PROTOCOL_VERSION, &v);
  LDAP_SET_OPTION(l, LDAP_OPT_X_TLS, &ssl_hard);

  errno=0;
#if 0
  rc = ldap_sasl_interactive_bind_s(l, NULL, "GSSAPI", NULL, NULL,
				    LDAP_SASL_QUIET, do_sasl_interact, NULL);
#else
  rc = ldap_bind_s(l, ldap_binddn, ldap_pwbuf, LDAP_AUTH_SIMPLE);
#endif
  if (rc!=LDAP_SUCCESS)
  {
    prtmsg("Failed to connect or authenticate to ldap for %s: %s%s%s", LDAP_URI,
	   ldap_err2string(rc),(errno==0)?"":": ",
	   (errno==0)?"":strerror(errno));
    goto freeall;
  }

  tv.tv_sec=30;
  tv.tv_usec=0;
  rc = ldap_search_ext_s(l, rekey_admin_group, LDAP_SCOPE_BASE, NO_FILTER,
			 no_attrs, 0, NULL, NULL, &tv, LDAP_NO_LIMIT, &response);
  if (rc != LDAP_SUCCESS) {
      prtmsg("Failed to verify group %s existence (searching): %s%s%s", rekey_admin_group,
	   ldap_err2string(rc),(errno==0)?"":": ",
	   (errno==0)?"":strerror(errno));
      goto freeall;
  }

  reason=aasprintf("verify group %s existence", rekey_admin_group);
  if (!verify_op_success(l, reason, response))
    goto freeall;
  ldap_msgfree(response);
  response=NULL;

  filter=aasprintf(ldap_filter, username, rekey_admin_group);
  rc = ldap_search_ext_s(l, ldap_base, LDAP_SCOPE_SUB, filter,
			 no_attrs, 0, NULL, NULL, &tv, LDAP_NO_LIMIT, &response);
  if (rc != LDAP_SUCCESS) {
      prtmsg("Failed to check user %s admin permission (searching): %s%s%s", username,
	   ldap_err2string(rc),(errno==0)?"":": ",
	   (errno==0)?"":strerror(errno));
      goto freeall;
  }

  reason=aasprintf("check user %s admin permission", username);
  if (!verify_single_result(l, 0, reason, response))
    goto freeall;

  ret=1;
 freeall:
  ldap_msgfree(response);
  if (l)
    ldap_unbind_ext_s(l, NULL, NULL);
  free(username);
  return ret;
}