*** raddb/dictionary.orig Mon Nov 8 15:28:15 1999 --- raddb/dictionary Mon Nov 8 15:29:30 1999 *************** *** 121,126 **** --- 121,134 ---- ATTRIBUTE Login-Time 1042 string # + # Experimental Attributes for SQL Accounting + # + ATTRIBUTE LocalTime 1100 integer + ATTRIBUTE GMTime 1101 integer + ATTRIBUTE SQL-LocalTime 1102 string + ATTRIBUTE SQL-GMTime 1103 string + + # # Non-Protocol Attributes # These attributes are used internally by the server # *** raddb/sqlconf.orig Mon Nov 8 15:28:09 1999 --- raddb/sqlconf Mon Nov 8 15:45:15 1999 *************** *** 0 **** --- 1,93 ---- + # + # sqlconf + # + # This file controls how radiusd connects to the SQL server, and what + # attributes get logged. There isn't any hard and fast rule as to how + # to lay out your database, but please read the README.sql file in the + # doc directory to see a sample schema that should work well to get + # you started (and will work with the definitions below). + # + + # Do we want to do SQL accounting? + SQL-Accounting yes + + # Accounting Database type, host, port, user, pass, etc... + SQL-Acct-Type MySQL + SQL-Acct-Host localhost + SQL-Acct-User radius + SQL-Acct-Passwd foobar + SQL-Acct-Database radius + SQL-Acct-Table radius_log + SQL-Acct-Insert-Cmd REPLACE + + # Are we interested in Stop records? + SQL-Log-Stop-Records yes + + # How about Start records? + SQL-Log-Start-Records no + + # And those pesky "alive" records? + SQL-Log-Alive-Records no + + # What about unknown record types? + SQL-Log-Unknown-Records no + + # Do you want to log accounting requests with blank usernames and caller-ids? + # (not yet implemented) + #SQL-Log-Blank-Username yes + + + # LocalTime, GMTime, SQL-LocalTime, and SQL-GMTime are special cases. + # They are generated internally by the sql accounting code. It is + # reccomended that you use GMTime if you have POPS in multiple time + # zones or plan to deploy pops in multiple time zones. + # + # LocalTime and GMTime are UNIX time values (seconds since epoch) + # + # For the SQL time fields, it is reccomended to let your SQL server + # generate the timestamps itself, but you can have radiusd do that for + # you. Additionally, if you use these fields, you will need to have + # these four attributes in your dictionary. The value is not important. + # + # ATTRIBUTE LocalTime 1100 integer + # ATTRIBUTE GMTime 1101 integer + # ATTRIBUTE SQL-LocalTime 1102 string + # ATTRIBUTE SQL-GMTime 1103 string + + #LocalTime event_time + GMTime event_time + #SQL-LocalTime sql_event_time + #SQL-GMTime sql_event_time + + + # And here, the fun begins. Something nobody else has done yet + # (At least none that I could find :) + # + # Make a map of your accounting attributes that you want to capture, + # and associate them with the appropriate fields in your SQL database. + # + # Any attributes listed here that are not in the accounting record will + # be ignored. + # + # Likewise, any attribute in the accounting record that is not mapped + # here will also be ignored. + # + # In other words, we're only going to pay attention to those attributes + # that both exist here and in the actual accounting request. This allows + # us to get rid of useless or unwanted information. + # + + Acct-Session-Id session_id + User-Name user_name + Caller-ID caller_id + NAS-IP-Address nas_ip + Acct-Session-Time session_time + Acct-Status-Type status_type + #Connect-Info connect_info + Ascend-Disconnect-Cause ascend_disconnect_cause + Ascend-Connect-Progress ascend_connect_progress + Ascend-Data-Rate connect_rate + Ascend-Xmit-Rate download_rate + Ascend-First-Dest first_dest + Client-Port-DNIS dnis + Framed-Address framed_address *** doc/README.sql.orig Mon Nov 8 15:45:30 1999 --- doc/README.sql Mon Nov 8 16:01:16 1999 *************** *** 0 **** --- 1,149 ---- + This is the README file for the SQL hacks + Author: Troy Settle + + + CONTENTS + -------- + 1. COMMENTS + 2. CREDITS + 3. FEATURES + 4. RELEASE NOTES + 5. INSTALLATION + 6. SQL Schema + + + COMMENTS + -------- + + To start, I want to tell you straight up that I'm not a programmer of any + real talent, and my skills at documentation suck even more. Please read + this text as best you can, and ask questions as needed. + + In 1997, we purchaced our first network access server, an Ascend Max 4004. + At the time I didn't know any better, so I installed Ascend's radiusd. + It worked well enough. As time went on, I found a patch to allow it to + log accounting information directly into a MySQL database. I implemented + it, and it's been in production for nearly 2 years now. + + Several months ago, I went on a search for a better solution. I found + radiusd-cistron. It did everything I needed, and then some. There were + even patches for it to use MySQL as a backend for accounting. Problem was + that the existing patches were not very friendly to Ascend's accounting + informatin, and putting a bandaid on them wasn't a desirable awnswer. So + after a couple months of procrastination, I finally sat down and started + cranking out some code. My first real experience in C for about 4 years. + + Initially, this was going to be for internal use only. But after laying + out the framework, I realized that this was going to turn out to be one of + the better radius-SQL implementations out there, so I decided to go ahead + and release it. + + + CREDITS + ------- + + I modeled some routines after the some of the code in the other SQL + patches availiable, but I don't think my code is similar enough to warrent + credit. If you feel that I'm using a signifigant chunk of your code and + desire proper credit, please let me know and I'll be glad to stick your + name in there. + + + FEATURES + --------------- + + Currently, the only feature I've implemented, is SQL accounting. So far, + it's working beautifully as an accounting server for ~500 ports. + + At this point, there's only a few items that I'd like to eventually add: + + Spooling in the event of a SQL breakdown. + SQL Authentication + SQL radutmp + + There may be other features that can be added. If you come up with one, + be sure to let me know. + + + RELEASE NOTES + ------------- + + To build, you will need to edit the Makefile for your platform. The one + for BSD works on FreeBSD 3.2-STABLE. Use it as a model for writing the + Makefile for your platform. When you get it working, please be sure to + email me your Makefile for inclusion into future patches. + + Currently, there is only support for MySQL. Adding support for other SQL + servers should be trivial. If you do hack in additional functionality, + please send me a diff so that I can incorporate it into my patch. + + If you run into any problems building this, please let me know what the + problem is, and what you had to do to make it work. I'll be straight up + and honest about this, I'm not an experienced developer, and will not be + able to offer much help at this point. + + There is one problem with an "assignment from incompatible pointer type" + that I've not yet been able to figure out. The code does work as expected + though. At this time, I believe it's safe to ignore these warnings. + + + INSTALLATION + ------------ + + In order to use this update, you will need to replace your existing + dictionary file with the one included with this distribution. You will + also need to copy and edit the sqlconf file out of the raddb directory. + When editing the sqlconf file, please be careful as to how you spell + things. As with everything else unix, it will not be forgiving on + syntactical errors. + + + SQL SCHEMA + ---------- + + + This table suits the needs for my company. You may need to track different + accounting information. If this is so, adjust the schema here to suit your + needs, then edit raddb/sqlconf to match. + + + # + # Table structure for table 'detail' + # + CREATE TABLE detail ( + record_id int(11) DEFAULT '0' NOT NULL auto_increment, + sql_event_time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, + event_time int(11) DEFAULT '0' NOT NULL, + session_id char(32) DEFAULT '' NOT NULL, + user_name char(32) DEFAULT '' NOT NULL, + caller_id char(20) DEFAULT '' NOT NULL, + nas_ip char(16) DEFAULT '' NOT NULL, + status_type smallint(6) DEFAULT '0' NOT NULL, + session_time int(11) DEFAULT '0' NOT NULL, + connect_info char(32) DEFAULT '' NOT NULL, + ascend_disconnect_cause smallint(6) DEFAULT '0' NOT NULL, + ascend_connect_progress smallint(6) DEFAULT '0' NOT NULL, + connect_rate int(11) DEFAULT '0' NOT NULL, + download_rate int(11) DEFAULT '0' NOT NULL, + first_dest char(16) DEFAULT '' NOT NULL, + dnis char(10) DEFAULT '' NOT NULL, + framed_address char(16) DEFAULT '' NOT NULL, + PRIMARY KEY (record_id), + UNIQUE foo (session_id,nas_ip,status_type), + KEY BYCLID (caller_id,event_time,sql_event_time), + KEY BYUSER (user_name,event_time,sql_event_time), + KEY BYADDR (framed_address,event_time,sql_event_time) + ); + + + + Due to issues with my currently employer, I'll no longer be able to + provide any support for this. Hopefully, someone will pick up the torch + and fix any bugs that might appear. + + + Thanks, + + Troy Settle + iPlus Internet Services + *** src/acct.c.orig Mon Nov 8 15:26:18 1999 --- src/acct.c Mon Nov 8 12:32:36 1999 *************** *** 655,660 **** --- 655,663 ---- fputs("\t", outfd); fprint_attr_val(outfd, pair); fputs("\n", outfd); + #ifdef USE_SQL + sql_build_record(pair); + #endif /* USE_SQL */ } pair = pair->next; } *************** *** 679,684 **** --- 682,691 ---- fputs("\n", outfd); fclose(outfd); } + + #ifdef USE_SQL + sql_save_record(pair); + #endif /* USE_SQL */ return ret; } *** src/radiusd.c.orig Mon Nov 8 15:26:41 1999 --- src/radiusd.c Mon Nov 8 16:44:33 1999 *************** *** 131,136 **** --- 131,144 ---- if (res == 0 && read_config_files() != 0) res = -1; + #ifdef USE_SQL + /* Read the SQL config file at startup only until we get it fixed */ + if(!reload) { + if (res == 0 && sql_rad_init() != 0) + res = -1; + } + #endif + if (res != 0) { if (pid == radius_pid) { log(L_ERR|L_CONS, *** src/radiusd.h.orig Mon Nov 8 15:26:35 1999 --- src/radiusd.h Mon Nov 8 12:03:16 1999 *************** *** 279,281 **** --- 279,297 ---- /* timestr.c */ int timestr_match(char *, time_t); + /* sql.c */ + typedef struct sql_pair { + int type; + char name[64]; + int attribute; + char field[32]; + char value[128]; + struct sql_attr *next; + } SQL_PAIR; + + int sql_rad_init(); + void sql_pairadd(SQL_PAIR **, SQL_PAIR *); + void sql_pairfree(SQL_PAIR *); + void sql_save_record(); + void sql_build_record(VALUE_PAIR *); + *** src/sql.c.orig Mon Nov 8 15:24:09 1999 --- src/sql.c Mon Nov 8 15:24:05 1999 *************** *** 0 **** --- 1,537 ---- + #ifdef USE_SQL + + #include + #include + #include + #include + #include + + #ifdef USE_MYSQL + # include + #endif + + #include "radiusd.h" + + static char *getfirstword(char *, char *); + static SQL_PAIR *sql_paircopy(SQL_PAIR *); + static void sql_safeprint(char *, int, char *, int); + + + /* + * Global Variables + */ + + int sql_acct_type; + + #define SQL_TYPE_MYSQL 1 + + int sql_accounting; + char sql_acct_host[64]; + char sql_acct_user[16]; + char sql_acct_pass[16]; + char sql_acct_database[16]; + char sql_acct_table[16]; + char sql_acct_insert_cmd[128]; + + int sql_log_stop_records; + int sql_log_start_records; + int sql_log_alive_records; + int sql_log_unknown_records; + int sql_log_blank_username; + + SQL_PAIR *sql_attrs = NULL; + + /* + * Write the accounting record out + */ + void sql_save_record() + { + SQL_PAIR *tp; + int saverecord = 1; + char buffer[128]; + char query[8196]; + char fields[2048]; + char values[2048]; + time_t t; + #ifdef USE_MYSQL + MYSQL sqlfd; + #endif + + memset(query,0,sizeof(query)); + memset(fields,0,sizeof(fields)); + memset(values,0,sizeof(values)); + + time(&t); + + /* log(L_INFO,"SQL_SAVE: Saving record - maybe..."); */ + + for(tp = sql_attrs; tp ; tp = tp->next) + { + if(strcasecmp("LocalTime",tp->name) == 0) + { + strftime(buffer, sizeof(buffer), "%s", localtime(&t)); + sprintf(values, "%s,'%s'", values, buffer); + sprintf(fields, "%s,%s", fields, tp->field); + } + else + if(strcasecmp("GMTime",tp->name) == 0) + { + strftime(buffer, sizeof(buffer), "%s", gmtime(&t)); + sprintf(values, "%s,'%s'", values, buffer); + sprintf(fields, "%s,%s", fields, tp->field); + } + else + if(strcasecmp("SQL-LocalTime",tp->name) == 0) + { + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", localtime(&t)); + sprintf(values, "%s,'%s'", values, buffer); + sprintf(fields, "%s,%s", fields, tp->field); + } + else + if(strcasecmp("SQL-GMTime",tp->name) == 0) + { + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", gmtime(&t)); + sprintf(values, "%s,'%s'", values, buffer); + sprintf(fields, "%s,%s", fields, tp->field); + } + else + { + + switch(tp->attribute) + { + case PW_ACCT_STATUS_TYPE: + switch(atoi(tp->value)) + { + case PW_STATUS_STOP: + saverecord = sql_log_stop_records; + break; + case PW_STATUS_START: + saverecord = sql_log_start_records; + break; + case PW_STATUS_ALIVE: + saverecord = sql_log_alive_records; + break; + default: + saverecord = sql_log_unknown_records; + break; + } + break; + case PW_USER_NAME: + if (strlen(tp->value) == 0) + saverecord = sql_log_blank_username; + break; + default: + break; + } + sprintf(values, "%s,'%s'", values, tp->value); + strcpy(tp->value, ""); + sprintf(fields, "%s,%s", fields, tp->field); + } + } + sprintf(query, "%s INTO %s (%s) VALUES (%s)", + sql_acct_insert_cmd, + sql_acct_table, + &fields[1], + &values[1]); + + if(saverecord != 0) + { + /* log(L_INFO,"SQL_save: Query: %s",query); */ + switch(sql_acct_type) { + #ifdef USE_MYSQL + case SQL_TYPE_MYSQL: + mysql_init(&sqlfd); + if(!(mysql_real_connect(&sqlfd,sql_acct_host,sql_acct_user,sql_acct_pass,sql_acct_database,0,NULL,0))) + { + /* MySQL server not responding... */ + log(L_ERR,"SQL_save: MySQL server (%s@%s/%s) not responding: %s", + sql_acct_user, sql_acct_host, sql_acct_database, mysql_error(&sqlfd)); + } + else + { + mysql_real_query(&sqlfd,query,sizeof(query)); + mysql_close(&sqlfd); + } + break; + #endif /* USE_MYSQL */ + + default: + log(L_ERR,"SQL: Acct module activated, but no valid SQL server type selected"); + break; + } + } + } + + /* + * Build the accounting record for SQL insertion + */ + void sql_build_record(VALUE_PAIR *pair) + { + SQL_PAIR *tp; + char buffer[1024]; + char *a = NULL; + + if(!sql_accounting) return; + + /* Are we interested in this pair? + * If so, print the value in to buffer + * then copy buffer to tp->value + */ + for (tp = sql_attrs ; tp ; tp = tp->next) + { + if (tp->attribute == pair->attribute) + { + /* Found one, add it to the list */ + switch(pair->type) + { + case PW_TYPE_STRING: + if (pair->attribute == PW_NAS_PORT_ID) + a = pair->strvalue; + else + { + sql_safeprint(pair->strvalue, pair->length, + buffer, sizeof(buffer)); + a = buffer; + } + break; + + case PW_TYPE_IPADDR: + ipaddr2str(buffer, pair->lvalue); + a = buffer; + break; + + case PW_TYPE_INTEGER: + sprintf(buffer, "%ld", pair->lvalue); + a = buffer; + break; + + default: + a = "UNKNOWN"; + break; + } + strncpy(tp->value, a, sizeof(tp->value)); + } + } + } + + + /* + * Initialize the SQL stuffs + */ + int sql_rad_init() + { + FILE *sqlfd; + char buffer[1024]; + char sqlfile[256]; + char cname[256]; + char cval[256]; + char *ptr, *ptr2; + int line=0; + DICT_ATTR *dentry = NULL; + SQL_PAIR *tp; + + sql_acct_type = SQL_TYPE_MYSQL; + strcpy(sql_acct_host,"localhost"); + strcpy(sql_acct_user,"radius"); + strcpy(sql_acct_pass,""); + strcpy(sql_acct_database,"radius"); + strcpy(sql_acct_table,"radacct"); + strcpy(sql_acct_insert_cmd,"REPLACE"); + + sql_accounting=0; + + sql_log_start_records=0; + sql_log_stop_records=0; + sql_log_alive_records=0; + sql_log_unknown_records=0; + sql_log_blank_username=0; + + + sprintf(sqlfile, "%s/%s", radius_dir, "sqlconf"); + + if((sqlfd = fopen(sqlfile,"r")) == (FILE *)NULL) + + { + log(L_ERR,"could not open file %s for reading",sqlfile); + return(-1); + } + + while(fgets(buffer, sizeof(buffer), sqlfd) != (char *)NULL) { + line++; + + if(buffer[0] == 35 || buffer[0] == '\0' || buffer[0] == '\n') { + continue; + } + /* Look for configuration variables */ + + /* get the first field from the config, return pointer to rest */ + ptr = getfirstword(buffer, cname); + + if (*ptr) + { + /* Trim off trailing whitespace */ + ptr2 = &ptr[strlen(ptr) -1]; + while(*ptr2 == ' ' || *ptr2 == '\n' || *ptr2 == '\t') + { + ptr2--; + if (ptr2 == ptr) break; + } + ptr2++; *ptr2='\0'; + strcpy(cval,ptr); + } + else + { + log(L_ERR,"SQL_init: Invalid paramater count on line %d of %s\n",line,buffer); + continue; + } + + /* + * We now have the name and value of the config var + * There as got to be a better way to do this + */ + + /* first the true/false, yes/no type stuff */ + if ((strcasecmp(cname,"SQL-Accounting") == 0) && (strcasecmp(cval,"yes") == 0)) + sql_accounting = 1; + else + if ((strcasecmp(cname,"SQL-Log-Stop-Records") == 0) && (strcasecmp(cval,"yes") == 0)) + sql_log_stop_records = 1; + else + if ((strcasecmp(cname,"SQL-Log-Start-Records") == 0) && (strcasecmp(cval,"yes") == 0)) + sql_log_start_records = 1; + else + if ((strcasecmp(cname,"SQL-Log-Alive-Records") == 0) && (strcasecmp(cval,"yes") == 0)) + sql_log_alive_records = 1; + else + if ((strcasecmp(cname,"SQL-Log-Unknown-Records") == 0) && (strcasecmp(cval,"yes") == 0)) + sql_log_unknown_records = 1; + else + if ((strcasecmp(cname,"SQL-Log-Blank-Username") == 0) && (strcasecmp(cval,"yes") == 0)) + sql_log_blank_username = 1; + + /* Now the funner stuff */ + else + if ((strcasecmp(cname,"SQL-Acct-Type") == 0) && *cval) + { + if (strcasecmp(cval,"MySQL") == 0) + sql_acct_type = SQL_TYPE_MYSQL; + } + else + if ((strcasecmp(cname,"SQL-Acct-Host") == 0) && *cval) + strcpy(sql_acct_host,cval); + else + if ((strcasecmp(cname,"SQL-Acct-User") == 0) && *cval) + strcpy(sql_acct_user,cval); + else + if ((strcasecmp(cname,"SQL-Acct-Passwd") == 0) && *cval) + strcpy(sql_acct_pass,cval); + else + if ((strcasecmp(cname,"SQL-Acct-Database") == 0) && *cval) + strcpy(sql_acct_database,cval); + else + if ((strcasecmp(cname,"SQL-Acct-Table") == 0) && *cval) + strcpy(sql_acct_table,cval); + else + if ((strcasecmp(cname,"SQL-Acct-Insert-Cmd") == 0) && *cval) + strcpy(sql_acct_insert_cmd,cval); + + + + /* see if this is a valid Attrib from the dictionary */ + else + if((dentry = dict_attrfind(cname)) != (DICT_ATTR *)NULL) + { + if((tp = (SQL_PAIR *)malloc(sizeof(SQL_PAIR))) == (SQL_PAIR *)NULL) + { + log(L_ERR|L_CONS, "SQL_init: out of memory"); + return (-1); + } + strcpy(tp->name,dentry->name); /* Attr Name */ + strcpy(tp->field,cval); /* Field Name */ + tp->type = dentry->type; /* Attr Type */ + tp->attribute = dentry->value; /* Attr Value */ + tp->next=(struct sql_attr *)NULL; + strcpy(tp->value, ""); + sql_pairadd(&sql_attrs,sql_paircopy(tp)); /* Add Item to List */ + sql_pairfree(tp); + } + } + fclose(sqlfd); + if(sql_accounting) + log(L_INFO,"SQL_INIT: Acct Module Using %s@%s:%s.%s", + sql_acct_user, + sql_acct_host, + sql_acct_database, + sql_acct_table); + return(0); + } + + + /* + * Allocate for a new SQL_PAIR + */ + + static SQL_PAIR *sql_paircopy(SQL_PAIR *from) + { + SQL_PAIR *vp = NULL; + SQL_PAIR *last = NULL; + SQL_PAIR *i, *t; + + for(i = from; i; i = i->next) { + if ((t = malloc(sizeof(SQL_PAIR))) == NULL) + continue; + memcpy(t, i, sizeof(SQL_PAIR)); + t->next = NULL; + if (last) + last->next = t; + else + vp = t; + last = t; + } + + return vp; + } + + + /* + * Add a pair to the end of a SQL_PAIR chain + */ + void sql_pairadd(SQL_PAIR **first, SQL_PAIR *new) + { + SQL_PAIR *i; + + new->next = NULL; + if (*first == NULL) { + *first = new; + return; + } + for(i = *first; i->next; i = i->next) + ; + i->next = new; + } + + + /* + * Free up memory used by an SQL_PAIR list + */ + void sql_pairfree(SQL_PAIR *pair) + { + SQL_PAIR *next; + + while(pair != NULL) { + next = pair->next; + free(pair); + pair = next; + } + } + + + /* + * Convert a string to something printable. + * The output string has to be _at least_ 4x the size + * of the input string! + * + * Borrowed from radiusd-cistron 1.6alpha2 + * will return when I re-write this as a module for 1.6 + */ + static void sql_safeprint(char *in, int inlen, char *out, int outlen) + { + unsigned char *str = (unsigned char *)in; + int done = 0; + int sp = 0; + + if (inlen < 0) inlen = strlen(str); + + while (inlen-- > 0 && (done + 3) < outlen) { + /* + * Hack: never print trailing zero. + * Some clients send strings with an off-by-one + * length (confused with strings in C). + */ + if (inlen == 0 && *str == 0) + break; + + sp = 0; + + switch (*str) { + case '\\': + sp = '\\'; + break; + case '\r': + sp = 'r'; + break; + case '\n': + sp = 'n'; + break; + case '\t': + sp = 't'; + break; + default: + if (*str < 32 || (*str >= 128 && *str <= 160)){ + sprintf(out, "\\%03o", *str); + done += 4; + out += 4; + } else { + *out++ = *str; + done++; + } + } + if (sp) { + *out++ = '\\'; + *out++ = sp; + done += 2; + } + str++; + } + *out = 0; + } + + /* + * Copy the first word from the buffer, and return + * a pointer to the first non-space charachter after that. + * + * We allow "" and \ to include spaces in the word + * (hold over from when this was getusername) + */ + static char *getfirstword(char *buffer, char *entry) + { + char *ptr; + char *to; + int spc_seen = 0; + + ptr = buffer; + to = entry; + + while (*ptr && !spc_seen) { + switch (*ptr) { + case '"': + ptr++; + while (*ptr && *ptr != '"') + *to++ = *ptr++; + if (*ptr) ptr++; + break; + case '\\': + ptr++; + *to++ = *ptr; + if (*ptr) ptr++; + break; + case ' ': + case '\t': + case '\n': + spc_seen = 1; + break; + default: + *to++ = *ptr++; + break; + } + } + *to = 0; + + while (*ptr == ' ' || *ptr == '\t' || *ptr == '\n') + ptr++; + + return ptr; + } + + + #endif /* USE_SQL */ *** src/Make.inc.orig Mon Nov 8 15:25:46 1999 --- src/Make.inc Mon Nov 8 13:15:26 1999 *************** *** 4,18 **** # # ! SERVER_OBJS = radiusd.o dict.o files.o util.o md5.o attrprint.o \ acct.o radius.o pam.o log.o version.o proxy.o \ exec.o auth.o timestr.o cache.o SERVERDBM_OBJS = radiusddbm.o dict.o filesdbm.o util.o md5.o attrprint.o \ acct.o radius.o pam.o log.o versiondbm.o proxy.o \ ! exec.o auth.o timestr.o cache.o SERVER_SRCS = radiusd.c dict.c files.c util.c md5.c attrprint.c acct.c \ radius.c pam.c log.c version.c proxy.c \ ! exec.c auth.c timestr.c cache.c INCLUDES = radius.h conf.h all: radiusd radwho radzap raduse radtest --- 4,18 ---- # # ! SERVER_OBJS = radiusd.o dict.o files.o util.o sql.o md5.o attrprint.o \ acct.o radius.o pam.o log.o version.o proxy.o \ exec.o auth.o timestr.o cache.o SERVERDBM_OBJS = radiusddbm.o dict.o filesdbm.o util.o md5.o attrprint.o \ acct.o radius.o pam.o log.o versiondbm.o proxy.o \ ! exec.o auth.o timestr.o cache.o sql.o SERVER_SRCS = radiusd.c dict.c files.c util.c md5.c attrprint.c acct.c \ radius.c pam.c log.c version.c proxy.c \ ! exec.c auth.c timestr.c cache.c sql.c INCLUDES = radius.h conf.h all: radiusd radwho radzap raduse radtest *************** *** 20,39 **** dbm: radiusd.dbm builddbm radiusd: $(SERVER_OBJS) ! $(CC) $(LDFLAGS) -o radiusd $(SERVER_OBJS) $(LIBS) $(LCRYPT) $(PAMLIB) radiusd.dbm: $(SERVERDBM_OBJS) $(CC) $(LDFLAGS) -o radiusd.dbm $(SERVERDBM_OBJS) $(LIBS) $(LCRYPT) \ ! $(DBMLIB) $(PAMLIB) radiusd.o: radiusd.c $(INCLUDES) ! $(CC) $(CFLAGS) -c radiusd.c radiusddbm.o: radiusd.c $(INCLUDES) ! $(CC) $(CFLAGS) $(DBM) -c radiusd.c -o radiusddbm.o acct.o: acct.c $(INCLUDES) ! $(CC) $(CFLAGS) -c acct.c attrprint.o: attrprint.c $(INCLUDES) $(CC) $(CFLAGS) -c attrprint.c --- 20,40 ---- dbm: radiusd.dbm builddbm radiusd: $(SERVER_OBJS) ! $(CC) $(LDFLAGS) -o radiusd $(SERVER_OBJS) $(LIBS) $(LCRYPT) $(PAMLIB) \ ! $(SQLLIB) $(SQLLIBDIR) radiusd.dbm: $(SERVERDBM_OBJS) $(CC) $(LDFLAGS) -o radiusd.dbm $(SERVERDBM_OBJS) $(LIBS) $(LCRYPT) \ ! $(DBMLIB) $(PAMLIB) $(SQLLIB) $(SQLLIBDIR) radiusd.o: radiusd.c $(INCLUDES) ! $(CC) $(CFLAGS) $(SQL) -c radiusd.c radiusddbm.o: radiusd.c $(INCLUDES) ! $(CC) $(CFLAGS) $(DBM) $(SQL) -c radiusd.c -o radiusddbm.o acct.o: acct.c $(INCLUDES) ! $(CC) $(CFLAGS) $(SQL) -c acct.c attrprint.o: attrprint.c $(INCLUDES) $(CC) $(CFLAGS) -c attrprint.c *************** *** 58,63 **** --- 59,67 ---- cache.o: cache.c $(INCLUDES) $(CC) $(CFLAGS) -c cache.c + + sql.o: sql.c $(INCLUDES) + $(CC) $(CFLAGS) $(SQL) -c sql.c proxy.o: proxy.c $(INCLUDES) $(CC) $(CFLAGS) -c proxy.c *** src/Makefile.BSD.orig Sat Sep 18 18:10:41 1999 --- src/Makefile.BSD Mon Nov 8 12:05:49 1999 *************** *** 4,10 **** # CC = gcc ! CFLAGS = -Wall -g -DNOSHADOW LDFLAGS = # -s #tatic LIBS = LCRYPT = -lcrypt --- 4,10 ---- # CC = gcc ! CFLAGS = -Wall -g -DNOSHADOW -I/usr/local/include LDFLAGS = # -s #tatic LIBS = LCRYPT = -lcrypt *************** *** 17,21 **** --- 17,25 ---- BINDIR = /usr/local/bin SBINDIR = /usr/local/sbin + + SQL = -DUSE_SQL -DUSE_MYSQL + SQLLIB = -lmysqlclient + SQLLIBDIR = -L/usr/local/lib/mysql .include "Make.inc" *** src/Makefile.lnx.orig Mon Nov 8 16:04:38 1999 --- src/Makefile.lnx Mon Nov 8 16:07:59 1999 *************** *** 28,31 **** --- 28,35 ---- BINDIR = /usr/local/bin SBINDIR = /usr/local/sbin + SQL = -DUSE_SQL -DUSE_MYSQL + SQLLIB = -lmysqlclient + SQLLIBDIR = -L/usr/lib/mysql + include Make.inc