Beispiel #1
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;
    }
}
Beispiel #2
0
int store_cred_service(const char *user, const char *pw, int mode)
{
	const char *at = strchr(user, '@');
	if ((at == NULL) || (at == user)) {
		dprintf(D_ALWAYS, "store_cred: malformed user name\n");
		return FAILURE;
	}
	if (( (size_t)(at - user) != strlen(POOL_PASSWORD_USERNAME)) ||
	    (memcmp(user, POOL_PASSWORD_USERNAME, at - user) != 0))
	{
		dprintf(D_ALWAYS, "store_cred: only pool password is supported on UNIX\n");
		return FAILURE;
	}

	char *filename;
	if (mode != QUERY_MODE) {
		filename = param("SEC_PASSWORD_FILE");
		if (filename == NULL) {
			dprintf(D_ALWAYS, "store_cred: SEC_PASSWORD_FILE not defined\n");
			return FAILURE;
		}
	}

	int answer;
	switch (mode) {
	case ADD_MODE: {
		answer = FAILURE;
		size_t pw_sz = strlen(pw);
		if (!pw_sz) {
			dprintf(D_ALWAYS,
			        "store_cred_service: empty password not allowed\n");
			break;
		}
		if (pw_sz > MAX_PASSWORD_LENGTH) {
			dprintf(D_ALWAYS, "store_cred_service: password too large\n");
			break;
		}
		priv_state priv = set_root_priv();
		answer = write_password_file(filename, pw);
		set_priv(priv);
		break;
	}
	case DELETE_MODE: {
		priv_state priv = set_root_priv();
		int err = unlink(filename);
		set_priv(priv);
		if (!err) {
			answer = SUCCESS;
		}
		else {
			answer = FAILURE_NOT_FOUND;
		}
		break;
	}
	case QUERY_MODE: {
		char *password = getStoredCredential(POOL_PASSWORD_USERNAME, NULL);
		if (password) {
			answer = SUCCESS;
			SecureZeroMemory(password, MAX_PASSWORD_LENGTH);
			free(password);
		}
		else {
			answer = FAILURE_NOT_FOUND;
		}
		break;
	}
	default:
		dprintf(D_ALWAYS, "store_cred_service: unknown mode: %d\n", mode);
		answer = FAILURE;
	}

	// clean up after ourselves
	if (mode != QUERY_MODE) {
		free(filename);
	}

	return answer;
}