Index: ppp/callbackser/.cvsignore
diff -u /dev/null ppp/callbackser/.cvsignore:1.1
--- /dev/null	Mon Dec 10 22:45:53 2001
+++ ppp/callbackser/.cvsignore	Mon Dec 10 02:44:02 2001
@@ -0,0 +1 @@
+callbackser
Index: ppp/callbackser/Makefile
diff -u /dev/null ppp/callbackser/Makefile:1.1
--- /dev/null	Mon Dec 10 22:45:53 2001
+++ ppp/callbackser/Makefile	Sat Dec  8 00:55:56 2001
@@ -0,0 +1,8 @@
+
+callbackser: main.c
+	${CC} ${CFLAGS} -o callbackser $<
+clean:
+	rm -f callbackser *~ *.o
+install:
+	strip callbackser
+	cp callbackser /etc/ppp
Index: ppp/callbackser/main.c
diff -u /dev/null ppp/callbackser/main.c:1.2
--- /dev/null	Mon Dec 10 22:45:53 2001
+++ ppp/callbackser/main.c	Mon Dec 10 02:38:36 2001
@@ -0,0 +1,48 @@
+/*
+ * 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);
+   if (!fork())
+   	system(buff);
+}
+
Index: ppp/etc.ppp/callback_1
diff -u /dev/null ppp/etc.ppp/callback_1:1.2
--- /dev/null	Mon Dec 10 22:45:53 2001
+++ ppp/etc.ppp/callback_1	Mon Dec 10 03:45:36 2001
@@ -0,0 +1,55 @@
+#!/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"
+EXECFILE="/etc/ppp/peers/cbcp_exec_$DEV"
+
+cat <<EOF >$EXECFILE
+#!/bin/sh
+/usr/sbin/chat -v -f $CHATFILE
+EOF
+
+chmod u+x $EXECFILE
+
+cat <<EOF >$CHATFILE
+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"
+PPP_OPT="$PPP_OPT debug"
+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 $EXECFILE"
+
+i=5 #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
+
+sleep 5;
+
+# a konecne akcia ...
+logger -i -t pppd "$0: calling on $DEV"
+/usr/sbin/pppd $DEV $PPP_OPT 2>/dev/tty7
+
+       
Index: ppp/etc.ppp/callbusers
diff -u /dev/null ppp/etc.ppp/callbusers:1.1
--- /dev/null	Mon Dec 10 22:45:53 2001
+++ ppp/etc.ppp/callbusers	Sat Dec  8 00:55:56 2001
@@ -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 :-)
Index: ppp/pppd/Makefile.bsd
diff -u ppp/pppd/Makefile.bsd:1.1.1.1 ppp/pppd/Makefile.bsd:1.2
--- ppp/pppd/Makefile.bsd:1.1.1.1	Sat Dec  8 00:32:53 2001
+++ ppp/pppd/Makefile.bsd	Sat Dec  8 00:49:48 2001
@@ -4,11 +4,11 @@
 # -D_BITYPES is for FreeBSD, which doesn't define anything to
 # tell us that u_int32_t gets defined if <sys/types.h> is included.
 # Remove for older *BSD systems for which this isn't true.
-CFLAGS+= -g -I../include -DHAVE_PATHS_H -D_BITYPES
+CFLAGS+= -g -I../include -DHAVE_PATHS_H -D_BITYPES -DCBCP_SUPPORT
 
 PROG=	pppd
 SRCS=	main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
-	demand.c auth.c options.c utils.c sys-bsd.c
+	demand.c auth.c options.c utils.c sys-bsd.c cbcp.c
 MAN=	pppd.cat8
 MAN8=	pppd.8
 BINMODE=4555
Index: ppp/pppd/Makefile.linux
diff -u ppp/pppd/Makefile.linux:1.1.1.1 ppp/pppd/Makefile.linux:1.5
--- ppp/pppd/Makefile.linux:1.1.1.1	Sat Dec  8 00:32:53 2001
+++ ppp/pppd/Makefile.linux	Mon Dec 10 02:39:35 2001
@@ -15,7 +15,7 @@
 MANPAGES = pppd.8
 PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
 	   auth.o options.o demand.o utils.o sys-linux.o ipxcp.o multilink.o \
-	   tdb.o tty.o
+	   tdb.o tty.o cbcp.o
 
 all: pppd
 
@@ -56,7 +56,7 @@
 
 INCLUDE_DIRS= -I../include
 
-COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP
+COMPILE_FLAGS= -D_linux_=1 -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MULTILINK -DHAVE_MMAP -DCBCP_SUPPORT
 
 CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS)
 
Index: ppp/pppd/auth.c
diff -u ppp/pppd/auth.c:1.1.1.1 ppp/pppd/auth.c:1.4
--- ppp/pppd/auth.c:1.1.1.1	Sat Dec  8 00:32:53 2001
+++ ppp/pppd/auth.c	Mon Dec 10 02:41:02 2001
@@ -184,7 +184,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 **));
@@ -505,19 +508,26 @@
     }
     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;
 {
     lcp_options *go = &lcp_gotoptions[unit];
 
+    dbglog ("network_phase");
+
     /*
      * If the peer had to authenticate, run the auth-up script now.
      */
