Esempio n. 1
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_creds(krb5_context context,
	       krb5_get_creds_opt opt,
	       krb5_ccache ccache,
	       krb5_const_principal inprinc,
	       krb5_creds **out_creds)
{
    krb5_kdc_flags flags;
    krb5_flags options;
    krb5_creds in_creds;
    krb5_error_code ret;
    krb5_creds **tgts;
    krb5_creds *try_creds;
    krb5_creds *res_creds;
    krb5_name_canon_iterator name_canon_iter = NULL;
    krb5_name_canon_rule_options rule_opts;
    int i;

    if (opt && opt->enctype) {
	ret = krb5_enctype_valid(context, opt->enctype);
	if (ret)
	    return ret;
    }

    memset(&in_creds, 0, sizeof(in_creds));
    in_creds.server = rk_UNCONST(inprinc);

    ret = krb5_cc_get_principal(context, ccache, &in_creds.client);
    if (ret)
	return ret;

    if (opt)
	options = opt->options;
    else
	options = 0;
    flags.i = 0;

    *out_creds = NULL;
    res_creds = calloc(1, sizeof(*res_creds));
    if (res_creds == NULL) {
	krb5_free_principal(context, in_creds.client);
	return krb5_enomem(context);
    }

    if (opt && opt->enctype) {
	in_creds.session.keytype = opt->enctype;
	options |= KRB5_TC_MATCH_KEYTYPE;
    }

    /* Check for entry in ccache */
    if (inprinc->name.name_type == KRB5_NT_SRV_HST_NEEDS_CANON) {
	ret = check_cc(context, options, ccache, &in_creds, res_creds);
	if (ret == 0) {
	    *out_creds = res_creds;
	    goto out;
	}
    }

    ret = krb5_name_canon_iterator_start(context, NULL, &in_creds,
					 &name_canon_iter);
    if (ret)
	goto out;

next_rule:
    ret = krb5_name_canon_iterate_creds(context, &name_canon_iter, &try_creds,
					&rule_opts);
    if (ret)
	return ret;
    if (name_canon_iter == NULL) {
	if (options & KRB5_GC_CACHED)
	    ret = KRB5_CC_NOTFOUND;
	else
	    ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
	goto out;
    }
    ret = check_cc(context, options, ccache, try_creds, res_creds);
    if (ret == 0) {
	*out_creds = res_creds;
	goto out;
    } else if(ret != KRB5_CC_END) {
	goto out;
    }
    if(options & KRB5_GC_CACHED)
	goto next_rule;

    if(rule_opts & KRB5_NCRO_USE_REFERRALS)
	flags.b.canonicalize = 1;
    else if(rule_opts & KRB5_NCRO_NO_REFERRALS)
	flags.b.canonicalize = 0;
    else
	flags.b.canonicalize = (options & KRB5_GC_CANONICALIZE) ? 1 : 0;
    if(options & KRB5_GC_USER_USER) {
	flags.b.enc_tkt_in_skey = 1;
	options |= KRB5_GC_NO_STORE;
    }
    if (options & KRB5_GC_FORWARDABLE)
	flags.b.forwardable = 1;
    if (options & KRB5_GC_NO_TRANSIT_CHECK)
	flags.b.disable_transited_check = 1;
    if (options & KRB5_GC_CONSTRAINED_DELEGATION) {
	flags.b.request_anonymous = 1; /* XXX ARGH confusion */
	flags.b.constrained_delegation = 1;
    }

    tgts = NULL;
    ret = _krb5_get_cred_kdc_any(context, flags, ccache,
				 try_creds, opt ? opt->self : 0,
				 opt ? opt->ticket : 0, out_creds,
				 &tgts);
    for(i = 0; tgts && tgts[i]; i++) {
	krb5_cc_store_cred(context, ccache, tgts[i]);
	krb5_free_creds(context, tgts[i]);
    }
    free(tgts);

    if (ret == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN &&
	!(rule_opts & KRB5_NCRO_SECURE))
	goto next_rule;

    if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0)
	store_cred(context, ccache, inprinc, *out_creds);

