VALUE_PAIR *rc_avpair_new (int attrid, void *pval, int len, int vendorcode) { VALUE_PAIR *vp = (VALUE_PAIR *) NULL; DICT_ATTR *pda; if ((pda = rc_dict_getattr (attrid, vendorcode)) == (DICT_ATTR *) NULL) { error("rc_avpair_new: unknown attribute %d", attrid); } else { if ((vp = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) != (VALUE_PAIR *) NULL) { strncpy (vp->name, pda->name, sizeof (vp->name)); vp->attribute = attrid; vp->vendorcode = vendorcode; vp->next = (VALUE_PAIR *) NULL; vp->type = pda->type; if (rc_avpair_assign (vp, pval, len) == 0) { return vp; } free (vp); vp = (VALUE_PAIR *) NULL; } else novm("rc_avpair_new"); } return vp; }
void rnemd_init(struct beads *b) { inuse = 1; if (N % 2 == 1) fatal(EINVAL, "rnemd: N must be even"); if (dd < 0 || dd >= 3 || dg < 0 || dg >= 3) fatal(EINVAL, "rnemd: gradient / velocity invalid"); printf("rnemd: slabs=%ld swaps=%ld gradient=%ld velocity=%ld\n", N, sw, dg, dd); assert(N && sw); int blocklens[2] = {1, 2}; struct rnemd_list q; ptrdiff_t indices[2] = {(ptrdiff_t)&q.v - (ptrdiff_t)&q, (ptrdiff_t)&q.pos - (ptrdiff_t)&q}; MPI_Datatype old_types[2] = {MPI_DOUBLE, MPI_INT}; MPI_Type_struct(ARRAY_SIZE(blocklens), blocklens, indices, old_types, &rnemd_type); MPI_Type_commit(&rnemd_type); MPI_Comm_rank(comm_grid, &rank); MPI_Comm_size(comm_grid, &size); max = MAX(0x10000, 2 * sw * size); list = calloc(max, sizeof(*list)); if (list == NULL) novm("rnemd: list"); t0 = b->time; }
/* * demand_conf - configure the interface for doing dial-on-demand. */ void demand_conf(void) { int i; struct protent *protp; /* framemax = lcp_allowoptions[0].mru; if (framemax < PPP_MRU) */ framemax = PPP_MRU; framemax += PPP_HDRLEN + PPP_FCSLEN; frame = malloc(framemax); if (frame == NULL) novm("demand frame"); framelen = 0; pend_q = NULL; escape_flag = 0; flush_flag = 0; fcs = PPP_INITFCS; ppp_send_config(0, PPP_MRU, (u_int32_t) 0, 0, 0); ppp_recv_config(0, PPP_MRU, (u_int32_t) 0, 0, 0); #ifdef PPP_FILTER set_filters(&pass_filter, &active_filter); #endif /* * Call the demand_conf procedure for each protocol that's got one. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) if (!((*protp->demand_conf)(0))) die(1); }
int rc_read_mapfile(char *filename) { char buffer[1024]; FILE *mapfd; char *c, *name, *id, *q; struct map2id_s *p; int lnr = 0; if ((mapfd = fopen(filename,"r")) == NULL) { error("rc_read_mapfile: can't read %s: %s", filename, strerror(errno)); return (-1); } #define SKIP(p) while(*p && isspace(*p)) p++; while (fgets(buffer, sizeof(buffer), mapfd) != NULL) { lnr++; q = buffer; SKIP(q); if ((*q == '\n') || (*q == '#') || (*q == '\0')) continue; if (( c = strchr(q, ' ')) || (c = strchr(q,'\t'))) { *c = '\0'; c++; SKIP(c); name = q; id = c; if ((p = (struct map2id_s *)malloc(sizeof(*p))) == NULL) { novm("rc_read_mapfile"); return (-1); } p->name = strdup(name); p->id = atoi(id); p->next = map2id_list; map2id_list = p; } else { error("rc_read_mapfile: malformed line in %s, line %d", filename, lnr); return (-1); } } #undef SKIP fclose(mapfd); return 0; }
/* convention: * the most positive velocities are withdrawn from slab #0 and added to #N/2. */ void rnemd_sweep(struct beads *b) { if (!inuse) return; double idx = N / b->l[dg]; int i, c = 0; int o = col_index * b->groupsize; int o2 = (row_index + groups_per_row) * b->groupsize; struct rnemd_list list2[2 * sw]; /* create hitlist of this process */ for (i = 0; i < b->groupsize; i++) { int k = (int)floor(b->xv[o + i][dg] * idx); double v = b->xv[o + i][dd + 3]; if ((k == 0 && v > 0.) || (k == N / 2 && v < 0.)) { if (c >= max) { max += 0x10000; list = realloc(list, max * sizeof(*list)); if (list == NULL) novm("rnemd: list"); } list[c].v = v; list[c].pos = i; list[c++].rank = rank; } } debug("rnemd: %d beads in both slabs", c); qsort(list, c, sizeof(*list), rnemd_cmp); /* join hitlists of all processes */ memset(list2, 0, 2 * sw * sizeof(*list2)); for (i = 0; i < MIN(sw, c / 2); i++) { list2[i] = list[i]; list2[i + sw] = list[c - i - 1]; } MPI_Allgather(list2, 2 * sw, rnemd_type, list, 2 * sw, rnemd_type, comm_grid); qsort(list, 2 * sw * size, sizeof(*list), rnemd_cmp); /* now replace the velocities */ for (i = 0; i < sw; i++) { int ie = 2 * size * sw - 1 - i; if (rank == list[i].rank) { assert(b->xv[o + list[i].pos][dd + 3] * list[ie].v < 0.); b->xv[o + list[i].pos][dd + 3] = list[ie].v; b->xv[o2 + list[i].pos][dd + 3] = list[ie].v; P_sum += list[ie].v; } if (rank == list[ie].rank) { assert(b->xv[o + list[ie].pos][dd + 3] * list[i].v < 0.); b->xv[o + list[ie].pos][dd + 3] = list[i].v; b->xv[o2 + list[ie].pos][dd + 3] = list[i].v; P_sum -= list[i].v; } } bcast_beads(b); }
/********************************************************************** * %FUNCTION: PPPOEInitDevice * %ARGUMENTS: * None * %RETURNS: * * %DESCRIPTION: * Initializes PPPoE device. ***********************************************************************/ static int PPPOEInitDevice(void) { conn = malloc(sizeof(PPPoEConnection)); if (!conn) { novm("PPPoE session data"); } memset(conn, 0, sizeof(PPPoEConnection)); conn->acName = acName; conn->serviceName = pppd_pppoe_service; conn->ifName = devnam; conn->discoverySocket = -1; conn->sessionSocket = -1; return 1; }
/* * set_noauth_addr - set address(es) that can be used without authentication. * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. */ static int set_noauth_addr(char **argv) { char *addr = *argv; int l = strlen(addr); struct wordlist *wp; wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l + 1); if (wp == NULL) novm("allow-ip argument"); wp->word = (char *) (wp + 1); wp->next = noauth_addrs; BCOPY(addr, wp->word, l); noauth_addrs = wp; return 1; }
/********************************************************************** * %FUNCTION: PPPOEInitDevice * %ARGUMENTS: * None * %RETURNS: * * %DESCRIPTION: * Initializes PPPoE device. ***********************************************************************/ static int PPPOEInitDevice(void) { conn = malloc(sizeof(PPPoEConnection)); if (!conn) { novm("PPPoE session data"); } memset(conn, 0, sizeof(PPPoEConnection)); conn->ifName = devnam; conn->discoverySocket = -1; conn->sessionSocket = -1; conn->useHostUniq = 1; conn->printACNames = printACNames; conn->discoveryTimeout = PADI_TIMEOUT; return 1; }
static int set_option_auo(char *filename, int line, OPTION *option, char *p) { int *iptr; if (p == NULL) { warn("%s: line %d: bogus option value", filename, line); return (-1); } if ((iptr = (int *) malloc(sizeof(iptr))) == NULL) { novm("read_config"); return (-1); } *iptr = 0; p = strtok(p, ", \t"); if (!strncmp(p, "local", 5)) *iptr = AUTH_LOCAL_FST; else if (!strncmp(p, "radius", 6)) *iptr = AUTH_RADIUS_FST; else { error("%s: auth_order: unknown keyword: %s", filename, p); free(iptr); return (-1); } p = strtok(NULL, ", \t"); if (p && (*p != '\0')) { if ((*iptr & AUTH_RADIUS_FST) && !strcmp(p, "local")) *iptr = (*iptr) | AUTH_LOCAL_SND; else if ((*iptr & AUTH_LOCAL_FST) && !strcmp(p, "radius")) *iptr = (*iptr) | AUTH_RADIUS_SND; else { error("%s: auth_order: unknown or unexpected keyword: %s", filename, p); free(iptr); return (-1); } } option->val = (void *) iptr; return 0; }
static int set_option_int(char *filename, int line, OPTION *option, char *p) { int *iptr; if (p == NULL) { errorlog("%s: line %d: bogus option value", filename, line); return (-1); } if ((iptr = (int *) malloc(sizeof(iptr))) == NULL) { novm("read_config"); return (-1); } *iptr = atoi(p); option->val = (void *) iptr; return 0; }
void usp_read_header(FILE *FH, struct beads *b) { int i; b->usp = malloc(sizeof(*b->usp)); if (b->usp == NULL) novm("usp"); printf("Restraining two blocks with umbrella potentials (usp).\n"); fscanf(FH, "# usp blocks= "); for (i = 0; i < 2 ; i++) { if (fscanf(FH, "%d ", &b->usp->blocks[i]) != 1) fatal(EINVAL, "usp blocks!"); if (b->usp->blocks[i] >= b->blocks) fatal(EINVAL, "usp - block doesn't exist!"); } fscanf(FH, "xa0= "); for (i = 0; i < 2 ; i++) { if (fscanf(FH, "%lg ", &b->usp->x0s[i]) != 1) fatal(EINVAL, "usp xa0!"); } fscanf(FH, "xb0= "); for (i = 0; i < 2 ; i++) { if (fscanf(FH, "%lg ", &b->usp->x0s[2+i]) != 1) fatal(EINVAL, "usp xb0!"); } fscanf(FH, "k= "); if (fscanf(FH, "%lg ", &b->usp->k) != 1) fatal(EINVAL, "usp k!"); if (ismaster) { //MF_TODO use consecutive filenames by adding the stepnumber/startingtime into the name char fn[PATH_MAX]; sprintf(fn, "usp%09lu.dat", b->step); // MF BUSY HERE b->usp->fh = fopen(fn,"w"); if (b->usp->fh == NULL) fatal(EIO, "Couldn't open usp.dat for writing"); fprintf(b->usp->fh,"# blocks %d and %d were restrained to %lg %lg and %lg %lg in the tangential plane with k %lg\n", b->usp->blocks[0],b->usp->blocks[1],b->usp->x0s[0],b->usp->x0s[1],b->usp->x0s[2],b->usp->x0s[3],b->usp->k); fprintf(b->usp->fh,"# time, T1/2/N pos of block 1, orientation of block 1, T1/2/N pos of block 2, orientation of block 2\n"); } }
/* * Function: rc_avpair_copy * * Purpose: Return a copy of the existing list "p" ala strdup(). * */ VALUE_PAIR *rc_avpair_copy(VALUE_PAIR *p) { VALUE_PAIR *vp, *fp = NULL, *lp = NULL; while (p) { vp = malloc(sizeof(VALUE_PAIR)); if (!vp) { novm("rc_avpair_copy"); return NULL; /* leaks a little but so what */ } *vp = *p; if (!fp) fp = vp; if (lp) lp->next = vp; lp = vp; p = p->next; } return fp; }
/* * demand_conf - configure the interface for doing dial-on-demand. */ void demand_conf() { int i; const struct protent *protp; /* framemax = lcp_allowoptions[0].mru; if (framemax < PPP_MRU) */ framemax = PPP_MRU; framemax += PPP_HDRLEN + PPP_FCSLEN; frame = malloc(framemax); if (frame == NULL) novm("demand frame"); framelen = 0; pend_q = NULL; escape_flag = 0; flush_flag = 0; fcs = PPP_INITFCS; netif_set_mtu(pcb, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU)); if (ppp_send_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0 || ppp_recv_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0) fatal("Couldn't set up demand-dialled PPP interface: %m"); #ifdef PPP_FILTER set_filters(&pass_filter, &active_filter); #endif /* * Call the demand_conf procedure for each protocol that's got one. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->enabled_flag && protp->demand_conf != NULL) ((*protp->demand_conf)(pcb)); /* FIXME: find a way to die() here */ #if 0 if (!((*protp->demand_conf)(pcb))) die(1); #endif }
static void make_bundle_links(int append) { TDB_DATA key, rec; char *p; char entry[32]; int l; key.dptr = blinks_id; key.dsize = strlen(blinks_id); slprintf(entry, sizeof(entry), "%s;", db_key); p = entry; if (append) { rec = tdb_fetch(pppdb, key); if (rec.dptr != NULL && rec.dsize > 0) { rec.dptr[rec.dsize-1] = 0; if (strstr(rec.dptr, db_key) != NULL) { /* already in there? strange */ warn("link entry already exists in tdb"); return; } l = rec.dsize + strlen(entry); p = malloc(l); if (p == NULL) novm("bundle link list"); slprintf(p, l, "%s%s", rec.dptr, entry); } else { warn("bundle link list not found"); } if (rec.dptr != NULL) free(rec.dptr); } rec.dptr = p; rec.dsize = strlen(p) + 1; if (tdb_store(pppdb, key, rec, TDB_REPLACE)) error("couldn't %s bundle link list", append? "update": "create"); if (p != entry) free(p); }
/* * Make a new bundle or join us to an existing bundle * if we are doing multilink. */ int mp_join_bundle() { lcp_options *go = &lcp_gotoptions[0]; lcp_options *ho = &lcp_hisoptions[0]; int unit, pppd_pid; int l; char *p; TDB_DATA key, pid, rec; if (!go->neg_mrru || !ho->neg_mrru) { /* not doing multilink */ if (go->neg_mrru) notice("oops, multilink negotiated only for receive"); multilink = 0; if (demand) { /* already have a bundle */ cfg_bundle(0, 0, 0, 0); return 0; } make_new_bundle(0, 0, 0, 0); set_ifunit(1); return 0; } /* * Find the appropriate bundle or join a new one. * First we make up a name for the bundle. * The length estimate is worst-case assuming every * character has to be quoted. * * Note - RFC 1990 requires that an unnegotiated endpoint * discriminator value be equivalent to negotiating with class * zero. Do not test ho->neg_endpoint here. */ l = 4 * strlen(peer_authname) + 10; l += 3 * ho->endpoint.length + 8; if (bundle_name) l += 3 * strlen(bundle_name) + 2; bundle_id = malloc(l); if (bundle_id == NULL) novm("bundle identifier"); p = bundle_id; p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname); *p++ = '/'; p += slprintf(p, bundle_id+l-p, "%s", epdisc_to_str(&ho->endpoint)); if (bundle_name) p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); dbglog("bundle_id = %s", bundle_id+7); /* * For demand mode, we only need to configure the bundle * and attach the link. */ if (demand) { cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); script_setenv("BUNDLE", bundle_id + 7, 1); return 0; } /* * Check if the bundle ID is already in the database. */ unit = -1; tdb_writelock(pppdb); key.dptr = bundle_id; key.dsize = p - bundle_id; pid = tdb_fetch(pppdb, key); if (pid.dptr != NULL) { /* bundle ID exists, see if the pppd record exists */ rec = tdb_fetch(pppdb, pid); if (rec.dptr != NULL) { /* it does, parse the interface number */ parse_num(rec.dptr, "IFNAME=ppp", &unit); /* check the pid value */ if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) || !process_exists(pppd_pid) || !owns_unit(pid, unit)) unit = -1; free(rec.dptr); } free(pid.dptr); } if (unit >= 0) { /* attach to existing unit */ if (bundle_attach(unit)) { set_ifunit(0); script_setenv("BUNDLE", bundle_id + 7, 0); tdb_writeunlock(pppdb); info("Link attached to %s", ifname); return 1; } /* attach failed because bundle doesn't exist */ } /* we have to make a new bundle */ make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); set_ifunit(1); script_setenv("BUNDLE", bundle_id + 7, 1); tdb_writeunlock(pppdb); info("New bundle %s created", ifname); return 0; }
/* * scan_authfile - Scan an authorization file for a secret suitable * for authenticating `client' on `server'. The return value is -1 * if no secret is found, otherwise >= 0. The return value has * NONWILD_CLIENT set if the secret didn't have "*" for the client, and * NONWILD_SERVER set if the secret didn't have "*" for the server. * Any following words on the line (i.e. address authorization * info) are placed in a wordlist and returned in *addrs. */ static int scan_authfile(FILE *f, char *client, char *server, u_int32_t ipaddr, char *secret, struct wordlist **addrs, char *filename) { int newline, xxx; int got_flag, best_flag; FILE *sf; struct wordlist *ap, *addr_list, *alist, *alast; char word[MAXWORDLEN]; char atfile[MAXWORDLEN]; char lsecret[MAXWORDLEN]; if (addrs != NULL) *addrs = NULL; addr_list = NULL; if (!getword(f, word, &newline, filename)) return -1; /* file is empty??? */ newline = 1; best_flag = -1; for (;;) { /* * Skip until we find a word at the start of a line. */ while (!newline && getword(f, word, &newline, filename)) ; if (!newline) break; /* got to end of file */ /* * Got a client - check if it's a match or a wildcard. */ got_flag = 0; if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { newline = 0; continue; } if (!ISWILD(word)) got_flag = NONWILD_CLIENT; /* * Now get a server and check if it matches. */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; if (server != NULL && strcmp(word, server) != 0 && !ISWILD(word)) continue; if (!ISWILD(word)) got_flag |= NONWILD_SERVER; /* * Got some sort of a match - see if it's better than what * we have already. */ if (got_flag <= best_flag) continue; /* * Get the secret. */ if (!getword(f, word, &newline, filename)) break; if (newline) continue; /* * Special syntax: @filename means read secret from file. */ if (word[0] == '@') { strcpy(atfile, word+1); if ((sf = fopen(atfile, "r")) == NULL) { syslog(LOG_WARNING, "can't open indirect secret file %s", atfile); continue; } check_access(sf, atfile); if (!getword(sf, word, &xxx, atfile)) { syslog(LOG_WARNING, "no secret in indirect secret file %s", atfile); fclose(sf); continue; } fclose(sf); } if (secret != NULL) strcpy(lsecret, word); /* * Now read address authorization info and make a wordlist. */ alist = alast = NULL; for (;;) { if (!getword(f, word, &newline, filename) || newline) break; ap = (struct wordlist *) malloc(sizeof(struct wordlist) + strlen(word)); if (ap == NULL) novm("authorized addresses"); ap->next = NULL; strcpy(ap->word, word); if (alist == NULL) alist = ap; else alast->next = ap; alast = ap; } /* * Check if the given IP address is allowed by the wordlist. */ if (ipaddr != 0 && !ip_addr_check(ipaddr, alist)) { free_wordlist(alist); continue; } /* * This is the best so far; remember it. */ best_flag = got_flag; if (addr_list) free_wordlist(addr_list); addr_list = alist; if (secret != NULL) strcpy(secret, lsecret); if (!newline) break; } if (addrs != NULL) *addrs = addr_list; else if (addr_list != NULL) free_wordlist(addr_list); non_wildclient = (best_flag & NONWILD_CLIENT) && client != NULL && *client != '\0'; return best_flag; }
int rc_avpair_parse (char *buffer, VALUE_PAIR **first_pair) { int mode; char attrstr[AUTH_ID_LEN]; char valstr[AUTH_ID_LEN]; DICT_ATTR *attr = NULL; DICT_VALUE *dval; VALUE_PAIR *pair; VALUE_PAIR *link; struct tm *tm; time_t timeval; mode = PARSE_MODE_NAME; while (*buffer != '\n' && *buffer != '\0') { if (*buffer == ' ' || *buffer == '\t') { buffer++; continue; } switch (mode) { case PARSE_MODE_NAME: /* Attribute Name */ rc_fieldcpy (attrstr, &buffer); if ((attr = rc_dict_findattr (attrstr)) == (DICT_ATTR *) NULL) { error("rc_avpair_parse: unknown attribute"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } mode = PARSE_MODE_EQUAL; break; case PARSE_MODE_EQUAL: /* Equal sign */ if (*buffer == '=') { mode = PARSE_MODE_VALUE; buffer++; } else { error("rc_avpair_parse: missing or misplaced equal sign"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } break; case PARSE_MODE_VALUE: /* Value */ rc_fieldcpy (valstr, &buffer); if ((pair = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) == (VALUE_PAIR *) NULL) { novm("rc_avpair_parse"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } strcpy (pair->name, attr->name); pair->attribute = attr->value; pair->type = attr->type; pair->vendorcode = attr->vendorcode; switch (pair->type) { case PW_TYPE_STRING: strcpy ((char *)pair->strvalue, valstr); pair->lvalue = strlen(valstr); break; case PW_TYPE_INTEGER: if (isdigit (*valstr)) { pair->lvalue = atoi (valstr); } else { if ((dval = rc_dict_findval (valstr)) == (DICT_VALUE *) NULL) { error("rc_avpair_parse: unknown attribute value: %s", valstr); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } free (pair); return (-1); } else { pair->lvalue = dval->value; } } break; case PW_TYPE_IPADDR: pair->lvalue = rc_get_ipaddr(valstr); break; case PW_TYPE_DATE: timeval = time (0); tm = localtime (&timeval); tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; rc_str2tm (valstr, tm); #ifdef TIMELOCAL pair->lvalue = (UINT4) timelocal (tm); #else /* TIMELOCAL */ pair->lvalue = (UINT4) mktime (tm); #endif /* TIMELOCAL */ break; default: error("rc_avpair_parse: unknown attribute type %d", pair->type); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } free (pair); return (-1); } pair->next = (VALUE_PAIR *) NULL; if (*first_pair == (VALUE_PAIR *) NULL) { *first_pair = pair; } else { link = *first_pair; while (link->next != (VALUE_PAIR *) NULL) { link = link->next; } link->next = pair; } mode = PARSE_MODE_NAME; break; default: mode = PARSE_MODE_NAME; break; } } return (0); }
/* * Function: rc_extract_vendor_specific_attributes * * Purpose: Extracts vendor-specific attributes, assuming they are in * the "SHOULD" format recommended by RCF 2138. * * Returns: found value_pair * */ static void rc_extract_vendor_specific_attributes(int attrlen, unsigned char *ptr, VALUE_PAIR **vp) { int vendor_id; int vtype; int vlen; UINT4 lvalue; DICT_ATTR *attr; VALUE_PAIR *pair; /* ptr is sitting at vendor-ID */ if (attrlen < 8) { /* Nothing to see here... */ return; } /* High-order octet of Vendor-Id must be zero (RFC2138) */ if (*ptr) { return; } /* Extract vendor_id */ vendor_id = (int) ( ((unsigned int) ptr[1]) * 256 * 256 + ((unsigned int) ptr[2]) * 256 + ((unsigned int) ptr[3])); /* Bump ptr up to contents */ ptr += 4; /* Set attrlen to length of data */ attrlen -= 4; for (; attrlen; attrlen -= vlen+2, ptr += vlen) { vtype = *ptr++; vlen = *ptr++; vlen -= 2; if (vlen < 0 || vlen > attrlen - 2) { /* Do not log an error. We are supposed to be able to cope with arbitrary vendor-specific gunk */ return; } /* Looks plausible... */ if ((attr = rc_dict_getattr(vtype, vendor_id)) == NULL) { continue; } /* TODO: Check that length matches data size!!!!! */ pair = (VALUE_PAIR *) malloc(sizeof(VALUE_PAIR)); if (!pair) { novm("rc_avpair_gen"); return; } strcpy(pair->name, attr->name); pair->attribute = attr->value; pair->vendorcode = vendor_id; pair->type = attr->type; pair->next = NULL; switch (attr->type) { case PW_TYPE_STRING: memcpy (pair->strvalue, (char *) ptr, (size_t) vlen); pair->strvalue[vlen] = '\0'; pair->lvalue = vlen; rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair); break; case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: memcpy ((char *) &lvalue, (char *) ptr, sizeof (UINT4)); pair->lvalue = ntohl (lvalue); rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair); break; default: warn("rc_avpair_gen: %s has unknown type", attr->name); free (pair); break; } } }
VALUE_PAIR *rc_avpair_gen (AUTH_HDR *auth) { int length; int x_len; int attribute; int attrlen; UINT4 lvalue; unsigned char *x_ptr; unsigned char *ptr; DICT_ATTR *attr; VALUE_PAIR *vp; VALUE_PAIR *pair; unsigned char hex[3]; /* For hex string conversion. */ char buffer[512]; /* * Extract attribute-value pairs */ ptr = auth->data; length = ntohs ((unsigned short) auth->length) - AUTH_HDR_LEN; vp = (VALUE_PAIR *) NULL; while (length > 0) { attribute = *ptr++; attrlen = *ptr++; attrlen -= 2; if (attrlen < 0) { error("rc_avpair_gen: received attribute with invalid length"); break; } /* Handle vendor-specific specially */ if (attribute == PW_VENDOR_SPECIFIC) { rc_extract_vendor_specific_attributes(attrlen, ptr, &vp); ptr += attrlen; length -= (attrlen + 2); continue; } if ((attr = rc_dict_getattr (attribute, VENDOR_NONE)) == (DICT_ATTR *) NULL) { *buffer= '\0'; /* Initial length. */ for (x_ptr = ptr, x_len = attrlen ; x_len > 0 ; x_len--, x_ptr++) { sprintf ((char *)hex, "%2.2X", *x_ptr); strcat (buffer, (char *)hex); } warn("rc_avpair_gen: received unknown attribute %d of length %d: 0x%s", attribute, attrlen, buffer); } else { if ((pair = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) == (VALUE_PAIR *) NULL) { novm("rc_avpair_gen"); rc_avpair_free(vp); return NULL; } strcpy (pair->name, attr->name); pair->attribute = attr->value; pair->vendorcode = VENDOR_NONE; pair->type = attr->type; pair->next = (VALUE_PAIR *) NULL; switch (attr->type) { case PW_TYPE_STRING: memcpy (pair->strvalue, (char *) ptr, (size_t) attrlen); pair->strvalue[attrlen] = '\0'; pair->lvalue = attrlen; rc_avpair_insert (&vp, (VALUE_PAIR *) NULL, pair); break; case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: memcpy ((char *) &lvalue, (char *) ptr, sizeof (UINT4)); pair->lvalue = ntohl (lvalue); rc_avpair_insert (&vp, (VALUE_PAIR *) NULL, pair); break; default: warn("rc_avpair_gen: %s has unknown type", attr->name); free (pair); break; } } ptr += attrlen; length -= attrlen + 2; } return (vp); }
static int tacacs_auth(char *t_user, char *t_passwd, char**t_msgp, struct wordlist **t_paddrs, struct wordlist **t_popts) { int tac_fd; char *msg; struct areply arep; struct tac_attrib *attr; struct tac_attrib *attrentry; struct wordlist **pnextaddr; struct wordlist *addr; int addrlen; int ret; if (prev_pap_auth_hook) { ret = prev_pap_auth_hook(t_user, t_passwd, t_msgp, t_paddrs, t_popts); if (ret >= 0) { return ret; } } if (!use_tacacs) return -1; *t_msgp = "TACACS+ server failed"; *t_popts = NULL; /* start authentication */ if (tac_server == -1) return 0; tac_fd = tac_connect(&tac_server, 1); if (tac_fd < 0) return 0; if (tac_authen_pap_send(tac_fd, t_user, t_passwd, tty) < 0) return 0; msg = tac_authen_pap_read(tac_fd); if (msg != NULL) { *t_msgp = msg; return 0; } close(tac_fd); /* user/password is valid, now check authorization */ if (use_authorize) { tac_fd = tac_connect(&tac_server, 1); if (tac_fd < 0) return 0; attr = NULL; tac_add_attrib(&attr, "service", "ppp"); tac_add_attrib(&attr, "protocol", "ip"); if (tac_author_send(tac_fd, t_user, tty, attr) < 0) return 0; tac_author_read(tac_fd, &arep); if (arep.status != AUTHOR_STATUS_PASS_ADD && arep.status != AUTHOR_STATUS_PASS_REPL) { *t_msgp = arep.msg; return 0; } tac_free_attrib(&attr); close(tac_fd); /* Build up list of allowable addresses */ *t_paddrs = NULL; /* Default to allow all */ pnextaddr = t_paddrs; for (attrentry=arep.attr; attrentry!=NULL; attrentry=attrentry->next) { if (strncmp(attrentry->attr, "addr=", 5) == 0) { addrlen = attrentry->attr_len - 5; /* Allocate a buffer for both the structure and the address */ addr = (struct wordlist*)malloc(sizeof(struct wordlist) + addrlen + 1); if (addr == NULL) novm("TACACS+ address"); addr->word = (char*)(addr+1); strncpy(addr->word, attrentry->attr+5, addrlen); addr->word[addrlen] = '\0'; addr->next = NULL; *pnextaddr = addr; pnextaddr = &addr->next; } } tac_free_attrib(&arep.attr); } *t_msgp = "Login succeeded"; syslog(LOG_INFO,"TACACS+ login succeeded for %s", t_user); authorized = 1; return 1; }
/* * Make a new bundle or join us to an existing bundle * if we are doing multilink. */ int mp_join_bundle() { lcp_options *go = &lcp_gotoptions[0]; lcp_options *ho = &lcp_hisoptions[0]; lcp_options *ao = &lcp_allowoptions[0]; int unit, pppd_pid; int l, mtu; char *p; TDB_DATA key, pid, rec; if (doing_multilink) { /* have previously joined a bundle */ if (!go->neg_mrru || !ho->neg_mrru) { notice("oops, didn't get multilink on renegotiation"); lcp_close(pcb, "multilink required"); return 0; } /* XXX should check the peer_authname and ho->endpoint are the same as previously */ return 0; } if (!go->neg_mrru || !ho->neg_mrru) { /* not doing multilink */ if (go->neg_mrru) notice("oops, multilink negotiated only for receive"); mtu = ho->neg_mru? ho->mru: PPP_MRU; if (mtu > ao->mru) mtu = ao->mru; if (demand) { /* already have a bundle */ cfg_bundle(0, 0, 0, 0); netif_set_mtu(pcb, mtu); return 0; } make_new_bundle(0, 0, 0, 0); set_ifunit(1); netif_set_mtu(pcb, mtu); return 0; } doing_multilink = 1; /* * Find the appropriate bundle or join a new one. * First we make up a name for the bundle. * The length estimate is worst-case assuming every * character has to be quoted. */ l = 4 * strlen(peer_authname) + 10; if (ho->neg_endpoint) l += 3 * ho->endpoint.length + 8; if (bundle_name) l += 3 * strlen(bundle_name) + 2; bundle_id = malloc(l); if (bundle_id == 0) novm("bundle identifier"); p = bundle_id; p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname); if (ho->neg_endpoint || bundle_name) *p++ = '/'; if (ho->neg_endpoint) p += slprintf(p, bundle_id+l-p, "%s", epdisc_to_str(&ho->endpoint)); if (bundle_name) p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); /* Make the key for the list of links belonging to the bundle */ l = p - bundle_id; blinks_id = malloc(l + 7); if (blinks_id == NULL) novm("bundle links key"); slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7); /* * For demand mode, we only need to configure the bundle * and attach the link. */ mtu = LWIP_MIN(ho->mrru, ao->mru); if (demand) { cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); netif_set_mtu(pcb, mtu); script_setenv("BUNDLE", bundle_id + 7, 1); return 0; } /* * Check if the bundle ID is already in the database. */ unit = -1; lock_db(); key.dptr = bundle_id; key.dsize = p - bundle_id; pid = tdb_fetch(pppdb, key); if (pid.dptr != NULL) { /* bundle ID exists, see if the pppd record exists */ rec = tdb_fetch(pppdb, pid); if (rec.dptr != NULL && rec.dsize > 0) { /* make sure the string is null-terminated */ rec.dptr[rec.dsize-1] = 0; /* parse the interface number */ parse_num(rec.dptr, "IFNAME=ppp", &unit); /* check the pid value */ if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) || !process_exists(pppd_pid) || !owns_unit(pid, unit)) unit = -1; free(rec.dptr); } free(pid.dptr); } if (unit >= 0) { /* attach to existing unit */ if (bundle_attach(unit)) { set_ifunit(0); script_setenv("BUNDLE", bundle_id + 7, 0); make_bundle_links(1); unlock_db(); info("Link attached to %s", ifname); return 1; } /* attach failed because bundle doesn't exist */ } /* we have to make a new bundle */ make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); set_ifunit(1); netif_set_mtu(pcb, mtu); script_setenv("BUNDLE", bundle_id + 7, 1); make_bundle_links(pcb); unlock_db(); info("New bundle %s created", ifname); multilink_master = 1; return 0; }
static int setdevname_pppol2tp(char **argv) { union { char buffer[128]; struct sockaddr pppol2tp; } s; int len = sizeof(s); char **a; int tmp; int tmp_len = sizeof(tmp); if (device_got_set) return 0; if (!int_option(*argv, &pppol2tp_fd)) return 0; if(getsockname(pppol2tp_fd, (struct sockaddr *)&s, &len) < 0) { fatal("Given FD for PPPoL2TP socket invalid (%s)", strerror(errno)); } if(s.pppol2tp.sa_family != AF_PPPOX) { fatal("Socket of not a PPPoX socket"); } /* Do a test getsockopt() to ensure that the kernel has the necessary * feature available. */ if (getsockopt(pppol2tp_fd, SOL_PPPOL2TP, PPPOL2TP_SO_DEBUG, &tmp, &tmp_len) < 0) { fatal("PPPoL2TP kernel driver not installed"); } pppol2tp_fd_str = strdup(*argv); if (pppol2tp_fd_str == NULL) novm("PPPoL2TP FD"); /* Setup option defaults. Compression options are disabled! */ modem = 0; lcp_allowoptions[0].neg_accompression = 1; lcp_wantoptions[0].neg_accompression = 0; lcp_allowoptions[0].neg_pcompression = 1; lcp_wantoptions[0].neg_pcompression = 0; ccp_allowoptions[0].deflate = 0; ccp_wantoptions[0].deflate = 0; ipcp_allowoptions[0].neg_vj = 0; ipcp_wantoptions[0].neg_vj = 0; ccp_allowoptions[0].bsd_compress = 0; ccp_wantoptions[0].bsd_compress = 0; the_channel = &pppol2tp_channel; device_got_set = 1; return 1; }
int rc_read_dictionary (char *filename) { FILE *dictfd; char dummystr[AUTH_ID_LEN]; char namestr[AUTH_ID_LEN]; char valstr[AUTH_ID_LEN]; char attrstr[AUTH_ID_LEN]; char typestr[AUTH_ID_LEN]; char vendorstr[AUTH_ID_LEN]; int line_no; DICT_ATTR *attr; DICT_VALUE *dval; VENDOR_DICT *vdict; char buffer[256]; int value; int type; int n; int retcode; if ((dictfd = fopen (filename, "r")) == (FILE *) NULL) { errorlog( "rc_read_dictionary: couldn't open dictionary %s: %s", filename, strerror(errno)); return (-1); } line_no = 0; retcode = 0; while (fgets (buffer, sizeof (buffer), dictfd) != (char *) NULL) { line_no++; /* Skip empty space */ if (*buffer == '#' || *buffer == '\0' || *buffer == '\n') { continue; } if (strncmp (buffer, "VENDOR", 6) == 0) { /* Read the VENDOR line */ if (sscanf(buffer, "%s%s%d", dummystr, namestr, &value) != 3) { errorlog("rc_read_dictionary: invalid vendor on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* Validate entry */ if (strlen (namestr) > NAME_LENGTH) { errorlog("rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* Create new vendor entry */ vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT)); if (!vdict) { novm("rc_read_dictionary"); retcode = -1; break; } strcpy(vdict->vendorname, namestr); vdict->vendorcode = value; vdict->attributes = NULL; vdict->next = vendor_dictionaries; vendor_dictionaries = vdict; } else if (strncmp (buffer, "ATTRIBUTE", 9) == 0) { /* Read the ATTRIBUTE line. It is one of: * ATTRIBUTE attr_name attr_val type OR * ATTRIBUTE attr_name attr_val type vendor */ vendorstr[0] = 0; n = sscanf(buffer, "%s%s%s%s%s", dummystr, namestr, valstr, typestr, vendorstr); if (n != 4 && n != 5) { errorlog("rc_read_dictionary: invalid attribute on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* * Validate all entries */ if (strlen (namestr) > NAME_LENGTH) { errorlog("rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (strlen (vendorstr) > NAME_LENGTH) { errorlog("rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (!isdigit (*valstr)) { errorlog("rc_read_dictionary: invalid value on line %d of dictionary %s", line_no, filename); retcode = -1; break; } value = atoi (valstr); if (strcmp (typestr, "string") == 0) { type = PW_TYPE_STRING; } else if (strcmp (typestr, "integer") == 0) { type = PW_TYPE_INTEGER; } else if (strcmp (typestr, "ipaddr") == 0) { type = PW_TYPE_IPADDR; } else if (strcmp (typestr, "date") == 0) { type = PW_TYPE_DATE; } else { errorlog("rc_read_dictionary: invalid type on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* Search for vendor if supplied */ if (*vendorstr) { vdict = rc_dict_findvendor(vendorstr); if (!vdict) { errorlog("rc_read_dictionary: unknown vendor on line %d of dictionary %s", line_no, filename); retcode = -1; break; } } else { vdict = NULL; } /* Create a new attribute for the list */ if ((attr = (DICT_ATTR *) malloc (sizeof (DICT_ATTR))) == (DICT_ATTR *) NULL) { novm("rc_read_dictionary"); retcode = -1; break; } strcpy (attr->name, namestr); if (vdict) { attr->vendorcode = vdict->vendorcode; } else { attr->vendorcode = VENDOR_NONE; } attr->value = value; attr->type = type; /* Insert it into the list */ if (vdict) { attr->next = vdict->attributes; vdict->attributes = attr; } else { attr->next = dictionary_attributes; dictionary_attributes = attr; } } else if (strncmp (buffer, "VALUE", 5) == 0) { /* Read the VALUE line */ if (sscanf (buffer, "%s%s%s%s", dummystr, attrstr, namestr, valstr) != 4) { errorlog("rc_read_dictionary: invalid value entry on line %d of dictionary %s", line_no, filename); retcode = -1; break; } /* * Validate all entries */ if (strlen (attrstr) > NAME_LENGTH) { errorlog("rc_read_dictionary: invalid attribute length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (strlen (namestr) > NAME_LENGTH) { errorlog("rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (!isdigit (*valstr)) { errorlog("rc_read_dictionary: invalid value on line %d of dictionary %s", line_no, filename); retcode = -1; break; } value = atoi (valstr); /* Create a new VALUE entry for the list */ if ((dval = (DICT_VALUE *) malloc (sizeof (DICT_VALUE))) == (DICT_VALUE *) NULL) { novm("rc_read_dictionary"); retcode = -1; break; } strcpy (dval->attrname, attrstr); strcpy (dval->name, namestr); dval->value = value; /* Insert it into the list */ dval->next = dictionary_values; dictionary_values = dval; } else if (strncmp (buffer, "INCLUDE", 7) == 0) { /* Read the INCLUDE line */ if (sscanf (buffer, "%s%s", dummystr, namestr) != 2) { errorlog("rc_read_dictionary: invalid include entry on line %d of dictionary %s", line_no, filename); retcode = -1; break; } if (rc_read_dictionary(namestr) == -1) { retcode = -1; break; } } } fclose (dictfd); return retcode; }
int lock (char *dev) { char hdb_lock_buffer[12]; int fd, n; int pid; char *p; p = strrchr(dev, '/'); if (p != NULL) { dev = ++p; } lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); if (lock_file == NULL) { novm("lock file name"); } strcpy (lock_file, LOCK_PREFIX); strcat (lock_file, dev); /* * Attempt to create the lock file at this point. */ while (1) { fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644); if (fd >= 0) { pid = getpid(); #ifndef PID_BINARY sprintf (hdb_lock_buffer, "%010d\n", pid); write (fd, hdb_lock_buffer, 11); #else write(fd, &pid, sizeof (pid)); #endif close(fd); return 0; } /* * If the file exists then check to see if the pid is stale */ if (errno == EEXIST) { fd = open(lock_file, O_RDONLY, 0); if (fd < 0) { if (errno == ENOENT) /* This is just a timing problem. */ { continue; } break; } /* Read the lock file to find out who has the device locked */ n = read (fd, hdb_lock_buffer, 11); close (fd); if (n < 0) { syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file); break; } /* See the process still exists. */ if (n > 0) { #ifndef PID_BINARY hdb_lock_buffer[n] = '\0'; sscanf (hdb_lock_buffer, " %d", &pid); #else pid = ((int *) hdb_lock_buffer)[0]; #endif if (pid == 0 || (kill(pid, 0) == -1 && errno == ESRCH)) { n = 0; } } /* If the process does not exist then try to remove the lock */ if (n == 0 && unlink (lock_file) == 0) { syslog (LOG_NOTICE, "Removed stale lock on %s (pid %d)", dev, pid); continue; } syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, pid); break; } syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file); break; } free(lock_file); lock_file = NULL; return -1; }