bool putClassAdAndEOM(Sock & sock, classad::ClassAd &ad) { if (sock.type() != Stream::reli_sock) { return putClassAd(&sock, ad) && sock.end_of_message(); } ReliSock & rsock = static_cast<ReliSock&>(sock); Selector selector; selector.add_fd(sock.get_file_desc(), Selector::IO_WRITE); int timeout = sock.timeout(0); sock.timeout(timeout); timeout = timeout ? timeout : 20; selector.set_timeout(timeout); if (!putClassAd(&sock, ad, PUT_CLASSAD_NON_BLOCKING)) { return false; } int retval = rsock.end_of_message_nonblocking(); while (true) { if (rsock.clear_backlog_flag()) { Py_BEGIN_ALLOW_THREADS selector.execute(); Py_END_ALLOW_THREADS if (selector.timed_out()) {THROW_EX(RuntimeError, "Timeout when trying to write to remote host");} } else if (retval == 1) {
int store_cred(const char* user, const char* pw, int mode, Daemon* d, bool force) { int result; int return_val; Sock* sock = NULL; // to help future debugging, print out the mode we are in static const int mode_offset = 100; static const char *mode_name[] = { ADD_CREDENTIAL, DELETE_CREDENTIAL, QUERY_CREDENTIAL #ifdef WIN32 , CONFIG_CREDENTIAL #endif }; dprintf ( D_ALWAYS, "STORE_CRED: In mode '%s'\n", mode_name[mode - mode_offset] ); // If we are root / SYSTEM and we want a local daemon, // then do the work directly to the local registry. // If not, then send the request over the wire to a remote credd or schedd. if ( is_root() && d == NULL ) { // do the work directly onto the local registry return_val = store_cred_service(user,pw,mode); } else { // send out the request remotely. // first see if we're operating on the pool password int cmd = STORE_CRED; char const *tmp = strchr(user, '@'); if (tmp == NULL || tmp == user || *(tmp + 1) == '\0') { dprintf(D_ALWAYS, "store_cred: user not in user@domain format\n"); return FAILURE; } if (((mode == ADD_MODE) || (mode == DELETE_MODE)) && ( (size_t)(tmp - user) == strlen(POOL_PASSWORD_USERNAME)) && (memcmp(POOL_PASSWORD_USERNAME, user, tmp - user) == 0)) { cmd = STORE_POOL_CRED; user = tmp + 1; // we only need to send the domain name for STORE_POOL_CRED } if (d == NULL) { if (cmd == STORE_POOL_CRED) { // need to go to the master for setting the pool password dprintf(D_FULLDEBUG, "Storing credential to local master\n"); Daemon my_master(DT_MASTER); sock = my_master.startCommand(cmd, Stream::reli_sock, 0); } else { dprintf(D_FULLDEBUG, "Storing credential to local schedd\n"); Daemon my_schedd(DT_SCHEDD); sock = my_schedd.startCommand(cmd, Stream::reli_sock, 0); } } else { dprintf(D_FULLDEBUG, "Starting a command on a REMOTE schedd\n"); sock = d->startCommand(cmd, Stream::reli_sock, 0); } if( !sock ) { dprintf(D_ALWAYS, "STORE_CRED: Failed to start command.\n"); dprintf(D_ALWAYS, "STORE_CRED: Unable to contact the REMOTE schedd.\n"); return FAILURE; } // for remote updates (which send the password), verify we have a secure channel, // unless "force" is specified if (((mode == ADD_MODE) || (mode == DELETE_MODE)) && !force && (d != NULL) && ((sock->type() != Stream::reli_sock) || !((ReliSock*)sock)->triedAuthentication() || !sock->get_encryption())) { dprintf(D_ALWAYS, "STORE_CRED: blocking attempt to update over insecure channel\n"); delete sock; return FAILURE_NOT_SECURE; } if (cmd == STORE_CRED) { result = code_store_cred(sock, const_cast<char*&>(user), const_cast<char*&>(pw), mode); if( result == FALSE ) { dprintf(D_ALWAYS, "store_cred: code_store_cred failed.\n"); delete sock; return FAILURE; } } else { // only need to send the domain and password for STORE_POOL_CRED if (!sock->code(const_cast<char*&>(user)) || !sock->code(const_cast<char*&>(pw)) || !sock->end_of_message()) { dprintf(D_ALWAYS, "store_cred: failed to send STORE_POOL_CRED message\n"); delete sock; return FAILURE; } } sock->decode(); result = sock->code(return_val); if( !result ) { dprintf(D_ALWAYS, "store_cred: failed to recv answer.\n"); delete sock; return FAILURE; } result = sock->end_of_message(); if( !result ) { dprintf(D_ALWAYS, "store_cred: failed to recv eom.\n"); delete sock; return FAILURE; } } // end of case where we send out the request remotely switch(mode) { case ADD_MODE: if( return_val == SUCCESS ) { dprintf(D_FULLDEBUG, "Addition succeeded!\n"); } else { dprintf(D_FULLDEBUG, "Addition failed!\n"); } break; case DELETE_MODE: if( return_val == SUCCESS ) { dprintf(D_FULLDEBUG, "Delete succeeded!\n"); } else { dprintf(D_FULLDEBUG, "Delete failed!\n"); } break; case QUERY_MODE: if( return_val == SUCCESS ) { dprintf(D_FULLDEBUG, "We have a credential stored!\n"); } else { dprintf(D_FULLDEBUG, "Query failed!\n"); } break; } if ( sock ) delete sock; return return_val; }