static void global_user_list_cb (USER * user, struct guldata *data) { ASSERT (validate_user (user)); ASSERT (data != 0); if (data->flags) { /* selectively display users based on user level/muzzle/cloak */ if (! (((data->flags & ON_GFLAG_ADMIN) && user->level == LEVEL_ADMIN) || ((data->flags & ON_GFLAG_ELITE) && user->level == LEVEL_ELITE) || ((data->flags & ON_GFLAG_MODERATOR) && user->level == LEVEL_MODERATOR) || ((data->flags & ON_GFLAG_USERS) && user->level == LEVEL_USER) || ((data->flags & ON_GFLAG_LEECH) && user->level == LEVEL_LEECH) || ((data->flags & ON_GFLAG_MUZZLED) && user->muzzled) || ((data->flags & ON_GFLAG_CLOAKED) && user->cloaked) || ((data->flags & ON_GFLAG_USERIP) && (user->ip & data->mask) == (data->ip & data->mask)))) return; } if (data->server && *data->server != '*' && strcasecmp (data->server, user->server) != 0) return; /* no match */ send_cmd (data->con, MSG_SERVER_GLOBAL_USER_LIST, "%s %s", user->nick, my_ntoa (BSWAP32 (user->ip))); }
/** * The /ns logout command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_logout(User * u) { char *nick = strtok(NULL, " "); char *param = strtok(NULL, " "); User *u2; if (!is_services_admin(u) && nick) { syntax_error(s_NickServ, u, "LOGOUT", NICK_LOGOUT_SYNTAX); } else if (!(u2 = (nick ? finduser(nick) : u))) { notice_lang(s_NickServ, u, NICK_X_NOT_IN_USE, nick); } else if (!u2->na) { if (nick) notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick); else notice_lang(s_NickServ, u, NICK_NOT_REGISTERED); } else if (u2->na->status & NS_VERBOTEN) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u2->na->nick); } else if (!nick && !nick_identified(u)) { notice_lang(s_NickServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); } else if (nick && is_services_admin(u2)) { notice_lang(s_NickServ, u, NICK_LOGOUT_SERVICESADMIN, nick); } else { if (nick && param && !stricmp(param, "REVALIDATE")) { cancel_user(u2); validate_user(u2); } else { u2->na->status &= ~(NS_IDENTIFIED | NS_RECOGNIZED); } if (ircd->modeonreg) { common_svsmode(u2, ircd->modeonunreg, "1"); } u->isSuperAdmin = 0; /* Dont let people logout and remain a SuperAdmin */ alog("%s: %s!%s@%s logged out nickname %s", s_NickServ, u->nick, u->username, u->host, u2->nick); if (nick) notice_lang(s_NickServ, u, NICK_LOGOUT_X_SUCCEEDED, nick); else notice_lang(s_NickServ, u, NICK_LOGOUT_SUCCEEDED); /* Stop nick tracking if enabled */ if (NSNickTracking) /* Shouldn't this be u2? -GD */ nsStopNickTracking(u); /* Clear any timers again */ if (u->na->nc->flags & NI_KILLPROTECT) { del_ns_timeout(u->na, TO_COLLIDE); } /* Send out an event */ send_event(EVENT_NICK_LOGOUT, 1, u2->nick); } return MOD_CONT; }
END_TEST START_TEST(test_validate_user) { int rc; char msg [100]; getsockopt_success = true; getpwuid_success = true; rc = validate_user(10, "eris", 1, msg); fail_unless(rc == PBSE_NONE); // send in a NULL name rc = validate_user(10, NULL, 1, msg); fail_unless(rc != PBSE_NONE); // send a null msg pointer rc = validate_user(10, "eris", 1, NULL); fail_unless(rc != PBSE_NONE); getsockopt_success = false; rc = validate_user(10, "eris", 1, msg); fail_unless(rc != PBSE_NONE); getsockopt_success = true; getpwuid_success = false; rc = validate_user(10, "eris", 1, msg); fail_unless(rc != PBSE_NONE); // test the case where user names won't match getpwuid_success = true; rc = validate_user(10, "fred", 1, msg); fail_unless(rc != PBSE_NONE); // test the case where user pids won't match rc = validate_user(10, "eris", 2, msg); fail_unless(rc != PBSE_NONE); }
int do_saregister(User *u) { char *buf, *nick, *pass, *email; NickRequest *nr; NickAlias *na; User *user; buf = moduleGetLastBuffer(); nick = myStrGetToken(buf, ' ', 0); pass = myStrGetToken(buf, ' ', 1); email = myStrGetToken(buf, ' ', 2); if (!email) { notice_user(s_NickServ, u, "Syntax: \2SAREGISTER \37nick\37 \37password\37 \37email\37"); notice_lang(s_NickServ, u, MORE_INFO, s_NickServ, "SAREGISTER"); } else if (readonly) { notice_lang(s_NickServ, u, NICK_REGISTRATION_DISABLED); } else if ((nr = findrequestnick(nick))) { notice_lang(s_NickServ, u, NICK_REQUESTED); } else if (!anope_valid_nick(nick)) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick); } else if ((na = findnick(nick))) { if (na->status & NS_VERBOTEN) notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, nick); else notice_lang(s_NickServ, u, NICK_ALREADY_REGISTERED, nick); } else if (!MailValidate(email)) { notice_lang(s_NickServ, u, MAIL_X_INVALID, email); } else { na = makenick(nick); if (!na) { alog("%s: makenick(%s) failed", s_NickServ, u->nick); notice_lang(s_NickServ, u, NICK_REGISTRATION_FAILED); } else { user = finduser(nick); enc_encrypt(pass, strlen(pass), na->nc->pass, PASSMAX - 1); na->nc->flags |= NSDefFlags; na->nc->memos.memomax = MSMaxMemos; if (user) na->last_usermask = user->vhost ? sstrdup(user->vhost) : sstrdup(user->host); else na->last_usermask = sstrdup("*@*"); if (user) na->last_realname = sstrdup(user->realname); else na->last_realname = sstrdup("unknown"); na->time_registered = na->last_seen = time(NULL); na->nc->language = NSDefLanguage; na->nc->email = sstrdup(email); send_event(EVENT_NICK_REGISTERED, 1, nick); alog("%s: %s (%s@%s) used saregister to register %s", s_NickServ, u->nick, u->username, u->host, nick); notice_user(s_NickServ, u, "Nick \2%s\2 has been registered", nick); if (user) { user->na = na; validate_user(user); } } } if (email) free(email); if (pass) free(pass); if (nick) free(nick); return MOD_CONT; }
int nslcd_usermod(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid) { int32_t tmpint32; int rc = LDAP_SUCCESS; char username[BUFLEN_NAME]; int asroot, isroot; char password[BUFLEN_PASSWORD]; int32_t param; char buffer[4096]; size_t buflen = sizeof(buffer); size_t bufptr = 0; const char *value = NULL; const char *fullname = NULL, *roomnumber = NULL, *workphone = NULL; const char *homephone = NULL, *other = NULL, *homedir = NULL; const char *shell = NULL; const char *binddn = NULL; /* the user performing the modification */ MYLDAP_ENTRY *entry; MYLDAP_SESSION *newsession; char errmsg[BUFLEN_MESSAGE]; /* read request parameters */ READ_STRING(fp, username); READ_INT32(fp, asroot); READ_STRING(fp, password); /* read the usermod parameters */ while (1) { READ_INT32(fp, param); if (param == NSLCD_USERMOD_END) break; READ_BUF_STRING(fp, value); switch (param) { case NSLCD_USERMOD_FULLNAME: fullname = value; break; case NSLCD_USERMOD_ROOMNUMBER: roomnumber = value; break; case NSLCD_USERMOD_WORKPHONE: workphone = value; break; case NSLCD_USERMOD_HOMEPHONE: homephone = value; break; case NSLCD_USERMOD_OTHER: other = value; break; case NSLCD_USERMOD_HOMEDIR: homedir = value; break; case NSLCD_USERMOD_SHELL: shell = value; break; default: /* other parameters are silently ignored */ break; } } /* log call */ log_setrequest("usermod=\"%s\"", username); log_log(LOG_DEBUG, "nslcd_usermod(\"%s\",%s,\"%s\")", username, asroot ? "asroot" : "asuser", *password ? "***" : ""); if (fullname != NULL) log_log(LOG_DEBUG, "nslcd_usermod(fullname=\"%s\")", fullname); if (roomnumber != NULL) log_log(LOG_DEBUG, "nslcd_usermod(roomnumber=\"%s\")", roomnumber); if (workphone != NULL) log_log(LOG_DEBUG, "nslcd_usermod(workphone=\"%s\")", workphone); if (homephone != NULL) log_log(LOG_DEBUG, "nslcd_usermod(homephone=\"%s\")", homephone); if (other != NULL) log_log(LOG_DEBUG, "nslcd_usermod(other=\"%s\")", other); if (homedir != NULL) log_log(LOG_DEBUG, "nslcd_usermod(homedir=\"%s\")", homedir); if (shell != NULL) log_log(LOG_DEBUG, "nslcd_usermod(shell=\"%s\")", shell); /* write the response header */ WRITE_INT32(fp, NSLCD_VERSION); WRITE_INT32(fp, NSLCD_ACTION_USERMOD); /* validate request */ entry = validate_user(session, username, &rc); if (entry == NULL) { /* for user not found we just say no result, otherwise break the protocol */ if (rc == LDAP_NO_SUCH_OBJECT) { WRITE_INT32(fp, NSLCD_RESULT_END); } return -1; } /* check if it is a modification as root */ isroot = (calleruid == 0) && asroot; if (asroot) { if (nslcd_cfg->rootpwmoddn == NULL) { log_log(LOG_NOTICE, "rootpwmoddn not configured"); /* we break the protocol */ return -1; } binddn = nslcd_cfg->rootpwmoddn; /* check if rootpwmodpw should be used */ if ((*password == '\0') && isroot && (nslcd_cfg->rootpwmodpw != NULL)) { if (strlen(nslcd_cfg->rootpwmodpw) >= sizeof(password)) { log_log(LOG_ERR, "nslcd_pam_pwmod(): rootpwmodpw will not fit in password"); return -1; } strcpy(password, nslcd_cfg->rootpwmodpw); } } else binddn = myldap_get_dn(entry); WRITE_INT32(fp, NSLCD_RESULT_BEGIN); /* home directory change requires either root or valid directory */ if ((homedir != NULL) && (!isroot) && !is_valid_homedir(homedir)) { log_log(LOG_NOTICE, "invalid directory: %s", homedir); WRITE_INT32(fp, NSLCD_USERMOD_HOMEDIR); WRITE_STRING(fp, "invalid directory"); homedir = NULL; } /* shell change requires either root or a valid shell */ if ((shell != NULL) && (!isroot) && !is_valid_shell(shell)) { log_log(LOG_NOTICE, "invalid shell: %s", shell); WRITE_INT32(fp, NSLCD_USERMOD_SHELL); WRITE_STRING(fp, "invalid shell"); shell = NULL; } /* perform requested changes */ newsession = get_session(binddn, myldap_get_dn(entry), password, &rc); if (newsession != NULL) { rc = change(newsession, myldap_get_dn(entry), homedir, shell); myldap_session_close(newsession); } /* return response to caller */ if (rc != LDAP_SUCCESS) { log_log(LOG_WARNING, "%s: modification failed: %s", myldap_get_dn(entry), ldap_err2string(rc)); mysnprintf(errmsg, sizeof(errmsg) - 1, "change failed: %s", ldap_err2string(rc)); WRITE_INT32(fp, NSLCD_USERMOD_RESULT); WRITE_STRING(fp, errmsg); WRITE_INT32(fp, NSLCD_USERMOD_END); WRITE_INT32(fp, NSLCD_RESULT_END); return 0; } log_log(LOG_NOTICE, "changed information for %s", myldap_get_dn(entry)); WRITE_INT32(fp, NSLCD_USERMOD_END); WRITE_INT32(fp, NSLCD_RESULT_END); return 0; }
/** * Adds a new user to anopes internal userlist. * * If the SVID passed is 2, the user will not be marked registered or requested to ID. * This is an addition to accomodate IRCds where we cannot determine this based on the NICK * or UID command. Some IRCd's keep +r on when changing nicks and do not use SVID (ex. InspIRCd 1.2). * Instead we get a METADATA command containing the accountname the user was last identified to. * Since this is received after the user is introduced to us we should not yet mark the user * as identified or ask him to identify. We will mark him as recognized for the time being and let * him keep his +r if he has it. * It is the responsibility of the protocol module to make sure that this is either invalidated, * or changed to identified. ~ Viper **/ User *do_nick(const char *source, char *nick, char *username, char *host, char *server, char *realname, time_t ts, uint32 svid, uint32 ip, char *vhost, char *uid) { User *user = NULL; char *tmp = NULL; NickAlias *old_na; /* Old nick rec */ int nc_changed = 1; /* Did nick core change? */ int status = 0; /* Status to apply */ char mask[USERMAX + HOSTMAX + 2]; char *logrealname; char *oldnick; if (!*source) { char ipbuf[16]; struct in_addr addr; if (ircd->nickvhost) { if (vhost) { if (!strcmp(vhost, "*")) { vhost = NULL; if (debug) alog("debug: new user�with no vhost in NICK command: %s", nick); } } } /* This is a new user; create a User structure for it. */ if (debug) alog("debug: new user: %s", nick); if (ircd->nickip) { addr.s_addr = htonl(ip); ntoa(addr, ipbuf, sizeof(ipbuf)); } if (LogUsers) { /** * Ugly swap routine for Flop's bug :) **/ if (realname) { tmp = strchr(realname, '%'); while (tmp) { *tmp = '-'; tmp = strchr(realname, '%'); } } logrealname = normalizeBuffer(realname); /** * End of ugly swap **/ if (ircd->nickvhost) { if (ircd->nickip) { alog("LOGUSERS: %s (%s@%s => %s) (%s) [%s] connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, ipbuf, server); } else { alog("LOGUSERS: %s (%s@%s => %s) (%s) connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, server); } } else { if (ircd->nickip) { alog("LOGUSERS: %s (%s@%s) (%s) [%s] connected to the network (%s).", nick, username, host, logrealname, ipbuf, server); } else { alog("LOGUSERS: %s (%s@%s) (%s) connected to the network (%s).", nick, username, host, logrealname, server); } } Anope_Free(logrealname); } /* We used to ignore the ~ which a lot of ircd's use to indicate no * identd response. That caused channel bans to break, so now we * just take what the server gives us. People are still encouraged * to read the RFCs and stop doing anything to usernames depending * on the result of an identd lookup. */ /* First check for AKILLs. */ /* DONT just return null if its an akill match anymore - yes its more efficent to, however, now that ircd's are * starting to use things like E/F lines, we cant be 100% sure the client will be removed from the network :/ * as such, create a user_struct, and if the client is removed, we'll delete it again when the QUIT notice * comes in from the ircd. **/ if (check_akill(nick, username, host, vhost, ipbuf)) { /* return NULL; */ } /** * DefCon AKILL system, if we want to akill all connecting user's here's where to do it * then force check_akill again on them... **/ /* don't akill on netmerges -Certus */ /* don't akill clients introduced by ulines. -Viper */ if (is_sync(findserver(servlist, server)) && checkDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(server)) { strncpy(mask, "*@", 3); strncat(mask, host, HOSTMAX); alog("DEFCON: adding akill for %s", mask); add_akill(NULL, mask, s_OperServ, time(NULL) + dotime(DefConAKILL), DefConAkillReason ? DefConAkillReason : "DEFCON AKILL"); if (check_akill(nick, username, host, vhost, ipbuf)) { /* return NULL; */ } } /* SGLINE */ if (ircd->sgline) { if (check_sgline(nick, realname)) return NULL; } /* SQLINE */ if (ircd->sqline) { if (check_sqline(nick, 0)) return NULL; } /* SZLINE */ if (ircd->szline && ircd->nickip) { if (check_szline(nick, ipbuf)) return NULL; } /* Now check for session limits */ if (LimitSessions && !is_ulined(server) && !add_session(nick, host, ipbuf)) return NULL; /* Allocate User structure and fill it in. */ user = new_user(nick); user->username = sstrdup(username); user->host = sstrdup(host); user->server = findserver(servlist, server); user->realname = sstrdup(realname); user->timestamp = ts; user->my_signon = time(NULL); user->chost = vhost ? sstrdup(vhost) : sstrdup(host); user->vhost = vhost ? sstrdup(vhost) : sstrdup(host); if (uid) { user->uid = sstrdup(uid); /* p10/ts6 stuff */ } else { user->uid = NULL; } user->vident = sstrdup(username); /* We now store the user's ip in the user_ struct, * because we will use it in serveral places -- DrStein */ if (ircd->nickip) { user->hostip = sstrdup(ipbuf); } else { user->hostip = NULL; } if (svid == 0) { display_news(user, NEWS_LOGON); display_news(user, NEWS_RANDOM); } if (svid == 2 && user->na) { /* We do not yet know if the user should be identified or not. * mark him as recognized for now. * It s up to the protocol module to make sure this either becomes ID'd or * is invalidated. ~ Viper */ if (debug) alog("debug: Marking %s as recognized..", user->nick); user->svid = 1; user->na->status |= NS_RECOGNIZED; nc_changed = 0; } else if (svid == ts && user->na) { /* Timestamp and svid match, and nick is registered; automagically identify the nick */ user->svid = svid; user->na->status |= NS_IDENTIFIED; check_memos(user); nc_changed = 0; /* Start nick tracking if available */ if (NSNickTracking) nsStartNickTracking(user); } else if (svid != 1) { /* Resets the svid because it doesn't match */ user->svid = 1; anope_cmd_svid_umode(user->nick, user->timestamp); } else { user->svid = 1; } send_event(EVENT_NEWNICK, 1, nick); } else { /* An old user changing nicks. */ if (UseTS6 && ircd->ts6) user = find_byuid(source); if (!user) user = finduser(source); if (!user) { alog("user: NICK from nonexistent nick %s", source); return NULL; } user->isSuperAdmin = 0; /* Dont let people nick change and stay SuperAdmins */ if (debug) alog("debug: %s changes nick to %s", source, nick); if (LogUsers) { logrealname = normalizeBuffer(user->realname); if (ircd->vhost) { alog("LOGUSERS: %s (%s@%s => %s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, (user->vhost ? user->vhost : "(none)"), logrealname, nick, user->server->name); } else { alog("LOGUSERS: %s (%s@%s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, logrealname, nick, user->server->name); } if (logrealname) { free(logrealname); } } user->timestamp = ts; if (stricmp(nick, user->nick) == 0) { /* No need to redo things */ change_user_nick(user, nick); nc_changed = 0; } else { /* Update this only if nicks aren't the same */ user->my_signon = time(NULL); old_na = user->na; if (old_na) { if (nick_recognized(user)) user->na->last_seen = time(NULL); status = old_na->status & NS_TRANSGROUP; cancel_user(user); } oldnick = sstrdup(user->nick); change_user_nick(user, nick); if ((old_na ? old_na->nc : NULL) == (user->na ? user->na->nc : NULL)) nc_changed = 0; if (!nc_changed && (user->na)) user->na->status |= status; else { anope_cmd_nc_change(user); } send_event(EVENT_CHANGE_NICK, 2, nick, oldnick); free(oldnick); } if (ircd->sqline) { if (!is_oper(user) && check_sqline(user->nick, 1)) return NULL; } } /* if (!*source) */ /* Check for nick tracking to bypass identification */ if (NSNickTracking && nsCheckNickTracking(user)) { user->na->status |= NS_IDENTIFIED; nc_changed = 0; } if (nc_changed || !nick_recognized(user)) { if (validate_user(user)) check_memos(user); } else { if (nick_identified(user)) { char tsbuf[16]; user->na->last_seen = time(NULL); if (user->na->last_usermask) free(user->na->last_usermask); user->na->last_usermask = smalloc(strlen(common_get_vident(user)) + strlen(common_get_vhost(user)) + 2); sprintf(user->na->last_usermask, "%s@%s", common_get_vident(user), common_get_vhost(user)); snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) user->timestamp); anope_cmd_svid_umode2(user, tsbuf); alog("%s: %s!%s@%s automatically identified for nick %s", s_NickServ, user->nick, user->username, user->host, user->nick); } } /* Bahamut sets -r on every nick changes, so we must test it even if nc_changed == 0 */ if (ircd->check_nick_id) { if (nick_identified(user)) { char tsbuf[16]; snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) user->timestamp); anope_cmd_svid_umode3(user, tsbuf); } } return user; }
static Bool vms_passwd_valid_p(char *pw, Bool verbose_p) { return (validate_user (getenv("USER"), typed_passwd) == 1); }
void free_user (USER * user) { HOTLIST *hotlist; LIST *list; USERDB *db; ASSERT (validate_user (user)); if (ISUSER (user->con) && Servers && !user->con->killed) { /* local user, notify peers of this user's departure */ pass_message_args (user->con, MSG_CLIENT_QUIT, "%s", user->nick); } /* remove this user from any channels they were on */ if (user->channels) { for (list = user->channels; list; list = list->next) { /* notify locally connected clients in the same channel that this user has parted */ part_channel (list->data, user); } list_free (user->channels, 0); } /* free up invite list */ for(list=user->invited;list;list=list->next) { CHANNEL *chan = list->data; chan->invited=list_delete(chan->invited,user); } ASSERT (Num_Files >= user->shared); Num_Files -= user->shared; Num_Gigs -= user->libsize; /* this is in kB */ if (ISUSER (user->con)) Local_Files -= user->shared; /* check the global hotlist for this user to see if anyone wants notice of this user's departure */ hotlist = hash_lookup (Hotlist, user->nick); if (hotlist) { ASSERT (validate_hotlist (hotlist)); ASSERT (hotlist->users != 0); for (list = hotlist->users; list; list = list->next) send_cmd (list->data, MSG_SERVER_USER_SIGNOFF, "%s", user->nick); } /* record the log off time */ if ((db = hash_lookup (User_Db, user->nick))) db->lastSeen = Current_Time; FREE (user->nick); FREE (user->pass); FREE (user->clientinfo); /* NOTE: user->server is just a ref, not a malloc'd pointer */ FREE (user); }
int get_tickets(int version) { rkinit_info info; AUTH_DAT auth_dat; int status; char errmsg[BUFSIZ]; /* error message for client */ rkinitd_intkt_info rii; SBCLEAR(info); SBCLEAR(auth_dat); BCLEAR(errmsg); SBCLEAR(rii); rpc_get_rkinit_info(&info); /* * The validate_user routine makes sure that the principal in question * is allowed to log in as username, and if so, does a setuid(localuid). * If there is an access violation or an error in setting the uid, * an error is returned and the string errmsg is initialized with * an error message that will be sent back to the client. */ status = validate_user(info.aname, info.inst, info.realm, info.username, errmsg); if (status != RKINIT_SUCCESS) { rpc_send_error(errmsg); exit(0); } else rpc_send_success(); /* * If the name of a ticket file was specified, set it; otherwise, * just use the default. */ if (strlen(info.tktfilename)) krb_set_tkt_string(info.tktfilename); /* * Call internal kerberos library routine so that we can supply * our own ticket decryption routine. */ /* * We need a setjmp here because krb_get_in_tkt ignores the * return value of decrypt_tkt. Thus if we want any of its * return values to reach the client, we have to jump out of * the routine. */ if (setjmp(rii.env) == 0) { status = krb_get_in_tkt(info.aname, info.inst, info.realm, info.sname, info.sinst, info.lifetime, NULL, decrypt_tkt, (char *)&rii); if (status) { strcpy(errmsg, krb_err_txt[status]); rpc_send_error(errmsg); } else rpc_send_success(); } else rpc_send_error(errbuf); return(RKINIT_SUCCESS); }
int authorize_socket( int local_socket, std::string &message, char *msg_buf, char **server_name_ptr, char **user_name_ptr, std::string &err_msg) { int rc; bool disconnect_svr = true; int server_port; int auth_type = 0; int svr_sock = -1; int user_pid = 0; int user_sock = 0; int trq_server_addr_len = 0; char *trq_server_addr = NULL; const char *className = "trqauthd"; /* incoming message format is: * trq_system_len|trq_system|trq_port|Validation_type|user_len|user|pid|psock| * message format to pbs_server is: * +2+22+492+user+sock+0 * format from pbs_server is: * +2+2+0+0+1 * outgoing message format is: * #|msg_len|message| * Send response to client here!! * Disconnect message to svr: * +2+22+592+{user_len}{user} * * msg to client in the case of success: * 0|0|| */ if ((rc = parse_request_client(local_socket, server_name_ptr, &server_port, &auth_type, user_name_ptr, &user_pid, &user_sock)) != PBSE_NONE) { if (*server_name_ptr != NULL) free(*server_name_ptr); if (*user_name_ptr != NULL) free(*user_name_ptr); return(rc); } else { int retries = 0; char *server_name = *server_name_ptr; while (retries < MAX_RETRIES) { rc = PBSE_NONE; disconnect_svr = true; if ((rc = validate_user(local_socket, *user_name_ptr, user_pid, msg_buf)) != PBSE_NONE) { log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, __func__, msg_buf); disconnect_svr = false; retries++; usleep(20000); continue; } else if ((rc = get_trq_server_addr(server_name, &trq_server_addr, &trq_server_addr_len)) != PBSE_NONE) { disconnect_svr = false; retries++; usleep(20000); continue; } else if ((svr_sock = socket_get_tcp_priv()) < 0) { rc = PBSE_SOCKET_FAULT; disconnect_svr = false; retries++; usleep(10000); continue; } else if ((rc = socket_connect(svr_sock, trq_server_addr, trq_server_addr_len, server_port, AF_INET, 1, err_msg)) != PBSE_NONE) { /* for now we only need ssh_key and sign_key as dummys */ char *ssh_key = NULL; char *sign_key = NULL; char log_buf[LOCAL_LOG_BUF_SIZE]; validate_server(server_name, server_port, ssh_key, &sign_key); sprintf(log_buf, "Active server is %s", active_pbs_server); log_event(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, __func__, log_buf); disconnect_svr = false; socket_close(svr_sock); retries++; usleep(50000); continue; } else if ((rc = build_request_svr(auth_type, *user_name_ptr, user_sock, message)) != PBSE_NONE) { socket_close(svr_sock); disconnect_svr = false; retries++; usleep(50000); continue; } else if (message.size() <= 0) { socket_close(svr_sock); disconnect_svr = false; rc = PBSE_INTERNAL; retries++; usleep(50000); continue; } else if ((rc = socket_write(svr_sock, message.c_str(), message.size())) != (int)message.size()) { socket_close(svr_sock); disconnect_svr = false; rc = PBSE_SOCKET_WRITE; retries++; usleep(50000); continue; } else if ((rc = parse_response_svr(svr_sock, err_msg)) != PBSE_NONE) { socket_close(svr_sock); disconnect_svr = false; retries++; usleep(50000); continue; } else { /* Success case */ message = "0|0||"; if (debug_mode == TRUE) { fprintf(stderr, "Conn to %s port %d success. Conn %d authorized\n", server_name, server_port, user_sock); } sprintf(msg_buf, "User %s at IP:port %s:%d logged in", *user_name_ptr, server_name, server_port); log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } break; } } if (disconnect_svr == true) { send_svr_disconnect(svr_sock, *user_name_ptr); socket_close(svr_sock); } if (trq_server_addr != NULL) free(trq_server_addr); return(rc); } // END authorize_socket()
void *process_svr_conn( void *sock) { const char *className = "trqauthd"; int rc = PBSE_NONE; char *server_name = NULL; int server_port = 0; char *user_name = NULL; int user_pid = 0; int user_sock = 0; std::string error_string; std::string message; int msg_len = 0; int local_socket = *(int *)sock; char msg_buf[1024]; long long req_type; /* Type of request coming in */ rc = socket_read_num(local_socket, &req_type); if (rc == PBSE_NONE) { switch (req_type) { case TRQ_DOWN_TRQAUTHD: { rc = parse_terminate_request(local_socket, &user_name, &user_pid); if (rc != PBSE_NONE) break; /* root is the only user that can terminate trqauthd */ if (strcmp(user_name, "root")) { rc = PBSE_PERM; break; } rc = validate_user(local_socket, user_name, user_pid, msg_buf); if (rc == PBSE_NONE) { trqauthd_up = false; rc = build_active_server_response(message); } break; } case TRQ_PING_SERVER: case TRQ_GET_ACTIVE_SERVER: { /* rc will get evaluated after the switch statement. */ rc = build_active_server_response(message); break; } case TRQ_VALIDATE_ACTIVE_SERVER: { if ((rc = validate_server(server_name, server_port, NULL, NULL)) != PBSE_NONE) { break; } else if ((rc = build_active_server_response(message)) != PBSE_NONE) { break; } break; } case TRQ_AUTH_CONNECTION: { rc = authorize_socket(local_socket, message, msg_buf, &server_name, &user_name, error_string); break; } default: rc = PBSE_IVALREQ; break; } } else { sprintf(msg_buf, "socket_read_num failed: %d", rc); log_record(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, __func__, msg_buf); } #ifdef UNIT_TEST /* process_svr_conn_rc is used by ./test/trq_auth/test_trq_auth.c to discover the status of unit test calls to process_svr_conn */ process_svr_conn_rc = rc; #endif if (rc != PBSE_NONE) { /* Failure case */ msg_len = 6 + 1 + 6 + 1 + 1; if (error_string.size() == 0) { char *err = pbse_to_txt(rc); if (err != NULL) error_string = err; } msg_len += error_string.size(); message = string_format("%d|%d|%s|",rc, error_string.size(), error_string.c_str()); if (debug_mode == TRUE) { if (server_name != NULL) fprintf(stderr, "Conn to %s port %d Fail. Conn %d not authorized (Err Num %d)\n", server_name, server_port, user_sock, rc); } if (error_string.size() == 0) { if (server_name != NULL) snprintf(msg_buf, sizeof(msg_buf), "User %s at IP:port %s:%d login attempt failed --no message", (user_name) ? user_name : "null", server_name, server_port); } else { snprintf(msg_buf, sizeof(msg_buf), "User %s at IP:port %s:%d login attempt failed --%s", (user_name) ? user_name : "null", (server_name) ? server_name : "null", server_port, error_string.c_str()); } log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } if (message.length() != 0) rc = socket_write(local_socket, message.c_str(), message.length()); if (server_name != NULL) free(server_name); if (user_name != NULL) free(user_name); socket_close(local_socket); free(sock); return(NULL); } /* END process_svr_conn() */
void *process_svr_conn( void *sock) { const char *className = "trqauthd"; int rc = PBSE_NONE; char *server_name = NULL; int server_port = 0; int auth_type = 0; char *user_name = NULL; int user_pid = 0; int user_sock = 0; char *error_msg = NULL; std::string message; int send_len = 0; char *trq_server_addr = NULL; int trq_server_addr_len = 0; int svr_sock = -1; int msg_len = 0; int debug_mark = 0; int local_socket = *(int *)sock; char msg_buf[1024]; long long req_type; /* Type of request coming in */ rc = socket_read_num(local_socket, &req_type); if (rc == PBSE_NONE) { switch (req_type) { case TRQ_DOWN_TRQAUTHD: { rc = parse_terminate_request(local_socket, &user_name, &user_pid); if (rc != PBSE_NONE) break; /* root is the only user that can terminate trqauthd */ if (strcmp(user_name, "root")) { rc = PBSE_PERM; break; } rc = validate_user(local_socket, user_name, user_pid, msg_buf); if (rc == PBSE_NONE) { trqauthd_up = false; rc = build_active_server_response(message); } break; } case TRQ_PING_SERVER: case TRQ_GET_ACTIVE_SERVER: { /* rc will get evaluated after the switch statement. */ rc = build_active_server_response(message); break; } case TRQ_VALIDATE_ACTIVE_SERVER: { if ((rc = validate_server(server_name, server_port, NULL, NULL)) != PBSE_NONE) { break; } else if ((rc = build_active_server_response(message)) != PBSE_NONE) { break; } break; } case TRQ_AUTH_CONNECTION: { int disconnect_svr = TRUE; /* incoming message format is: * trq_system_len|trq_system|trq_port|Validation_type|user_len|user|pid|psock| * message format to pbs_server is: * +2+22+492+user+sock+0 * format from pbs_server is: * +2+2+0+0+1 * outgoing message format is: * #|msg_len|message| * Send response to client here!! * Disconnect message to svr: * +2+22+592+{user_len}{user} * * msg to client in the case of success: * 0|0|| */ if ((rc = parse_request_client(local_socket, &server_name, &server_port, &auth_type, &user_name, &user_pid, &user_sock)) != PBSE_NONE) { disconnect_svr = FALSE; debug_mark = 1; } else { int retries = 0; while (retries < MAX_RETRIES) { rc = PBSE_NONE; disconnect_svr = TRUE; if ((rc = validate_user(local_socket, user_name, user_pid, msg_buf)) != PBSE_NONE) { log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, __func__, msg_buf); disconnect_svr = FALSE; debug_mark = 1; retries++; usleep(20000); continue; } else if ((rc = get_trq_server_addr(server_name, &trq_server_addr, &trq_server_addr_len)) != PBSE_NONE) { disconnect_svr = FALSE; debug_mark = 2; retries++; usleep(20000); continue; } else if ((svr_sock = socket_get_tcp_priv()) < 0) { rc = PBSE_SOCKET_FAULT; disconnect_svr = FALSE; debug_mark = 3; retries++; usleep(10000); continue; } else if ((rc = socket_connect(&svr_sock, trq_server_addr, trq_server_addr_len, server_port, AF_INET, 1, &error_msg)) != PBSE_NONE) { /* for now we only need ssh_key and sign_key as dummys */ char *ssh_key = NULL; char *sign_key = NULL; char log_buf[LOCAL_LOG_BUF_SIZE]; validate_server(server_name, server_port, ssh_key, &sign_key); sprintf(log_buf, "Active server is %s", active_pbs_server); log_event(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, __func__, log_buf); disconnect_svr = FALSE; debug_mark = 4; socket_close(svr_sock); retries++; usleep(50000); continue; } else if ((rc = build_request_svr(auth_type, user_name, user_sock, message)) != PBSE_NONE) { socket_close(svr_sock); disconnect_svr = FALSE; debug_mark = 5; retries++; usleep(50000); continue; } else if ((send_len = message.length()) <= 0) { socket_close(svr_sock); disconnect_svr = FALSE; rc = PBSE_INTERNAL; debug_mark = 6; retries++; usleep(50000); continue; } else if ((rc = socket_write(svr_sock, message.c_str(), send_len)) != send_len) { socket_close(svr_sock); disconnect_svr = FALSE; rc = PBSE_SOCKET_WRITE; debug_mark = 7; retries++; usleep(50000); continue; } else if ((rc = parse_response_svr(svr_sock, &error_msg)) != PBSE_NONE) { socket_close(svr_sock); disconnect_svr = FALSE; debug_mark = 8; retries++; usleep(50000); continue; } else { /* Success case */ message = "0|0||"; if (debug_mode == TRUE) { fprintf(stderr, "Conn to %s port %d success. Conn %d authorized\n", server_name, server_port, user_sock); } snprintf(msg_buf, sizeof(msg_buf), "User %s at IP:port %s:%d logged in", user_name, server_name, server_port); log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } break; } } if (TRUE == disconnect_svr) { send_svr_disconnect(svr_sock, user_name); socket_close(svr_sock); } break; } default: rc = PBSE_IVALREQ; break; } } else { sprintf(msg_buf, "socket_read_num failed: %d", rc); log_record(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, __func__, msg_buf); } #ifdef UNIT_TEST /* process_svr_conn_rc is used by ./test/trq_auth/test_trq_auth.c to discover the status of unit test calls to process_svr_conn */ process_svr_conn_rc = rc; #endif if (rc != PBSE_NONE) { /* Failure case */ msg_len = 6 + 1 + 6 + 1 + 1; if (error_msg == NULL) { char *tmp_err = pbse_to_txt(rc); if (tmp_err != NULL) error_msg = strdup(tmp_err); else error_msg = strdup(""); } msg_len += strlen(error_msg); message = string_format("%d|%d|%s|",rc,strlen(error_msg),error_msg); if (debug_mode == TRUE) { fprintf(stderr, "Conn to %s port %d Fail. Conn %d not authorized (dm = %d, Err Num %d)\n", server_name, server_port, user_sock, debug_mark, rc); } snprintf(msg_buf, sizeof(msg_buf), "User %s at IP:port %s:%d login attempt failed --%s", (user_name) ? user_name : "null", (server_name) ? server_name : "null", server_port, (error_msg) ? error_msg : "null"); log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } if (message.length() != 0) rc = socket_write(local_socket, message.c_str(), message.length()); if (trq_server_addr != NULL) free(trq_server_addr); if (server_name != NULL) free(server_name); if (user_name != NULL) free(user_name); if (error_msg != NULL) free(error_msg); socket_close(local_socket); free(sock); return(NULL); } /* END process_svr_conn() */
void free_user (USER * user) { LIST *list; USERDB *db; whowas_t *who; ip_info_t *info; ASSERT (validate_user (user)); if (ISUSER (user->con) && Servers && !user->con->killed) { /* local user, notify peers of this user's departure */ pass_message_args (user->con, MSG_CLIENT_QUIT, "%s", user->nick); } /* remove this user from any channels they were on */ if (user->channels) { for (list = user->channels; list; list = list->next) { /* notify locally connected clients in the same channel that this user has parted */ part_channel (list->data, user); } list_free (user->channels, 0); } /* check the global hotlist for this user to see if anyone wants notice of this user's departure */ for (list = hashlist_lookup (Hotlist, user->nick); list; list = list->next) { ASSERT (validate_connection (list->data)); send_cmd (list->data, MSG_SERVER_USER_SIGNOFF, "%s", user->nick); } ASSERT (Num_Files >= user->shared); Num_Files -= user->shared; ASSERT (Num_Gigs >= user->libsize); if (Num_Gigs < user->libsize) { log_message ("free_user: bad total lib size: Num_Gigs=%f user->libsize=%u", Num_Gigs, user->libsize); Num_Gigs = user->libsize; /* prevent negative value */ } Num_Gigs -= user->libsize; /* this is in kB */ #ifndef ROUTING_ONLY if (ISUSER (user->con)) { if (user->shared > Local_Files) { log_message ("free_user: local file count error, %s is sharing %d, more than %d", user->nick, user->shared, Local_Files); Local_Files = 0; } else Local_Files -= user->shared; } #endif /* !ROUTING_ONLY */ /* record the log off time */ if ((db = hash_lookup (User_Db, user->nick))) db->lastSeen = global.current_time; /* save info in the who-was table */ who = hash_lookup (Who_Was, user->nick); if (!who) { who = CALLOC (1, sizeof (whowas_t)); if (!who) { OUTOFMEMORY ("free_user"); FREE (user->nick); } else { who->nick = user->nick; hash_add (Who_Was, who->nick, who); } } else FREE (user->nick); if (who) { who->ip = user->ip; who->when = global.current_time; who->server = user->server; who->clientinfo = user->clientinfo; } memset (user->pass, 0, strlen (user->pass)); FREE (user->pass); /* decrement the clone count */ info = hash_lookup (Clones, (void *) user->ip); if (info->users <= 0) { log_message ("free_user: ERROR, info->users <= 0"); info->users = 0; } else info->users--; /* NOTE: user->server is just a ref, not a malloc'd pointer */ memset (user, 0xff, sizeof (USER)); /* catch refs to bad memory */ FREE (user); }