@@ -534,7 +544,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) {
 	new_phase(PHASE_CALLBACK);
 	(*cbcp_protent.open)(unit);
 	return;
@@ -587,6 +598,45 @@
 	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];
+   
+   dbglog ("callback_phase");
+   
+   if(!(cbcp_protent.enabled_flag&2)) 
+     {
+	network_phase(unit);
+	return;
+     } // neni cb switch
+   dbglog ("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.
+	  {
+	     dbglog ("callback_phase allowdirect");
+	     network_phase(unit);
+	     // pri licitacii alebo cez opt cb nepovolena
+	  } else {
+	     dbglog ("callback_phase disallowdirect");
+	     dbglog ("CBCP Nedovoleny pokus obist cb zlou licitaciu");
+	     auth_peer_fail(unit,PPP_CBCP);
+	     return;
+	  }
+     } else {
+	dbglog ("callback_phase ready to open");
+	new_phase(PHASE_CALLBACK);
+	(*cbcp_protent.open)(unit);        // toto ho prinuti poslat vyzvu ..
+     }
+}
+#endif
+
+
 /*
  * The peer has failed to authenticate himself using `protocol'.
  */
@@ -637,8 +687,13 @@
      * If there is no more authentication still to be done,
      * proceed to the network (or callback) phase.
      */
+#ifdef CBCP_SUPPORT
     if ((auth_pending[unit] &= ~bit) == 0)
+        callback_phase(unit);
+#else
+    if ((auth_pending[unit] &= ~bit) == 0)
         network_phase(unit);
+#endif
 }
 
 /*
@@ -688,7 +743,15 @@
      * 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
+	}
 }
 
 
@@ -1450,6 +1513,16 @@
 	filename = _PATH_CHAPFILE;
 	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) {
Index: ppp/pppd/cbcp.c
diff -u ppp/pppd/cbcp.c:1.1.1.1 ppp/pppd/cbcp.c:1.4
--- ppp/pppd/cbcp.c:1.1.1.1	Sat Dec  8 00:32:53 2001
+++ ppp/pppd/cbcp.c	Mon Dec 10 02:42:44 2001
@@ -36,10 +36,13 @@
  * Options.
  */
 static int setcbcp __P((char **));
+static int setcbcps __P((char **));
 
 static option_t cbcp_option_list[] = {
     { "callback", o_special, setcbcp,
       "Ask for callback", OPT_PRIO | OPT_A2STRVAL, &cbcp[0].us_number },
+    { "callbacksrv", o_special_noarg, setcbcps,
+      "Offer callback", OPT_PRIO },
     { NULL }
 };
 
@@ -48,6 +51,7 @@
  */
 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));
@@ -63,7 +67,7 @@
     cbcp_lowerup,
     NULL,
     cbcp_open,
-    NULL,
+    cbcp_close,
     cbcp_printpkt,
     NULL,
     0,