out:
    if (ret) {
	krb5_free_creds(context, res_creds);
	ret = not_found(context, inprinc, ret);
    }
    krb5_free_principal(context, in_creds.client);
    krb5_free_name_canon_iterator(context, name_canon_iter);
    _krb5_debug(context, 5, "krb5_get_creds: ret = %d", ret);
    return ret;
}
Esempio n. 2
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_get_credentials_with_flags(krb5_context context,
				krb5_flags options,
				krb5_kdc_flags flags,
				krb5_ccache ccache,
				krb5_creds *in_creds,
				krb5_creds **out_creds)
{
    krb5_error_code ret;
    krb5_name_canon_iterator name_canon_iter = NULL;
    krb5_name_canon_rule_options rule_opts;
    krb5_creds **tgts;
    krb5_creds *try_creds;
    krb5_creds *res_creds;
    int i;

    if (in_creds->session.keytype) {
	ret = krb5_enctype_valid(context, in_creds->session.keytype);
	if (ret)
	    return ret;
	options |= KRB5_TC_MATCH_KEYTYPE;
    }

    *out_creds = NULL;
    res_creds = calloc(1, sizeof(*res_creds));
    if (res_creds == NULL)
	return krb5_enomem(context);

    if (in_creds->server->name.name_type == KRB5_NT_SRV_HST_NEEDS_CANON) {
	ret = check_cc(context, options, ccache, in_creds, res_creds);
	if (ret == 0) {
	    *out_creds = res_creds;
	    return 0;
	}
    }

    ret = krb5_name_canon_iterator_start(context, NULL, in_creds,
					 &name_canon_iter);
    if (ret)
	return ret;

next_rule:
    krb5_free_cred_contents(context, res_creds);
    memset(res_creds, 0, sizeof (*res_creds));
    ret = krb5_name_canon_iterate_creds(context, &name_canon_iter, &try_creds,
					&rule_opts);
    if (ret)
	goto out;
    if (name_canon_iter == NULL) {
	if (options & KRB5_GC_CACHED)
	    ret = KRB5_CC_NOTFOUND;
	else
	    ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
	goto out;
    }

    ret = check_cc(context, options, ccache, try_creds, res_creds);
    if (ret == 0) {
	*out_creds = res_creds;
	goto out;
    } else if(ret != KRB5_CC_END) {
        goto out;
    }
    if(options & KRB5_GC_CACHED)
	goto next_rule;

    if(options & KRB5_GC_USER_USER)
	flags.b.enc_tkt_in_skey = 1;
    if (flags.b.enc_tkt_in_skey)
	options |= KRB5_GC_NO_STORE;

    tgts = NULL;
    ret = _krb5_get_cred_kdc_any(context, flags, ccache,
				 try_creds, NULL, NULL, out_creds, &tgts);
    for(i = 0; tgts && tgts[i]; i++) {
	krb5_cc_store_cred(context, ccache, tgts[i]);
	krb5_free_creds(context, tgts[i]);
    }
    free(tgts);
    if (ret == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN &&
	!(rule_opts & KRB5_NCRO_SECURE))
	goto next_rule;

    if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0)
	store_cred(context, ccache, in_creds->server, *out_creds);

