📄 mainconfig.c
字号:
return -1; } strcpy(c->realm, name2); if (authhost) strcpy(c->server, authhost); if (accthost) strcpy(c->acct_server, accthost); /* * If one or the other of authentication/accounting * servers is set to LOCALHOST, then don't require * a shared secret. */ if ((c->ipaddr != htonl(INADDR_NONE)) || (c->acct_ipaddr != htonl(INADDR_NONE))) { if ((s = cf_section_value_find(cs, "secret")) == NULL ) { radlog(L_ERR, "%s[%d]: No shared secret supplied for realm: %s", filename, cf_section_lineno(cs), name2); return -1; } if (strlen(s) >= sizeof(c->secret)) { radlog(L_ERR, "%s[%d]: Secret of length %d is greater than the allowed maximum of %d.", filename, cf_section_lineno(cs), strlen(s), sizeof(c->secret) - 1); return -1; } strNcpy((char *)c->secret, s, sizeof(c->secret)); } c->striprealm = 1; if ((cf_section_value_find(cs, "nostrip")) != NULL) c->striprealm = 0; if ((cf_section_value_find(cs, "noacct")) != NULL) c->acct_port = 0; if ((cf_section_value_find(cs, "trusted")) != NULL) c->trusted = 1; if ((cf_section_value_find(cs, "notrealm")) != NULL) c->notrealm = 1; if ((cf_section_value_find(cs, "notsuffix")) != NULL) c->notrealm = 1; if ((t = cf_section_value_find(cs,"ldflag")) != NULL) { static const LRAD_NAME_NUMBER ldflags[] = { { "fail_over", 0 }, { "round_robin", 1 }, { NULL, 0 } }; c->ldflag = lrad_str2int(ldflags, t, -1); if (c->ldflag == -1) { radlog(L_ERR, "%s[%d]: Unknown value \"%s\" for ldflag", filename, cf_section_lineno(cs), t); return -1; } } else { c->ldflag = 0; /* non, make it fail-over */ } c->active = TRUE; c->acct_active = TRUE; c->next = NULL; *tail = c; tail = &c->next; } /* * And make these realms preferred over the ones * in the 'realms' file. */ *tail = mainconfig.realms; mainconfig.realms = my_realms; /* * Ensure that all of the flags agree for the realms. * * Yeah, it's O(N^2), but it's only once, and the * maximum number of realms is small. */ for(c = mainconfig.realms; c != NULL; c = c->next) { REALM *this; /* * Check that we cannot load balance to LOCAL * realms, as that doesn't make any sense. */ if ((c->ldflag == 1) && ((c->ipaddr == htonl(INADDR_NONE)) || (c->acct_ipaddr == htonl(INADDR_NONE)))) { radlog(L_ERR | L_CONS, "ERROR: Realm %s cannot be load balanced to LOCAL", c->realm); exit(1); } /* * Compare this realm to all others, to ensure * that the configuration is consistent. */ for (this = c->next; this != NULL; this = this->next) { if (strcasecmp(c->realm, this->realm) != 0) { continue; } /* * Same realm: Different load balancing * flag: die. */ if (c->ldflag != this->ldflag) { radlog(L_ERR | L_CONS, "ERROR: Inconsistent value in realm %s for load balancing 'ldflag' attribute", c->realm); exit(1); } } } return 0;}/* * Create the linked list of realms from the new configuration * type. This way we don't have to change too much in the other * source-files. */static RADCLIENT *generate_clients(const char *filename, CONF_SECTION *section){ CONF_SECTION *cs; RADCLIENT *list, *c; char *hostnm, *secret, *shortnm, *netmask; char *nastype, *login, *password; char *name2; list = NULL; for (cs = cf_subsection_find_next(section, NULL, "client"); cs != NULL; cs = cf_subsection_find_next(section, cs, "client")) { name2 = cf_section_name2(cs); if (!name2) { radlog(L_CONS|L_ERR, "%s[%d]: Missing client name", filename, cf_section_lineno(cs)); clients_free(list); return NULL; } /* * Check the lengths, we don't want any core dumps */ hostnm = name2; if((secret = cf_section_value_find(cs, "secret")) == NULL) { radlog(L_ERR, "%s[%d]: Missing secret for client: %s", filename, cf_section_lineno(cs), name2); clients_free(list); return NULL; } if((shortnm = cf_section_value_find(cs, "shortname")) == NULL) { radlog(L_ERR, "%s[%d]: Missing shortname for client: %s", filename, cf_section_lineno(cs), name2); clients_free(list); return NULL; } netmask = strchr(hostnm, '/'); if (strlen(secret) >= sizeof(c->secret)) { radlog(L_ERR, "%s[%d]: Secret of length %d is greater than the allowed maximum of %d.", filename, cf_section_lineno(cs), strlen(secret), sizeof(c->secret) - 1); clients_free(list); return NULL; } if (strlen(shortnm) > sizeof(c->shortname)) { radlog(L_ERR, "%s[%d]: Client short name of length %d is greater than the allowed maximum of %d.", filename, cf_section_lineno(cs), strlen(shortnm), sizeof(c->shortname) - 1); clients_free(list); return NULL; } if((nastype = cf_section_value_find(cs, "nastype")) != NULL) { if(strlen(nastype) >= sizeof(c->nastype)) { radlog(L_ERR, "%s[%d]: nastype of length %d longer than the allowed maximum of %d", filename, cf_section_lineno(cs), strlen(nastype), sizeof(c->nastype) - 1); clients_free(list); return NULL; } } if((login = cf_section_value_find(cs, "login")) != NULL) { if(strlen(login) >= sizeof(c->login)) { radlog(L_ERR, "%s[%d]: login of length %d longer than the allowed maximum of %d", filename, cf_section_lineno(cs), strlen(login), sizeof(c->login) - 1); clients_free(list); return NULL; } } if((password = cf_section_value_find(cs, "password")) != NULL) { if(strlen(password) >= sizeof(c->password)) { radlog(L_ERR, "%s[%d]: password of length %d longer than the allowed maximum of %d", filename, cf_section_lineno(cs), strlen(password), sizeof(c->password) - 1); clients_free(list); return NULL; } } /* * The size is fine.. Let's create the buffer */ c = rad_malloc(sizeof(RADCLIENT)); memset(c, 0, sizeof(RADCLIENT)); /* * Look for netmasks. */ c->netmask = ~0; if (netmask) { int mask_length; mask_length = atoi(netmask + 1); if ((mask_length < 0) || (mask_length > 32)) { radlog(L_ERR, "%s[%d]: Invalid value '%s' for IP network mask.", filename, cf_section_lineno(cs), netmask + 1); clients_free(list); return NULL; } if (mask_length == 0) { c->netmask = 0; } else { c->netmask = ~0 << (32 - mask_length); } *netmask = '\0'; c->netmask = htonl(c->netmask); } c->ipaddr = ip_getaddr(hostnm); if (c->ipaddr == INADDR_NONE) { radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s", filename, cf_section_lineno(cs), hostnm); clients_free(list); return NULL; } /* * Update the client name again... */ if (netmask) { *netmask = '/'; c->ipaddr &= c->netmask; strcpy(c->longname, hostnm); } else { ip_hostname(c->longname, sizeof(c->longname), c->ipaddr); } strcpy((char *)c->secret, secret); strcpy(c->shortname, shortnm); if(nastype != NULL) strcpy(c->nastype, nastype); if(login != NULL) strcpy(c->login, login); if(password != NULL) strcpy(c->password, password); c->next = list; list = c; } return list;}/* * Code for handling listening on multiple ports. */static rad_listen_t listen_inst;static const char *listen_type = NULL;static const CONF_PARSER listen_config[] = { { "ipaddr", PW_TYPE_IPADDR, offsetof(rad_listen_t,ipaddr), NULL, "0.0.0.0" }, { "port", PW_TYPE_INTEGER, offsetof(rad_listen_t,port), NULL, "0" }, { "type", PW_TYPE_STRING_PTR, 0, &listen_type, "" }, { NULL, -1, 0, NULL, NULL } /* end the list */};static const LRAD_NAME_NUMBER listen_compare[] = { { "auth", RAD_LISTEN_AUTH }, { "acct", RAD_LISTEN_ACCT }, { NULL, 0 },};/* * Free a linked list of listeners; */static void listen_free(rad_listen_t *list){ while (list) { rad_listen_t *next = list->next; /* * The code below may have eaten the FD. */ if (list->fd >= 0) close(list->fd); free(list); list = next; }}/* * Binds a listener to a socket. */static int listen_bind(rad_listen_t *this){ struct sockaddr salocal; struct sockaddr_in *sa; rad_listen_t **last; /* * If the port is zero, then it means the appropriate * thing from /etc/services. */ if (this->port == 0) { struct servent *svp; switch (this->type) { case RAD_LISTEN_AUTH: svp = getservbyname ("radius", "udp"); if (svp != NULL) { this->port = ntohs(svp->s_port); } else { this->port = PW_AUTH_UDP_PORT; } break; case RAD_LISTEN_ACCT: svp = getservbyname ("radacct", "udp"); if (svp != NULL) { this->port = ntohs(svp->s_port); } else { this->port = PW_ACCT_UDP_PORT; } break; default: radlog(L_ERR|L_CONS, "ERROR: Non-fatal internal sanity check failed in bind."); return -1; } } /* * Find it in the old list, AFTER updating the port. If * it's there, use that, rather than creating a new * socket. This allows HUP's to re-use the old sockets, * which means that packets waiting in the socket queue * don't get lost. */ for (last = &mainconfig.listen; *last != NULL; last = &((*last)->next)) { if ((this->ipaddr == (*last)->ipaddr) && (this->type == (*last)->type) && (this->port == (*last)->port)) { this->fd = (*last)->fd; (*last)->fd = -1; return 0; } } /* * Create the socket. */ this->fd = socket(AF_INET, SOCK_DGRAM, 0); if (this->fd < 0) { return -1; } #ifdef WITH_UDPFROMTO /* * Initialize udpfromto for all sockets. */ if (udpfromto_init(this->fd) != 0) { radlog(L_ERR|L_CONS, "ERROR: udpfromto init failed."); }#endif sa = (struct sockaddr_in *) &salocal; memset ((char *) sa, '\0', sizeof(salocal)); sa->sin_family = AF_INET; sa->sin_addr.s_addr = this->ipaddr; sa->sin_port = htons(this->port); if (bind(this->fd, &salocal, sizeof(*sa)) < 0) { close(this->fd); this->fd = -1; return -1; } return 0;}static int last_proxy_port = 0;/* * Externally visible function for creating a new proxy LISTENER. * * For now, don't take ipaddr or port. */int proxy_new_listener(void){ int port; rad_listen_t *this; this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->ipaddr = mainconfig.myip; this->type = RAD_LISTEN_PROXY; /* * Proxying was not previously defined: die. */ if (last_proxy_port == 0) return -1; /* * Keep going until we find an unused port. */ for (port = last_proxy_port + 1; port < 64000; port++) { this->port = port; if (listen_bind(this) == 0) { rad_listen_t **last; last_proxy_port = port; /* * Add the new listener to the list of * listeners. */ for (last = &mainconfig.listen; *last != NULL; last = &((*last)->next)) { /* do nothing */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -