+ Reject_Client(Client, "bad server password");
+ return DISCONNECTED;
+ }
+ return Hello_User_PostAuth(Client);
+#endif
+}
+
+
+#ifdef PAM
+
+/**
+ * Read result of the authenticatior sub-process from pipe
+ *
+ * @param r_fd File descriptor of the pipe.
+ * @param events (ignored IO specification)
+ */
+static void
+cb_Read_Auth_Result(int r_fd, UNUSED short events)
+{
+ CONN_ID conn;
+ CLIENT *client;
+ int result;
+ size_t len;
+ PROC_STAT *proc;
+
+ LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
+ conn = Conn_GetFromProc(r_fd);
+ if (conn == NONE) {
+ /* Ops, none found? Probably the connection has already
+ * been closed!? We'll ignore that ... */
+ io_close(r_fd);
+ LogDebug("Auth: Got callback for unknown connection!?");
+ return;
+ }
+ proc = Conn_GetProcStat(conn);
+ client = Conn_GetClient(conn);
+
+ /* Read result from pipe */
+ len = Proc_Read(proc, &result, sizeof(result));
+ Proc_Close(proc);
+ if (len == 0)
+ return;
+
+ if (len != sizeof(result)) {
+ Log(LOG_CRIT, "Auth: Got malformed result!");
+ Reject_Client(client, "internal error");
+ return;
+ }
+
+ if (result == true) {
+ Client_SetUser(client, Client_OrigUser(client), true);
+ (void)Hello_User_PostAuth(client);
+ } else
+ Reject_Client(client, "bad password");
+}
+
+#endif
+
+
+/**
+ * Reject a client because of wrong password.
+ *
+ * This function is called either when the global server password or a password
+ * checked using PAM has been wrong.
+ *
+ * @param Client The client to reject.
+ */
+static void
+Reject_Client(CLIENT *Client, const char *InternalReason)
+{
+ Log(LOG_ERR,
+ "User \"%s\" rejected (connection %d): %s!",
+ Client_Mask(Client), Client_Conn(Client), InternalReason);
+ Conn_Close(Client_Conn(Client), InternalReason,
+ "Access denied! Bad password?", true);
+}
+
+
+/**
+ * Finish client registration.
+ *
+ * Introduce the new client to the network and send all "hello messages"
+ * to it after authentication has been succeeded.
+ *
+ * @param Client The client logging in.
+ * @returns CONNECTED or DISCONNECTED.
+ */
+static bool
+Hello_User_PostAuth(CLIENT *Client)
+{
+ if (Class_IsMember(CLASS_GLINE, Client)) {
+ Reject_Client(Client, "G-Line'd");
+ return DISCONNECTED;
+ }
+ if (Class_IsMember(CLASS_KLINE, Client)) {
+ Reject_Client(Client, "K-Line'd");