diff -urNw ppp-2.3.5-2/callbackser/Makefile ppp-cb/callbackser/Makefile
--- ppp-2.3.5-2/callbackser/Makefile	Thu Jan  1 01:00:00 1970
+++ ppp-cb/callbackser/Makefile	Tue Jan  5 01:18:14 1999
@@ -0,0 +1,8 @@
+
+callbackser: main.c
+	${CC} ${CFLAGS} -o callbackser $<
+clean:
+	rm -f callbackser *~ *.o
+install:
+	strip callbackser
+	cp callbackser /etc/ppp
diff -urNw ppp-2.3.5-2/callbackser/main.c ppp-cb/callbackser/main.c
--- ppp-2.3.5-2/callbackser/main.c	Thu Jan  1 01:00:00 1970
+++ ppp-cb/callbackser/main.c	Tue Jan  5 01:55:20 1999
@@ -0,0 +1,47 @@
+/*
+ * cbcps - Call Back Configuration Protocol. SERVER
+ * Miro Bobovsky , 7.11.1998 ver2.0
+ * robte s tym co chete - GPL a lubovolny iny vse povoliaci.
+ * toto spusta pppd, a spusti zas pppd ale s aj vytoci cislo.
+*/
+
+/*
+ * Sercurity fixes by s.ballestrero@iname.com
+ * But still not really nice.
+ * GPL, of course.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+main(int argc, char **argv)
+{
+   char *user=argv[2];
+   char *number=argv[3];
+   char ttySx=*(argv[1]+strlen(argv[1])-1);  // vyberie len cislo z ttySx
+   char buff[100]="/etc/ppp/callback_\0 \0\0\0";
+   
+   int i;
+   
+   if(argc!=4) return(-1);
+
+   // let's care a bit about security...
+   for(i=0;i<strlen(number);i++){
+      if( ispunct(*(number+i)) 
+	 || isalpha(*(number+i)) 
+	 || isspace(*(number+i)) ){
+	 *(number+i)=',';	 
+      }else if(!isdigit(*(number+i))){
+	 *(number+i)='\0';
+      }
+   }
+   openlog("callbackser", LOG_PID | LOG_NDELAY, LOG_LOCAL2);
+   buff[strlen(buff)]=ttySx;            //will give callback_1 for modem 1
+   strncat(buff,number,sizeof(buff)-strlen(buff)-1);
+   syslog(LOG_INFO,"%c calling Nr. %s for user %s: %s",ttySx,number,user,buff);
+   system(buff);
+}
+
diff -urNw ppp-2.3.5-2/etc.ppp/callback_1 ppp-cb/etc.ppp/callback_1
--- ppp-2.3.5-2/etc.ppp/callback_1	Thu Jan  1 01:00:00 1970
+++ ppp-cb/etc.ppp/callback_1	Tue Jan  5 01:47:12 1999
@@ -0,0 +1,46 @@
+#!/bin/bash
+logger -i -t pppd "$0: $*"
+# toto bude volane z callbackser. Arg=number kam treba volat.
+# toto sa ma volat /etc/ppp/callback_0 pre modem 0 a 1 pre modem 1 atd.
+# a pouziva cbcp_chat0 (1) a call cbcp0 (1) ... vid nizsie
+number=$*
+
+DEV=ttyS1
+
+umask 077 # nemusia mi do toho pozerat vsetci
+
+CHATFILE="/etc/ppp/peers/cbcp_chat_$DEV"
+
+cat <<EOF >$CHATFILEV
+ABORT BUSY
+ABORT "NO CARRIER"
+ABORT VOICE
+ABORT "NO DIALTONE"
+ABORT "NO ANSWER"
+"" ATZ
+OK "ATDT$number"
+CONNECT \d\c
+EOF
+
+PPP_OPT="115200 modem crtscts nodetach"
+PPP_OPT="$PPP_OPT debug kdebug 5"
+PPP_OPT="$PPP_OPT ms-dns 10.20.0.1"
+PPP_OPT="$PPP_OPT 10.20.0.1:"
+PPP_OPT="$PPP_OPT name pcsash auth +chap -pap"
+PPP_OPT="$PPP_OPT connect '/usr/sbin/chat -v -f $CHATFILE'"
+PPP_OPT="$PPP_OPT idle 90"
+
+i=20 #cakacka 13 seconds je uplne normalne
+while [ $i != 0 ];do
+   if [ ! -s /var/lock/LCK..$DEV ]; then
+      break; # nemam lock file je to dobre
+   fi
+   sleep 1;
+   i=$[$i-1]
+done
+
+# a konecne akcia ...
+logger -i -t pppd "$0: calling on $DEV"
+/usr/sbin/pppd $DEV $PPP_OPT 2>/dev/tty7
+
+       
diff -urNw ppp-2.3.5-2/etc.ppp/callbusers ppp-cb/etc.ppp/callbusers
--- ppp-2.3.5-2/etc.ppp/callbusers	Thu Jan  1 01:00:00 1970
+++ ppp-cb/etc.ppp/callbusers	Tue Jan  5 01:56:08 1999
@@ -0,0 +1,10 @@
+## configuration file for pppd Callback Server
+## ludia ktory mozu mat callback (bude im ponuknute volit cislo)
+## syntax : username!D(irect)!U(serConfig)!A(dminConfig)!Number! 
+## examples: 
+## freelogin!D!U!!!  = call back or not, at caller's choice
+## forcedlogin!!!A!274! = only call back to 274.
+## directlogin!D!!!!    = don't allow any callback.
+## Please Note:
+## with win95/98 clients the combination  U!A defaults back to Admin.
+## (Bill's fault, as usual :-)
diff -urNw ppp-2.3.5-2/pppd/Makefile.linux ppp-cb/pppd/Makefile.linux
--- ppp-2.3.5-2/pppd/Makefile.linux	Mon Dec 28 18:28:15 1998
+++ ppp-cb/pppd/Makefile.linux	Tue Jan  5 01:20:44 1999
@@ -43,8 +43,8 @@
 endif
 
 
-HAS_SHADOW=y
-#USE_PAM=y
+#HAS_SHADOW=y
+USE_PAM=y
 
 INCLUDE_DIRS= -I../include
 
diff -urNw ppp-2.3.5-2/pppd/auth.c ppp-cb/pppd/auth.c
--- ppp-2.3.5-2/pppd/auth.c	Thu Mar 26 05:46:00 1998
+++ ppp-cb/pppd/auth.c	Tue Jan  5 01:52:20 1999
@@ -127,7 +127,10 @@
 
 /* Prototypes for procedures local to this file. */
 
