Date: Wed, 08 Jul 1998 16:15:10 +0100 From: Damian Hamill <damian@cablenet.net> To: Terry Lambert <tlambert@primenet.com>, freebsd-isp@FreeBSD.ORG Subject: Re: SASL References Message-ID: <35A38CFE.FCF07ABF@cablenet.net> References: <199807071823.LAA18971@usr01.primenet.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------F0E7820B0AA8AE204326DE3B Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Terry Lambert wrote: > > > We experimented with DDNS for some time with our radius server doing > > the updates but in the end we patched sendmail to get the address of a > > customer's host from a database that the radius server maintained. > > > > The patches to both the radius server and to sendmail are simple. > > Are they available for reference? I'll include some attachements below. They will need work to integrate into your mail server but you will get the idea. The sendmail diff file is against version 8.9b3. Both files contain references to some other functions which you can replace with your own versions (or download my Vdb package from the MySQL site and it's mirrors). > > In general, the reason I was leaning toward pottung the code in the > radiusd, instead of in the radiusd and the mail server, is to reduce > the number of changes. There are a *lot* of third party mail servers > out there (surprising as that seems). We did it as an internal requirement and we were only using sendmail. It has meant tracking new releases of sendmail but it hasn't been too difficult. We were going to patch the mail server anyway to stop it trying to connect to hosts that were offline. It was just a little bit more work to get the IP address from an SQL table. > > What problems were you thinking of, in particular? Unless you had > a malfunction, there's really little reason that the DNS database > couldn't be the "database maintained by the radius server". I found the dynamic DNS to be unreliable and the version of bind that we are using would fall over if a secondary forwarded it an update query. It was much less work patching sendmail than it was to get the dynamic DNS working. If a delete doesn't happen then when another host gets the same IP address it will start to get the previous hosts email. Remember the DNS updates (and the Radius accounting requests) are via UDP, an unreliable protocol. Using SQL (via TCP or Domain socket) the whole process is much reliable. What's more if a delete is missed then the DNS mapping will hang around, unless you periodically restart your name server (which I ended up doing - at which point I realised it was the wrong way to solve the problem). regards damian -- * Damian Hamill M.D. damian@cablenet.net * CableNet & The Landscape Channel * http://www.cablenet.net/ http://www.landscapetv.com/ --------------F0E7820B0AA8AE204326DE3B Content-Type: text/plain; charset=us-ascii; name="sendmail-daemon.c.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sendmail-daemon.c.diffs" 810,814d809 < /*-- Cablenet Begin *********/ < u_long al, dl; < char qbuf[1024], *fldv[1], login[64], domain[256], hostbuf[32], *p; < extern SOCKADDR dummy_ip; < /*-- Cablenet End *********/ 829,903d823 < /*-- Cablenet Begin *********/ < /* if we can find it in the online database then set up host to the < char representation of the IP address < break the host into login and domain parts < if the domain isn't our domain then carry on as normal < */ < < strcpy(domain, LowerStr(host)); < < if (tTd(16, 1)) < syslog(LOG_INFO,"makeconnection: to %s ",domain); < < if ((p = strchr(domain, '.')) != NULL) { < *p = '\0'; < < strcpy(login, domain); < < strcpy(domain, p +1); < < if (domain[strlen(domain) -1] == '.') < domain[strlen(domain) -1] = '\0'; < < } else < domain[0] = '\0'; < < if ( domain[0] && strcmp(domain, dflt_domain) == 0) { < int num; < < /* if this is a local domain then they must be in the online < database to continue */ < < /* connect to the dns sql engine */ < < if (dnshandle < 0) { < if ((dnshandle = ConnectSql(dns_host, dns_dbase)) < 0) { < < /* the only way to handle this is to post an error to < syslog and fail */ < < syslog( LOG_ERR, "couldn't open dns database for %s", < Vusrmsg ); < < return EX_TEMPFAIL; < } < } < < sprintf(qbuf, < "select ipaddr from online where login = '%s'", < login ); < < num = 1; < if ( VdbQuery(dnshandle, qbuf) == 0 && < VdbFirstRec(dnshandle, &fldv[0], &num ) == 0) < { < sprintf(hostbuf, "[%s]", fldv[0] ); < < if (tTd(16, 1)) < syslog(LOG_INFO, < "found IP address %s for %s from online table\n", < hostbuf, host ); < < host = hostbuf; < < DisconnectSql(); < < } else { < < DisconnectSql(); < < return EX_TEMPFAIL; < } < < } < /*-- Cablenet End *********/ < 1009,1037d928 < < /*-- Cablenet Begin *********/ < /* if this is the dummy IP address for the ISP < then just return fail */ < < /* compare dummy_ip_address with < the address we are going to connect to */ < < al = addr.sin.sin_addr.s_addr; < dl = dummy_ip.sin.sin_addr.s_addr; < < #ifdef IPv6 < #ifdef NETINET < if ( bcmp(&dummy_ip.sin.sin_addr.s_addr, < &addr.sin.sin_addr.s_addr, < sizeof (addr.sin.sin_addr.s_addr)) == 0) < #else < if ( bcmp(&dummy_ip.sa.sa_data, < &addr.sa.sa_data, < sizeof (addr.sa.sa_data)) == 0) < < #endif < #else < if ( al == dl) < #endif < { < return (EX_TEMPFAIL); < } < /*-- Cablenet End *********/ --------------F0E7820B0AA8AE204326DE3B Content-Type: text/plain; charset=us-ascii; name="radacct.extra" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="radacct.extra" /**************** include in acct.c **********/ int CableNetStart(char *login, char *ipaddr, time_t t) { char qbuf[512], msg[512], sbuf[1024], *fldv[3]; int num, child_pid; /* connect to the dns sql engine */ if (dnshandle < 0) { if ((dnshandle = ConnectSql(dns_host, dns_dbase)) < 0) { sprintf(msg, "CableNetStart can't connect to dns\n"); log_err(msg); syslog(LOG_ERR, "CableNetStart can't connect to dns\n"); return -1; } } /* remove any old entry from the online table */ /* make sure no records are hanging around for any old ip address */ sprintf(qbuf, "delete from online where ipaddr = '%s' or login = '%s'", ipaddr,login ); if (VdbQuery(dnshandle, qbuf) < 0) { DisconnectSql(); return -1; } sprintf(qbuf, "insert into online (login,ipaddr,start) values('%s','%s',%ld)", login, ipaddr, t ); if (VdbQuery(dnshandle, qbuf) < 0) { syslog( LOG_ERR, "error inserting into database >>%s<< [%s]", qbuf, Vdbmsg); DisconnectSql(); return -1; } finish_ok: DEBUG("login user %s ipaddr: %s\n", login, ipaddr ); syslog(LOG_NOTICE, "login user %s ipaddr: %s\n", login, ipaddr ); /* now do things like punt the mail to the user */ /* fork a child to do the work */ child_pid = fork(); if(child_pid < 0) { sprintf(msg, "Fork failed for %s [%s]", login, ipaddr ); log_err(msg); } if (child_pid == 0) { /* This is the child, do the work */ sprintf(sbuf, "%s/bin/logonuser %s %s", csms_base, login, ipaddr); system(sbuf); exit(0); } return 0; } int CableNetStop(char *login, char *ipaddr, int inoct, int outoct, time_t t, int session_time) { char qbuf[512], msg[512], *fldv[1]; char sbuf[1024]; int num; /* connect to the accounts sql engine */ if (accthandle < 0) { if ((accthandle = ConnectSql(acct_host, acct_dbase)) < 0) { sprintf(msg, "CableNetStop can't connect to acct\n"); log_err(msg); return -1; } } DEBUG("logoff user %s\n", login ); /* connect to the dns sql engine */ if (dnshandle < 0) { if ((dnshandle = ConnectSql(dns_host, dns_dbase)) < 0) { sprintf(msg, "CableNetStop can't connect to dns\n"); log_err(msg); return -1; } } sprintf(qbuf, "delete from online where ipaddr = '%s'", ipaddr ); if (VdbQuery(dnshandle, qbuf) < 0) { DisconnectSql(); return -1; } DisconnectSql(); return 0; } int DoCableNetAccounting(authreq) AUTH_REQ *authreq; { char login[64], ipaddrbuf[64]; int session_time = 0, status_type = 0, in_octets = 0; int out_octets = 0; time_t t; VALUE_PAIR *pair; t = time((time_t *)NULL); /* Acct-Status-Type = Stop Acct-Session-Time = 304 Acct-Authentic = RADIUS Acct-Input-Octets = 4877 Acct-Output-Octets = 1174 Acct-Delay-Time = 357 User-Service-Type = Framed-User Framed-Protocol = PPP Framed-Address = <ipaddr> User-Name = "snor" */ login[0] = '0'; ipaddrbuf[0] = '\0'; pair = authreq->request; while(pair != (VALUE_PAIR *)NULL) { switch(pair->type) { case PW_TYPE_STRING: if (strncmp(pair->name, "User-Name", 9) == 0) { strncpy(login, pair->strvalue, 63); StripLTBlanks(login); } break; case PW_TYPE_INTEGER: if (strncmp(pair->name, "Acct-Session-Time", 16) == 0) { session_time = pair->lvalue; t -= session_time; } else if (strncmp(pair->name, "Acct-Status-Type", 16) == 0) { status_type = pair->lvalue; } else if (strncmp(pair->name, "Acct-Input-Octets", 16) == 0) { in_octets = pair->lvalue; } else if (strncmp(pair->name, "Acct-Output-Octets", 16) == 0) { out_octets = pair->lvalue; } else if (strncmp(pair->name, "Acct-Delay-Time", 15) == 0) { t -= pair->lvalue; } break; case PW_TYPE_IPADDR: if (strncmp(pair->name,"Framed-Address",14) == 0) { ipaddr2str(ipaddrbuf, pair->lvalue); } break; } pair = pair->next; } if ( login[0] == '\0' || ipaddrbuf[0] == '\0') return -1; switch (status_type) { case PW_STATUS_START: CableNetStart(login,ipaddrbuf,t); break; case PW_STATUS_STOP: CableNetStop(login,ipaddrbuf,in_octets, out_octets, t, session_time); break; } return 0; } /******************** in rad_accounting() **********/ if((namepair == (VALUE_PAIR *)NULL) || (strlen(namepair->strvalue) <= 0)) { sprintf(msg, "Accounting: from %s - No User Name\n", ip_hostname(authreq->ipaddr)); log_err(msg); pairfree(authreq->request); memset(authreq, 0, sizeof(AUTH_REQ)); free(authreq); return; } + /* try to save this accounting information for CableNet users */ + DoCableNetAccounting(authreq); + /* * Create a directory for this client. */ sprintf(buffer, "%s/%s", radacct_dir, clientname); mkdir(buffer, 0755); /* * Write Detail file. */ sprintf(buffer, "%s/%s/detail", radacct_dir, clientname); --------------F0E7820B0AA8AE204326DE3B-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-isp" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?35A38CFE.FCF07ABF>