out:
    krb5_free_name_canon_iterator(context, name_canon_iter);
    if (ret) {
	krb5_free_creds(context, res_creds);
	return not_found(context, in_creds->server, ret);
    }
    return 0;
}
Esempio n. 3
0
int main(int argc, char *argv[]) {

    MyString my_full_name;
    const char *full_name;
    char* pw = NULL;
    struct StoreCredOptions options;
    int result = FAILURE_ABORTED;
    bool pool_password_arg = false;
    bool pool_password_delete = false;
    Daemon *daemon = NULL;
    char *credd_host;

    MyName = condor_basename(argv[0]);

    // load up configuration file
    myDistro->Init( argc, argv );
    config();

    if (!parseCommandLine(&options, argc, argv)) {
        goto cleanup;
    }

    // if -h was given, just print usage
    if (options.help || (options.mode == 0)) {
        usage();
        goto cleanup;
    }

#if !defined(WIN32)
    // if the -f argument was given, we just want to prompt for a password
    // and write it to a file (in our weirdo XORed format)
    //
    if (options.password_file != NULL) {
        if (options.pw[0] == '\0') {
            pw = get_password();
            printf("\n");
        }
        else {
            pw = strnewp(options.pw);
            SecureZeroMemory(options.pw, MAX_PASSWORD_LENGTH + 1);
        }
        result = write_password_file(options.password_file, pw);
        SecureZeroMemory(pw, strlen(pw));
        if (result != SUCCESS) {
            fprintf(stderr,
                    "error writing password file: %s\n",
                    options.password_file);
        }
        goto cleanup;
    }
#endif

    // determine the username to use
    if ( strcmp(options.username, "") == 0 ) {
        // default to current user and domain
        char* my_name = my_username();
        char* my_domain = my_domainname();

        my_full_name.formatstr("%s@%s", my_name, my_domain);
        if ( my_name) {
            free(my_name);
        }
        if ( my_domain) {
            free(my_domain);
        }
        my_name = my_domain = NULL;
    } else if (strcmp(options.username, POOL_PASSWORD_USERNAME) == 0) {
#if !defined(WIN32)
        // we don't support querying the pool password on UNIX
        // (since it is not possible to do so through the
        //  STORE_POOL_CRED command)
        if (options.mode == QUERY_MODE) {
            fprintf(stderr, "Querying the pool password is not supported.\n");
            goto cleanup;
        }
#endif
        // append the correct domain name if we're using the pool pass
        // we first try POOL_PASSWORD_DOMAIN, then UID_DOMAIN
        pool_password_arg = true;
        char *domain;
        if ((domain = param("SEC_PASSWORD_DOMAIN")) == NULL) {
            if ((domain = param("UID_DOMAIN")) == NULL) {
                fprintf(stderr, "ERROR: could not domain for pool password\n");
                goto cleanup;
            }
        }
        my_full_name.formatstr(POOL_PASSWORD_USERNAME "@%s", domain);
        free(domain);
    } else {
        // username was specified on the command line
        my_full_name += options.username;
    }
    full_name = my_full_name.Value();
    printf("Account: %s\n\n", full_name);

    // determine where to direct our command
    daemon = NULL;
    credd_host = NULL;
    if (options.daemonname != NULL) {
        if (pool_password_arg && (options.mode != QUERY_MODE)) {
            // daemon named on command line; go to master for pool password
            //printf("sending command to master: %s\n", options.daemonname);
            daemon = new Daemon(DT_MASTER, options.daemonname);
        }
        else {
            // daemon named on command line; go to schedd for user password
            //printf("sending command to schedd: %s\n", options.daemonname);
            daemon = new Daemon(DT_SCHEDD, options.daemonname);
        }
    }
    else if (!pool_password_arg && ((credd_host = param("CREDD_HOST")) != NULL)) {
        // no daemon given, use credd for user passwords if CREDD_HOST is defined
        // (otherwise, we use the local schedd)
        //printf("sending command to CREDD: %s\n", credd_host);
        daemon = new Daemon(DT_CREDD);
    }
    else {
        //printf("sending command to local daemon\n");
    }

    // flag the case where we're deleting the pool password
    if (pool_password_arg && (options.mode == DELETE_MODE)) {
        pool_password_delete = true;
    }

    switch (options.mode) {
    case ADD_MODE:
    case DELETE_MODE:
        if (!pool_password_delete) {
            if ( strcmp(options.pw, "") == 0 ) {
                // get password from the user.
                pw = get_password();
                printf("\n\n");
            } else {
                // got the passwd from the command line.
                pw = strnewp(options.pw);
                SecureZeroMemory(options.pw, MAX_PASSWORD_LENGTH);
            }
        }
        if ( pw || pool_password_delete) {
            result = store_cred(full_name, pw, options.mode, daemon);
            if ((result == FAILURE_NOT_SECURE) && goAheadAnyways()) {
                // if user is ok with it, send the password in the clear
                result = store_cred(full_name, pw, options.mode, daemon, true);
            }
            if (pw) {
                SecureZeroMemory(pw, strlen(pw));
                delete[] pw;
            }
        }
        break;
    case QUERY_MODE:
        result = queryCredential(full_name, daemon);
        break;
#if defined(WIN32)
    case CONFIG_MODE:
        return interactive();
        break;
#endif
    default:
        fprintf(stderr, "Internal error\n");
        goto cleanup;
    }

    // output result of operation
    switch (result) {
    case SUCCESS:
        if (options.mode == QUERY_MODE) {
            printf("A credential is stored and is valid.\n");
        }
        else {
            printf("Operation succeeded.\n");
        }
        break;

    case FAILURE:
        printf("Operation failed.\n");
        if (pool_password_arg && (options.mode != QUERY_MODE)) {
            printf("    Make sure you have CONFIG access to the target Master.\n");
        }
        else {
            printf("    Make sure your ALLOW_WRITE setting includes this host.\n");
        }
        break;

    case FAILURE_BAD_PASSWORD:
        if (options.mode == QUERY_MODE) {
            printf("A credential is stored, but it is invalid. "
                   "Run 'condor_store_cred add' again.\n");
        }
        else {
            printf("Operation failed: bad password.\n");
        }
        break;

    case FAILURE_NOT_FOUND:
        if (options.mode == QUERY_MODE) {
            printf("No credential is stored.\n");
        }
        else {
            printf("Operation failed: username not found.\n");
        }
        break;

    case FAILURE_NOT_SECURE:
    case FAILURE_ABORTED:
        printf("Operation aborted.\n");
        break;

    case FAILURE_NOT_SUPPORTED:
        printf("Operation failed.\n"
               "    The target daemon is not running as SYSTEM.\n");
        break;

    default:
        fprintf(stderr, "Operation failed: unknown error code\n");
    }

cleanup:
    if (options.daemonname) {
        delete[] options.daemonname;
    }
    if (daemon) {
        delete daemon;
    }

    if ( result == SUCCESS ) {
        return 0;
    } else {
        return 1;
    }
}
Esempio n. 4
0
int queryCredential( const char* user, Daemon *d ) {
	return store_cred(user, NULL, QUERY_MODE, d);	
}
Esempio n. 5
0
int addCredential( const char* user, const char* pw, Daemon *d ) {
	return store_cred(user, pw, ADD_MODE, d);	
}
Esempio n. 6
0
int deleteCredential( const char* user, const char* pw, Daemon *d ) {
	return store_cred(user, pw, DELETE_MODE, d);	
}