-static void network_phase __P((int));
+void network_phase __P((int));
+#ifdef CBCP_SUPPORT
+static void callback_phase __P((int));
+#endif
 static void check_idle __P((void *));
 static void connect_time_expired __P((void *));
 static int  plogin __P((char *, char *, char **, int *));
@@ -256,14 +259,19 @@
     }
     auth_pending[unit] = auth;
 
+#ifdef CBCP_SUPPORT
+   if (!auth)  // ak neni auth tak priamo bez chap/pap ideme.
+     callback_phase(unit);
+#else
     if (!auth)
 	network_phase(unit);
+#endif
 }
 
 /*
  * Proceed to the network phase.
  */
-static void
+void
 network_phase(unit)
     int unit;
 {
@@ -271,6 +279,8 @@
     struct protent *protp;
     lcp_options *go = &lcp_gotoptions[unit];
 
+    syslog(LOG_DEBUG, "network_phase");
+
     /*
      * If the peer had to authenticate, run the auth-up script now.
      */
@@ -283,7 +293,8 @@
     /*
      * If we negotiated callback, do it now.
      */
-    if (go->neg_cbcp) {
+   // maybe only for Callback client ??
+    if (go->neg_cbcp && cbcp_protent.enabled_flag==1) {
 	phase = PHASE_CALLBACK;
 	(*cbcp_protent.open)(unit);
 	return;
@@ -308,6 +319,44 @@
 	lcp_close(0, "No network protocols running");
 }
 
+#ifdef CBCP_SUPPORT
+static void
+callback_phase(int unit)   //faza callbacku ..  treba pozret ci sa moze obist.
+{
+   cbcp_state *us = &cbcp[unit];
+   lcp_options *wo=&lcp_wantoptions[unit];
+   lcp_options *go=&lcp_gotoptions[unit];
+   
+   syslog(LOG_DEBUG, "callback_phase");
+   
+   if(!cbcp_protent.enabled_flag&2) 
+     {
+	network_phase(unit);
+	return;
+     } // neni cb switch
+   syslog(LOG_DEBUG, "callback_phase enabled");
+   // to sa pouzilo napr pri spatnom volani.
+   if(!wo->neg_cbcp || !go->neg_cbcp) 
+     {	//asi by stacilo len go pozerat.
+	if(us->us_allowdirect)      // smie sa obist nevylicitovanim ... inac je to podfuk.
+	  {
+	     syslog(LOG_DEBUG, "callback_phase allowdirect");
+	     network_phase(unit);
+	     // pri licitacii alebo cez opt cb nepovolena
+	  } else {
+	     syslog(LOG_DEBUG, "callback_phase disallowdirect");
+	     syslog(LOG_WARNING, "CBCP Nedovoleny pokus obist cb zlou licitaciu");
+	     auth_peer_fail(unit,PPP_CBCP);
+	     return;
+	  }
+     } else {
+	syslog(LOG_DEBUG, "callback_phase ready to open");
+	phase = PHASE_CALLBACK;
+	(*cbcp_protent.open)(unit);        // toto ho prinuti poslat vyzvu ..
+     }
+}
+#endif
+
 /*
  * The peer has failed to authenticate himself using `protocol'.
  */
@@ -359,7 +408,14 @@
      * proceed to the network (or callback) phase.
      */
     if ((auth_pending[unit] &= ~bit) == 0)
+     {
+#ifdef CBCP_SUPPORT
+      // syslog(LOG_DEBUG," bbo po auth_peer_success");
+       callback_phase(unit);
+#else
         network_phase(unit);
+#endif
+    }
 }
 
 /*
@@ -1107,6 +1163,15 @@
     addrs = NULL;
     secbuf[0] = 0;
 
+#ifdef CBCP_SUPPORT
+   if(cbcp_protent.enabled_flag&2) 
+     {
+    BCOPY(client,cbcpuser,strlen(client)>19 ? 19: strlen(client));
+    cbcpuser[19]=0;
+    if (cbcp_auth(&cbcp[unit],cbcpuser)<1) return 0;
+     } // no callbacksrv switch
+
+#endif
     f = fopen(filename, "r");
     if (f == NULL) {
 	syslog(LOG_ERR, "Can't open chap secret file %s: %m", filename);
diff -urNw ppp-2.3.5-2/pppd/cbcp.c ppp-cb/pppd/cbcp.c
--- ppp-2.3.5-2/pppd/cbcp.c	Wed Apr 30 07:50:26 1997
+++ ppp-cb/pppd/cbcp.c	Tue Jan  5 02:27:52 1999
@@ -18,6 +18,25 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+/*
+ * cbcps - Call Back Configuration Protocol. SERVER
+ * Miro Bobovsky , 7.11.1998 ver2.0
+ * robte s tym co chete - GPL a lubovolny iny vse povoliaci.
+ * ocakavam za pppd prepinac auth +chap -pap cb ip:ip
+ * ocakavam subor /etc/ppp/callbusers kde su user (nestaci chap-s)
+ * s patricnym sytaxom name!D!U!A!number!.
+ * snazim sa spustit /etc/ppp/callbackser pre volanie. (pppd chat).
+ */
+
+/*
+ * Merge by Sergio Ballestrero <s.ballestrero@iname.com>
+ * i had quite some problems since i can't read Slovakian...
+ * I feel there could still be incoherencies, and i haven't 
+ * checked yet, so i could have broken the CallBack client.
+ * Anyway, whatever the result might be, it's CopyLefted (L) 1999
+ */
+
+       
 #ifndef lint
 static char rcsid[] = "$Id: cbcp.c,v 1.2 1997/04/30 05:50:26 paulus Exp $";
 #endif
@@ -34,11 +53,13 @@
 #include "lcp.h"
 #include "ipcp.h"
 
+
 /*
  * Protocol entry points.
  */
 static void cbcp_init      __P((int unit));
 static void cbcp_open      __P((int unit));
+static void cbcp_close     __P((int unit, char *reason));
 static void cbcp_lowerup   __P((int unit));
 static void cbcp_input     __P((int unit, u_char *pkt, int len));
 static void cbcp_protrej   __P((int unit));
@@ -54,7 +75,7 @@
     cbcp_lowerup,
     NULL,
     cbcp_open,
-    NULL,
+    cbcp_close,
     cbcp_printpkt,
     NULL,
     0,
@@ -66,13 +87,28 @@
 
 cbcp_state cbcp[NUM_PPP];	
 
-/* internal prototypes */
+char cbcpuser[20];
+char cbcp_adminn[]="********************";
+
+char *cbcp_codenames[] = {
+    "Request", "Response", "Ack"
+};
+
+char *cbcp_optionnames[] = {
+    "NoCallback",
+    "UserDefined",
+    "AdminDefined",
+    "List"
+};
 
+/* internal prototypes */
 static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
 static void cbcp_resp __P((cbcp_state *us));
 static void cbcp_up __P((cbcp_state *us));
 static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
 static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
+static void cbcp_recvresp(cbcp_state *us, char *pckt, int len);
+static void cbcp_sendack(cbcp_state *us,u_char type,u_char delay );
 
 /* init state */
 static void
@@ -81,8 +117,16 @@
 {
     cbcp_state *us;
 
+   LCPDEBUG((LOG_DEBUG, "cbcp_init"));
+
     us = &cbcp[iface];
     memset(us, 0, sizeof(cbcp_state));
+   cbcpuser[0]=0;
+   us->us_allowdirect = 0;
+   us->us_userconf = 0;
+   us->us_adminconf = 0;
+   us->us_id = 0;
+   cbcp_adminn[0]=0;
     us->us_unit = iface;
     us->us_type |= (1 << CB_CONF_NO);
 }
@@ -94,21 +138,62 @@
 {
     cbcp_state *us = &cbcp[iface];
 
-    syslog(LOG_DEBUG, "cbcp_lowerup");
-    syslog(LOG_DEBUG, "want: %d", us->us_type);
+    LCPDEBUG((LOG_DEBUG, "cbcp_lowerup"));
+    LCPDEBUG((LOG_DEBUG, "want: %s", cbcp_optionnames[us->us_type]));
 
     if (us->us_type == CB_CONF_USER)
-        syslog(LOG_DEBUG, "phone no: %s", us->us_number);
+        LCPDEBUG((LOG_DEBUG, "phone no: %s", us->us_number));
 }
 
 static void
 cbcp_open(unit)
     int unit;
 {
-    syslog(LOG_DEBUG, "cbcp_open");
+    //z auth -- start cbcp communication
+    u_char buf[256];
+    u_char *bufp = buf;
+    u_char *outp;
+    int outlen;
+    cbcp_state *us = &cbcp[unit];
+
+   
+   if (us->us_id==1) {
+    LCPDEBUG((LOG_DEBUG, "cbcp_server_open done already"));
+      return;
+   };
+   
+    LCPDEBUG((LOG_DEBUG, "cbcp_server_open"));
+   
+    us->us_id = 1;
+    outp = outpacket_buf;
+    outlen=4;                //header? (hlavicka)
+    if(us->us_allowdirect) { 
+       outlen+=2;
+       PUTCHAR(CB_CONF_NO, bufp);
+       PUTCHAR(2 , bufp);
+    }
+    if(us->us_userconf) { 
+       outlen+=5;
+       PUTCHAR(CB_CONF_USER, bufp);
+       PUTCHAR(5 , bufp); //typ,dlzka
+       PUTCHAR(0, bufp);
+       PUTCHAR(1, bufp);
+       PUTCHAR(0, bufp);//delay,atyp,Number
+    } 
+    if(us->us_adminconf) {
+       outlen+=2;
+       PUTCHAR(CB_CONF_ADMIN, bufp);
+       PUTCHAR(2 , bufp);
+    }
+    MAKEHEADER(outp, PPP_CBCP);  // a dorobim paket , dlzky a ...
+    PUTCHAR(CBCP_REQ, outp);  // prikaz
+    PUTCHAR(us->us_id,outp); //id
+    PUTSHORT(outlen, outp);       // IBAZE WINNT posiela to kazde 2 sek.
+    BCOPY(buf, outp, outlen-4);   // s novym id a ja len raz .. ale ide.
+    output(1, outpacket_buf, outlen + PPP_HDRLEN);
 }
 
-/* process an incomming packet */
+/* process an incoming packet */
 static void
 cbcp_input(unit, inpacket, pktlen)
     int unit;
@@ -121,6 +206,8 @@
 
     cbcp_state *us = &cbcp[unit];
 
+   LCPDEBUG((LOG_DEBUG, "cbcp_input"));
+   
     inp = inpacket;
 
     if (pktlen < CBCP_MINLEN) {
@@ -143,19 +230,23 @@
  
     switch(code) {
     case CBCP_REQ:
+        LCPDEBUG((LOG_DEBUG, "CBCP_REQ received"));
         us->us_id = id;
 	cbcp_recvreq(us, inp, len);
 	break;
 
     case CBCP_RESP:
-	syslog(LOG_DEBUG, "CBCP_RESP received");
+       LCPDEBUG((LOG_DEBUG, "CBCP_RESP received"));
+       if (id != us->us_id)
+	 syslog(LOG_ERR," id does not match: expected %d recv %d",
+		us->us_id,id);
+       cbcp_recvresp(us,inp,len);
 	break;
 
     case CBCP_ACK:
 	if (id != us->us_id)
-	    syslog(LOG_DEBUG, "id doesn't match: expected %d recv %d",
-		   us->us_id, id);
-
+	 LCPDEBUG((LOG_DEBUG, "id doesn't match: expected %d recv %d",
+		us->us_id, id));
 	cbcp_recvack(us, inp, len);
 	break;
 
@@ -165,20 +256,12 @@
 }
 
 /* protocol was rejected by foe */
-void cbcp_protrej(int iface)
+void cbcp_protrej(iface)
+int iface;
 {
+      LCPDEBUG((LOG_DEBUG,"cbcp_protrej"));
 }
 
-char *cbcp_codenames[] = {
-    "Request", "Response", "Ack"
-};
-
-char *cbcp_optionnames[] = {
-    "NoCallback",
-    "UserDefined",
-    "AdminDefined",
-    "List"
-};
 
 /* pretty print a packet */
 static int
@@ -272,7 +355,7 @@
     address[0] = 0;
 
     while (len) {
-        syslog(LOG_DEBUG, "length: %d", len);
+        LCPDEBUG((LOG_DEBUG, "cbcp_recvreq length: %d", len));
 
 	GETCHAR(type, pckt);
 	GETCHAR(opt_len, pckt);
@@ -284,22 +367,22 @@
 
 	switch(type) {
 	case CB_CONF_NO:
-	    syslog(LOG_DEBUG, "no callback allowed");
+	    LCPDEBUG((LOG_DEBUG, "cbcp_recvreq: no callback allowed"));
 	    break;
 
 	case CB_CONF_USER:
-	    syslog(LOG_DEBUG, "user callback allowed");
+	    LCPDEBUG((LOG_DEBUG, "cbcp_recvreq: user callback allowed"));
 	    if (opt_len > 4) {
 	        GETCHAR(addr_type, pckt);
 		memcpy(address, pckt, opt_len - 4);
 		address[opt_len - 4] = 0;
 		if (address[0])
-		    syslog(LOG_DEBUG, "address: %s", address);
+		    LCPDEBUG((LOG_DEBUG, "address: %s", address));
 	    }
 	    break;
 
 	case CB_CONF_ADMIN:
-	    syslog(LOG_DEBUG, "user admin defined allowed");
+	    LCPDEBUG((LOG_DEBUG, "cbcp_recvreq: user admin defined allowed"));
 	    break;
 
 	case CB_CONF_LIST:
@@ -321,7 +404,7 @@
     int len = 0;
 
     cb_type = us->us_allowed & us->us_type;
-    syslog(LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type);
+    LCPDEBUG((LOG_DEBUG, "cbcp_resp cb_type=%d", cb_type));
 
 #if 0
     if (!cb_type)
@@ -329,7 +412,7 @@
 #endif
 
     if (cb_type & ( 1 << CB_CONF_USER ) ) {
-	syslog(LOG_DEBUG, "cbcp_resp CONF_USER");
+	LCPDEBUG((LOG_DEBUG, "cbcp_resp CONF_USER"));
 	PUTCHAR(CB_CONF_USER, bufp);
 	len = 3 + 1 + strlen(us->us_number) + 1;
 	PUTCHAR(len , bufp);
@@ -341,7 +424,7 @@
     }
 
     if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
-	syslog(LOG_DEBUG, "cbcp_resp CONF_ADMIN");
+	LCPDEBUG((LOG_DEBUG, "cbcp_resp CONF_ADMIN"));
         PUTCHAR(CB_CONF_ADMIN, bufp);
 	len = 3 + 1;
 	PUTCHAR(len , bufp);
@@ -352,7 +435,7 @@
     }
 
     if (cb_type & ( 1 << CB_CONF_NO ) ) {
-        syslog(LOG_DEBUG, "cbcp_resp CONF_NO");
+        LCPDEBUG((LOG_DEBUG, "cbcp_resp CONF_NO"));
 	PUTCHAR(CB_CONF_NO, bufp);
 	len = 3;
 	PUTCHAR(len , bufp);
@@ -373,6 +456,9 @@
     u_char *outp;
     int outlen;
 
+   LCPDEBUG((LOG_DEBUG, "cbcp_send"));
+
+   
     outp = outpacket_buf;
 
     outlen = 4 + len;
@@ -399,6 +485,9 @@
     int opt_len;
     char address[256];
 
+   LCPDEBUG((LOG_DEBUG, "cbcp_recvack"));
+
+   
     if (len) {
         GETCHAR(type, pckt);
 	GETCHAR(opt_len, pckt);
@@ -411,7 +500,7 @@
 	    memcpy(address, pckt, opt_len - 4);
 	    address[opt_len - 4] = 0;
 	    if (address[0])
-	        syslog(LOG_DEBUG, "peer will call: %s", address);
+	        LCPDEBUG((LOG_DEBUG, "peer will call: %s", address));
 	}
     }
 
@@ -428,3 +517,220 @@
     persist = 0;
     lcp_close(0, "Call me back, please");
 }
+
+static void cbcp_close(int unit, char *reason)
+{
+    LCPDEBUG((LOG_DEBUG, "cbcp_server_close because %s",reason));
+}
+
+
+static void cbcp_recvresp(cbcp_state *us, char *pckt, int len)
+{
+   u_char type, delay=0, addr_type;
+   int opt_len,dlzka;
+
+   
+   if (len<2) {  
+      syslog(LOG_ERR, "CBCP recvresp: packet too short %d",len);
+      phase=PHASE_TERMINATE; 
+      return;
+   }
+   
+   GETCHAR(type, pckt);
+   GETCHAR(opt_len, pckt);
+   
+   if (opt_len > 2)
+     GETCHAR(delay, pckt);
+   
+   LCPDEBUG((LOG_DEBUG,"cbcp_server_recvresp type=%s delay=%d",
+	  cbcp_optionnames[type-1],delay));
+   
+   switch(type) {
+    case CB_CONF_NO:
+      if(!us->us_allowdirect)
+	{
+	   syslog(LOG_ERR, "CBCP Error: requested direct "
+		  "connection is not allowed");
+           phase=PHASE_TERMINATE; 
+	   return;
+	}
+      break;
+    case CB_CONF_ADMIN:
+      if(!us->us_adminconf)
+	{
+	   syslog(LOG_ERR, "CBCP Error: requested "
+		  "admin-configured callback is not allowed");
+           phase=PHASE_TERMINATE; 
+	   return;
+	}
+      break;
+    default:   // t.j. asi voli ale pozreme.
+      if(!us->us_userconf)
+	{
+	   syslog(LOG_ERR, "CBCP Error: requested "
+		  "user-configured callback is not allowed");
+           phase=PHASE_TERMINATE; 
+	   return;
+	}
+      if(opt_len>4) {
+	 GETCHAR(addr_type, pckt);
+	 dlzka=opt_len - 4<20?opt_len - 4:19;
+	 memcpy(cbcp_adminn, pckt, dlzka);
+	 cbcp_adminn[dlzka]=0;
+	 LCPDEBUG((LOG_DEBUG, "Callback number: %s", cbcp_adminn));
+      }
+   }
+   cbcp_sendack(us,type,delay);      
+}
+
+
+
+void cbcp_sendack( cbcp_state *us,u_char type,u_char delay )
+{
+   u_char buf[256];
+   u_char *bufp = buf;
+   int len = 0;
+   u_char *outp;
+   int outlen;
+
+   LCPDEBUG((LOG_DEBUG, "cbcp_server_sendack"));
+
+   outp = outpacket_buf;
+   switch(type) {
+    case CB_CONF_NO:
+      len=2;
+      PUTCHAR(CB_CONF_NO, bufp);
+      PUTCHAR(len , bufp);
+      break;
+    case CB_CONF_USER:
+      len=strlen(cbcp_adminn)+5;
+      PUTCHAR(CB_CONF_USER, bufp);
+      PUTCHAR(len, bufp);
+      PUTCHAR(delay, bufp);
+      PUTCHAR(1, bufp);
+      BCOPY(cbcp_adminn,bufp,len-5);
+      bufp+=len-5;
+      PUTCHAR(0, bufp);
+      break;
+    case CB_CONF_ADMIN:
+      len=3;
+      PUTCHAR(CB_CONF_ADMIN,bufp);
+      PUTCHAR(len,bufp);
+      PUTCHAR(delay,bufp);
+      break;
+    default:
+      syslog(LOG_ERR, "CBCP unkown callback request type");
+      phase=PHASE_TERMINATE;
+      return;
+      break;
+   }
+   outlen = 4 + len;
+   MAKEHEADER(outp, PPP_CBCP);
+   PUTCHAR(CBCP_ACK, outp);
+   PUTCHAR(us->us_id,outp);
+   PUTSHORT(outlen, outp);
+   BCOPY(buf, outp, len);
+   output(1, outpacket_buf, outlen + PPP_HDRLEN);
+   network_phase(us->us_unit);
+   
+   if(type==CB_CONF_ADMIN || type==CB_CONF_USER){ 
+      //spustenie programu na volanie
+      char *argv[4];
+      argv[0] = CBprog;         // progam
+      argv[1] = devnam;		// /dev/ttyS?
+      argv[2] = cbcpuser;       // ID
+      argv[3] = cbcp_adminn;    // number
+      argv[4] = NULL;
+      run_program(argv[0], argv, 0);
+   }
+}
+
+
+//int akysposobppp(char *name)
+int cbcp_auth(cbcp_state *us,char *name)
+{
+   FILE *fp;
+   char *a,*b;
+   char line[81];
+
+   LCPDEBUG((LOG_DEBUG, "cbcp_server_auth"));
+
+   
+   us->us_allowdirect = 0;
+   us->us_userconf = 0;
+   us->us_adminconf = 0;
+   cbcp_adminn[0]=0;
+   if(strlen(name)<2) {
+      syslog(LOG_ERR,"CBCP - name too short"); 
+      return 0;
+   }
+   if((fp=fopen(CBusers,"r"))==NULL) {
+	syslog(LOG_ERR,"CBCP could not open "CBusers);
+	return 0;
+     }
+   while(fgets(line,80,fp)!=NULL){
+      if( *line=='#' ) 
+	continue;
+      if( (a=strchr(line,'!'))!=NULL ) 
+	*(a++)=0;
+      if(strcmp(line,name)==0) {
+	 if( strlen(a)<5 ) {
+	    syslog(LOG_ERR,"CBCP syntax error in "CBusers);
+/*	    us->us_allowdirect=1;*/
+/* no, if the syntax is wrong, i don't think we should let him in */
+	 } else {
+	    if( *(a++)=='D') {
+	       a++;
+	       us->us_allowdirect=1;
+	    }
+	    if( *(a++)=='U') {
+	       a++;
+	       us->us_userconf=1;
+	    }
+	    if( *(a++)=='A') {
+	       a++;
+	       if( (b=strchr(a,'!'))!=NULL ) 
+		 {
+		    *b=0;
+		    strncpy(cbcp_adminn,a,20);
+		    us->us_adminconf=1;
+		 }
+	    }
+	 }
+	 fclose(fp); 
+	 syslog(LOG_INFO,"CBCP name:%s P:%d V:%d A:%d number:[%s]\n",
+		name,
+		us->us_allowdirect,
+		us->us_userconf,
+		us->us_adminconf,
+		cbcp_adminn);
+		/*
+		 * I think that if no mode is allowed, we 
+		 * should consider the check failed
+		 */
+	 return us->us_allowdirect|us->us_userconf|us->us_adminconf;
+      }
+   }
+   fclose(fp);
+   
+   /* 
+    * if no name was found, then IMHO we should allow the user 
+    * to connect like no callback exists.
+    * If you want to exclude some logins from connection,
+    * there are better solutions - PAM, for example.
+    * you can still put an explicit username!!!!! in callbusers
+    */
+   
+   syslog(LOG_ERR,"CBCP neni v "CBusers);
+   us->us_allowdirect=1;
+   syslog(LOG_INFO,"CBCP name:%s P:%d V:%d A:%d number:[%s]\n",
+	  name,
+	  us->us_allowdirect,
+	  us->us_userconf,
+	  us->us_adminconf,
+	  cbcp_adminn);
+   return 1;
+}
+
+
+
diff -urNw ppp-2.3.5-2/pppd/cbcp.h ppp-cb/pppd/cbcp.h
--- ppp-2.3.5-2/pppd/cbcp.h	Thu Sep 19 06:45:47 1996
+++ ppp-cb/pppd/cbcp.h	Tue Jan  5 01:28:01 1999
@@ -1,17 +1,47 @@
 #ifndef CBCP_H
 #define CBCP_H
 
+
+/*
+ * cbcps - Call Back Configuration Protocol. SERVER
+ * Miro Bobovsky , 7.11.1998 ver2.0
+ * robte s tym co chete - GPL a lubovolny iny vse povoliaci.
+ */
+
+/*
+ * Merge by Sergio Ballestrero <s.ballestrero@iname.com>
+ * i had quite some problems since i can't read Slovakian...
+ * Anyway, whatever the result might be, it's CopyLefted (L) 1999
+ */
+    
+
 typedef struct cbcp_state {
     int    us_unit;	/* Interface unit number */
     u_char us_id;		/* Current id */
     u_char us_allowed;
     int    us_type;
     char   *us_number;    /* Telefone Number */
+    char   *us_numbertocall;
+    u_char us_userconf;
+    u_char us_adminconf;
+    u_char us_allowdirect;
 } cbcp_state;
 
 extern cbcp_state cbcp[];
 
 extern struct protent cbcp_protent;
+
+#define CBusers "/etc/ppp/callbusers"
+#define CBprog  "/etc/ppp/callbackser"
+
+extern char cbcpuser[];
+//extern int cbcp_volit;		// ci sme si uzer volit callb cislo
+//extern int cbcp_admin;		// cislo zadava admin a user ho ani nevie.
+//extern int cbcp_priamo;	// smie ist bez callbacku.
+extern char cbcp_adminn[];	// cislo (ad admina alebo od usera ak moze.
+int cbcp_auth(cbcp_state *us, char *name);	// fcia co pozera callbusers a nastavi param.
+
+extern void network_phase __P((int));
 
 #define CBCP_MINLEN 4
 
diff -urNw ppp-2.3.5-2/pppd/chap.c ppp-cb/pppd/chap.c
--- ppp-2.3.5-2/pppd/chap.c	Thu Nov 27 07:07:48 1997
+++ ppp-cb/pppd/chap.c	Fri Dec 18 23:02:11 1998
@@ -579,6 +579,7 @@
     ChapSendStatus(cstate, code);
 
     if (code == CHAP_SUCCESS) {
+        syslog(LOG_NOTICE, "CHAP %s login ok:%s",devnam,rhostname);
 	old_state = cstate->serverstate;
 	cstate->serverstate = CHAPSS_OPEN;
 	if (old_state == CHAPSS_INITIAL_CHAL) {
@@ -590,6 +591,7 @@
 	       rhostname);
 
     } else {
+        syslog(LOG_NOTICE, "CHAP %s login error:%s",devnam,rhostname);
 	syslog(LOG_ERR, "CHAP peer authentication failed for remote host %s",
 	       rhostname);
 	cstate->serverstate = CHAPSS_BADAUTH;
diff -urNw ppp-2.3.5-2/pppd/lcp.c ppp-cb/pppd/lcp.c
--- ppp-2.3.5-2/pppd/lcp.c	Thu Nov 27 07:08:44 1997
+++ ppp-cb/pppd/lcp.c	Mon Jan  4 19:40:24 1999
@@ -1398,7 +1398,17 @@
 	    }
 	    ho->neg_accompression = 1;
 	    break;
-
+#ifdef CBCP_SUPPORT	    
+	case  CI_CALLBACK:   // on mi ponuka cbcp a co ja na to.
+	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd Bbo callback"));
+	    if (!ao->neg_cbcp ||
+		cilen != CILEN_CBCP) {
+		orc = CONFREJ;
+		break;
+	    }
+            ho->neg_cbcp = 1;
+           break;
+#endif
 	default:
 	    LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd unknown option %d",
 		      citype));