@@ -76,7 +80,20 @@
 };
 
 cbcp_state cbcp[NUM_PPP];	
+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));
@@ -84,6 +101,8 @@
 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 );
 
 /* option processing */
 static int
@@ -91,6 +110,7 @@
     char **argv;
 {
     lcp_wantoptions[0].neg_cbcp = 1;
+    lcp_allowoptions[0].neg_cbcp = 1;
     cbcp_protent.enabled_flag = 1;
     cbcp[0].us_number = strdup(*argv);
     if (cbcp[0].us_number == 0)
@@ -100,6 +120,20 @@
     return (1);
 }
 
+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);
+}
+
+
 /* init state */
 static void
 cbcp_init(iface)
@@ -107,8 +141,18 @@
 {
     cbcp_state *us;
 
+   dbglog ("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);
 }
@@ -121,20 +165,62 @@
     cbcp_state *us = &cbcp[iface];
 
     dbglog("cbcp_lowerup");
-    dbglog("want: %d", us->us_type);
+    dbglog("want: %s", cbcp_optionnames[us->us_type]);
 
-    if (us->us_type == CB_CONF_USER)
-        dbglog("phone no: %s", us->us_number);
+//    if (us->us_type == CB_CONF_USER)
+//        dbglog("phone no: %s", us->us_number);
 }
 
 static void
 cbcp_open(unit)
     int unit;
 {
+    u_char buf[256];
+    u_char *bufp = buf;
+    u_char *outp;
+    int outlen;
+    cbcp_state *us = &cbcp[unit];
+
     dbglog("cbcp_open");
+
+   
+   if (us->us_id==1) {
+    dbglog ("cbcp_server_open done already");
+      return;
+   };
+   
+    dbglog ("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;
@@ -147,6 +233,7 @@
 
     cbcp_state *us = &cbcp[unit];
 
+    dbglog ("cbcp_input");
     inp = inpacket;
 
     if (pktlen < CBCP_MINLEN) {
@@ -169,12 +256,16 @@
  
     switch(code) {
     case CBCP_REQ:
+        dbglog ("CBCP_REQ received");
         us->us_id = id;
 	cbcp_recvreq(us, inp, len);
 	break;
 
     case CBCP_RESP:
 	dbglog("CBCP_RESP received");
+       if (id != us->us_id)
+       error (" id does not match: expected %d recv %d", us->us_id,id);
+       cbcp_recvresp(us,inp,len);
 	break;
 
     case CBCP_ACK:
@@ -193,19 +284,9 @@
 /* protocol was rejected by foe */
 void cbcp_protrej(int iface)
 {
+	dbglog ("cbcp_protrej");
 }
 
-char *cbcp_codenames[] = {
-    "Request", "Response", "Ack"
-};
-
-char *cbcp_optionnames[] = {
-    "NoCallback",
-    "UserDefined",
-    "AdminDefined",
-    "List"
-};
-
 /* pretty print a packet */
 static int
 cbcp_printpkt(p, plen, printer, arg)
@@ -398,6 +479,8 @@
     u_char *outp;
     int outlen;
 
+    dbglog ("cbcp_send");
+    
     outp = outpacket_buf;
 
     outlen = 4 + len;
@@ -424,6 +507,8 @@
     int opt_len;
     char address[256];
 
+    dbglog ("cbcp_recvack");
+    
     if (len) {
         GETCHAR(type, pckt);
 	GETCHAR(opt_len, pckt);
@@ -454,3 +539,214 @@
     lcp_close(0, "Call me back, please");
     status = EXIT_CALLBACK;
 }
+
+static void cbcp_close(int unit, char *reason)
+{
+    dbglog ("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) {  
+      error("CBCP recvresp: packet too short %d",len);
+      new_phase (PHASE_TERMINATE); 
+      return;
+   }
+   
+   GETCHAR(type, pckt);
+   GETCHAR(opt_len, pckt);
+   
+   if (opt_len > 2)
+     GETCHAR(delay, pckt);
+   
+   dbglog ("cbcp_server_recvresp type=%s delay=%d", cbcp_optionnames[type-1],delay);
+   
+   switch(type) {
+    case CB_CONF_NO:
+      if(!us->us_allowdirect)
+	{
+	   error ("CBCP Error: requested direct connection is not allowed");
+           new_phase(PHASE_TERMINATE);
+	   return;
+	}
+      break;
+    case CB_CONF_ADMIN:
+      if(!us->us_adminconf)
+	{
+	   error ("CBCP Error: requested admin-configured callback is not allowed");
+          new_phase (PHASE_TERMINATE);
+	   return;
+	}
+      break;
+    default:   // t.j. asi voli ale pozreme.
+      if(!us->us_userconf)
+	{
+	   error ("CBCP Error: requested user-configured callback is not allowed");
+           new_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;
+	 dbglog ("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;
+
+   dbglog ("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:
+      error ("CBCP unkown callback request type");
+      new_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, NULL, NULL);
+   }
+}
+
+
+//int akysposobppp(char *name)
+int cbcp_auth(cbcp_state *us,char *name)
+{
+   FILE *fp;
+   char *a,*b;
+   char line[81];
+
+   dbglog ("cbcp_server_auth");
+
+   
+   us->us_allowdirect = 0;
+   us->us_userconf = 0;
+   us->us_adminconf = 0;
+   cbcp_adminn[0]=0;
+   if(strlen(name)<2) {
+      error ("CBCP - name too short"); 
+      return 0;
+   }
+   if((fp=fopen(CBusers,"r"))==NULL) {
+	error ("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 ) {
+	    error ("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); 
+	 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
+    */
+   
+   error ("CBCP neni v"CBusers);
+   us->us_allowdirect=1;
+   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;
+}
+
Index: ppp/pppd/cbcp.h
diff -u ppp/pppd/cbcp.h:1.1.1.1 ppp/pppd/cbcp.h:1.2
--- ppp/pppd/cbcp.h:1.1.1.1	Sat Dec  8 00:32:53 2001
+++ ppp/pppd/cbcp.h	Sat Dec  8 01:52:40 2001
@@ -7,11 +7,27 @@
     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
 
Index: ppp/pppd/fsm.c
diff -u ppp/pppd/fsm.c:1.1.1.1 ppp/pppd/fsm.c:1.2
--- ppp/pppd/fsm.c:1.1.1.1	Sat Dec  8 00:32:53 2001
+++ ppp/pppd/fsm.c	Sat Dec  8 04:48:07 2001
@@ -443,7 +443,7 @@
 	  (len == 0)) ){
 	/* Ack is bad - ignore it */
 	error("Received bad configure-ack: %P", inp, len);
-	return;
+//	return;
     }
     f->seen_ack = 1;
 
Index: ppp/pppd/lcp.c
diff -u ppp/pppd/lcp.c:1.1.1.1 ppp/pppd/lcp.c:1.3
--- ppp/pppd/lcp.c:1.1.1.1	Sat Dec  8 00:32:53 2001
+++ ppp/pppd/lcp.c	Mon Dec 10 02:43:06 2001
@@ -343,7 +343,7 @@
     ao->neg_pcompression = 1;
     ao->neg_accompression = 1;
 #ifdef CBCP_SUPPORT
-    ao->neg_cbcp = 1;
+    ao->neg_cbcp = 0;
 #endif
     ao->neg_endpoint = 1;
 }
@@ -1702,6 +1702,18 @@
 	    BCOPY(p, ho->endpoint.value, cilen);
 	    INCPTR(cilen, p);
 	    break;
+
+#ifdef CBCP_SUPPORT	    
+	case  CI_CALLBACK:   // on mi ponuka cbcp a co ja na to.
+	    info ("lcp_reqci: rcvd Bbo callback");
+	    if (!ao->neg_cbcp ||
+		cilen != CILEN_CBCP) {
+		orc = CONFREJ;
+		break;
+	    }
+            ho->neg_cbcp = 1;
+           break;
+#endif
 
 	default:
 	    LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype));