diff -urNw ppp-2.3.5-2/pppd/options.c ppp-cb/pppd/options.c
--- ppp-2.3.5-2/pppd/options.c	Thu Mar 26 05:46:07 1998
+++ ppp-cb/pppd/options.c	Tue Jan  5 01:51:21 1999
@@ -160,6 +160,7 @@
 static int setmtu __P((char **));
 #ifdef CBCP_SUPPORT
 static int setcbcp __P((char **));
+static int setcbcps __P((char **));
 #endif
 static int nomru __P((char **));
 static int nopcomp __P((char **));
@@ -318,6 +319,7 @@
     {"mru", 1, setmru},		/* Set MRU value for negotiation */
     {"mtu", 1, setmtu},		/* Set our MTU */
 #ifdef CBCP_SUPPORT
+    {"callbacksrv", 0, setcbcps},
     {"callback", 1, setcbcp},	/* Ask for callback */
 #endif
     {"netmask", 1, setnetmask},	/* set netmask */
@@ -1290,6 +1292,18 @@
 }
 
 #ifdef CBCP_SUPPORT
+static int
+setcbcps(argv)
+    char **argv;
+{
+    lcp_wantoptions[0].neg_cbcp = 1;   // poslem licitaciu na cbcp
+    lcp_allowoptions[0].neg_cbcp = 1;  // ak bude pytat cbcp potvrdim.
+    cbcp_protent.enabled_flag = 2;     // povolovanie protokolu po novom.
+    // i need to differentiate server and client callback
+    // IMHO, CBCP client and server are mutually exclusive
+    // so the tests should be cbcp_protent.enabled_flag==2 for SERVER
+    return(1);
+}
 static int
 setcbcp(argv)
     char **argv;
