int vmps_process(REQUEST *request) { DEBUG2("Doing VMPS"); module_post_auth(0, request); DEBUG2("Done VMPS"); request->reply->code = PW_AUTHENTICATION_ACK; return 0; }
/* * Post-authentication step processes the response before it is * sent to the NAS. It can receive both Access-Accept and Access-Reject * replies. */ int rad_postauth(REQUEST *request) { int result; int postauth_type = 0; VALUE_PAIR *vp; /* * Do post-authentication calls. ignoring the return code. */ vp = pairfind(request->config_items, PW_POST_AUTH_TYPE); if (vp) { RDEBUG2("Using Post-Auth-Type %s", dict_valnamebyattr(PW_POST_AUTH_TYPE, vp->vp_integer)); postauth_type = vp->vp_integer; } result = module_post_auth(postauth_type, request); switch (result) { /* * The module failed, or said to reject the user: Do so. */ case RLM_MODULE_FAIL: case RLM_MODULE_INVALID: case RLM_MODULE_REJECT: case RLM_MODULE_USERLOCK: default: request->reply->code = PW_AUTHENTICATION_REJECT; result = RLM_MODULE_REJECT; break; /* * The module handled the request, cancel the reply. */ case RLM_MODULE_HANDLED: /* FIXME */ break; /* * The module had a number of OK return codes. */ case RLM_MODULE_NOOP: case RLM_MODULE_NOTFOUND: case RLM_MODULE_OK: case RLM_MODULE_UPDATED: result = RLM_MODULE_OK; break; } return result; }
/* * Post-authentication step processes the response before it is * sent to the NAS. It can receive both Access-Accept and Access-Reject * replies. */ int rad_postauth(REQUEST *request) { int result; int postauth_type = 0; VALUE_PAIR *postauth_type_item = NULL; /* * Do post-authentication calls. ignoring the return code. */ postauth_type_item = pairfind(request->config_items, PW_POST_AUTH_TYPE); if (postauth_type_item) postauth_type = postauth_type_item->lvalue; result = module_post_auth(postauth_type, request); switch (result) { default: break; /* * The module failed, or said to reject the user: Do so. */ case RLM_MODULE_FAIL: case RLM_MODULE_REJECT: case RLM_MODULE_USERLOCK: case RLM_MODULE_INVALID: request->reply->code = PW_AUTHENTICATION_REJECT; result = RLM_MODULE_REJECT; break; /* * The module had a number of OK return codes. */ case RLM_MODULE_NOTFOUND: case RLM_MODULE_NOOP: case RLM_MODULE_UPDATED: case RLM_MODULE_OK: case RLM_MODULE_HANDLED: result = RLM_MODULE_OK; break; } return result; }
static int dhcp_process(REQUEST *request) { int rcode; VALUE_PAIR *vp; vp = pairfind(request->packet->vps, 53, DHCP_MAGIC_VENDOR); /* DHCP-Message-Type */ if (vp) { DICT_VALUE *dv = dict_valbyattr(53, DHCP_MAGIC_VENDOR, vp->vp_integer); DEBUG("Trying sub-section dhcp %s {...}", dv->name ? dv->name : "<unknown>"); rcode = module_post_auth(vp->vp_integer, request); } else { DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!"); rcode = RLM_MODULE_FAIL; } /* * For messages from a client, look for Relay attribute, * and forward it if necessary. */ vp = NULL; if (request->packet->data[0] == 1) { vp = pairfind(request->config_items, 270, DHCP_MAGIC_VENDOR); } if (vp) { VALUE_PAIR *giaddr; /* * Find the original giaddr. * FIXME: Maybe look in the original packet? * * It's invalid to have giaddr=0 AND a relay option */ giaddr = pairfind(request->packet->vps, 266, DHCP_MAGIC_VENDOR); if (giaddr && (giaddr->vp_ipaddr == htonl(INADDR_ANY))) { if (pairfind(request->packet->vps, 82, DHCP_MAGIC_VENDOR)) { RDEBUG("DHCP: Received packet with giaddr = 0 and containing relay option: Discarding packet"); return 1; } } if (request->packet->data[3] > 10) { RDEBUG("DHCP: Number of hops is greater than 10: not relaying"); return 1; } /* * Forward a reply... */ pairfree(&request->reply->vps); request->reply->vps = paircopy(request->packet->vps); request->reply->code = request->packet->code; request->reply->id = request->packet->id; request->reply->src_ipaddr = request->packet->dst_ipaddr; request->reply->src_port = request->packet->dst_port; request->reply->dst_ipaddr.af = AF_INET; request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; /* * Don't change the destination port. It's the * server port. */ /* * Hop count goes up. */ vp = pairfind(request->reply->vps, 259, DHCP_MAGIC_VENDOR); if (vp) vp->vp_integer++; return 1; } /* * Responses from a server. Handle them differently. */ if (request->packet->data[0] == 2) { pairfree(&request->reply->vps); request->reply->vps = paircopy(request->packet->vps); request->reply->code = request->packet->code; request->reply->id = request->packet->id; /* * Delete any existing giaddr. If we received a * message from the server, then we're NOT the * server. So we must be the destination of the * giaddr field. */ pairdelete(&request->packet->vps, 266, DHCP_MAGIC_VENDOR); /* * Search for client IP address. */ vp = pairfind(request->packet->vps, 264, DHCP_MAGIC_VENDOR); if (!vp) { request->reply->code = 0; RDEBUG("DHCP: No YIAddr in the reply. Discarding packet"); return 1; } /* * FROM us, TO the client's IP, OUR port + 1. */ request->reply->src_ipaddr = request->packet->dst_ipaddr; request->reply->src_port = request->packet->dst_port; request->reply->dst_ipaddr.af = AF_INET; request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; request->reply->dst_port = request->packet->dst_port + 1; /* * Hop count goes down. */ vp = pairfind(request->reply->vps, 259, DHCP_MAGIC_VENDOR); if (vp && (vp->vp_integer > 0)) vp->vp_integer--; /* * FIXME: Keep original somewhere? If the * broadcast flags are set, use them here? */ return 1; } vp = pairfind(request->reply->vps, 53, DHCP_MAGIC_VENDOR); /* DHCP-Message-Type */ if (vp) { request->reply->code = vp->vp_integer; if ((request->reply->code != 0) && (request->reply->code < PW_DHCP_OFFSET)) { request->reply->code += PW_DHCP_OFFSET; } } else switch (rcode) { case RLM_MODULE_OK: case RLM_MODULE_UPDATED: if (request->packet->code == PW_DHCP_DISCOVER) { request->reply->code = PW_DHCP_OFFER; break; } else if (request->packet->code == PW_DHCP_REQUEST) { request->reply->code = PW_DHCP_ACK; break; } request->reply->code = PW_DHCP_NAK; break; default: case RLM_MODULE_REJECT: case RLM_MODULE_FAIL: case RLM_MODULE_INVALID: case RLM_MODULE_NOOP: case RLM_MODULE_NOTFOUND: if (request->packet->code == PW_DHCP_DISCOVER) { request->reply->code = 0; /* ignore the packet */ } else { request->reply->code = PW_DHCP_NAK; } break; case RLM_MODULE_HANDLED: break; } /* * Releases don't get replies. */ if (request->packet->code == PW_DHCP_RELEASE) { request->reply->code = 0; } return 1; }
static int dhcp_process(REQUEST *request) { int rcode; VALUE_PAIR *vp; vp = pairfind(request->packet->vps, 53, DHCP_MAGIC_VENDOR); /* DHCP-Message-Type */ if (vp) { DICT_VALUE *dv = dict_valbyattr(53, DHCP_MAGIC_VENDOR, vp->vp_integer); DEBUG("Trying sub-section dhcp %s {...}", dv->name ? dv->name : "<unknown>"); rcode = module_post_auth(vp->vp_integer, request); } else { DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!"); rcode = RLM_MODULE_FAIL; } /* * Look for Relay attribute, and forward it if necessary. */ vp = pairfind(request->config_items, 270, DHCP_MAGIC_VENDOR); if (vp) { VALUE_PAIR *giaddr; RADIUS_PACKET relayed; request->reply->code = 0; /* don't reply to the client */ /* * Find the original giaddr. * FIXME: Maybe look in the original packet? * * It's invalid to have giaddr=0 AND a relay option */ giaddr = pairfind(request->packet->vps, 266, DHCP_MAGIC_VENDOR); if (giaddr && (giaddr->vp_ipaddr == htonl(INADDR_ANY))) { if (pairfind(request->packet->vps, 82, DHCP_MAGIC_VENDOR)) { RDEBUG("DHCP: Received packet with giaddr = 0 and containing relay option: Discarding packet"); return 1; } /* * FIXME: Add cache by XID. */ RDEBUG("DHCP: Cannot yet relay packets with giaddr = 0"); return 1; } if (request->packet->data[3] > 10) { RDEBUG("DHCP: Number of hops is greater than 10: not relaying"); return 1; } /* * Forward it VERBATIM to the next server, rather * than to the client. */ memcpy(&relayed, request->packet, sizeof(relayed)); relayed.dst_ipaddr.af = AF_INET; relayed.dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; relayed.dst_port = request->packet->dst_port; relayed.src_ipaddr = request->packet->dst_ipaddr; relayed.src_port = request->packet->dst_port; relayed.data = rad_malloc(relayed.data_len); memcpy(relayed.data, request->packet->data, request->packet->data_len); relayed.vps = NULL; /* * The only field that changes is the number of hops */ relayed.data[3]++; /* number of hops */ /* * Forward the relayed packet VERBATIM, don't * respond to the client, and forget completely * about this request. */ fr_dhcp_send(&relayed); free(relayed.data); return 1; } vp = pairfind(request->reply->vps, 53, DHCP_MAGIC_VENDOR); /* DHCP-Message-Type */ if (vp) { request->reply->code = vp->vp_integer; if ((request->reply->code != 0) && (request->reply->code < PW_DHCP_OFFSET)) { request->reply->code += PW_DHCP_OFFSET; } } else switch (rcode) { case RLM_MODULE_OK: case RLM_MODULE_UPDATED: if (request->packet->code == PW_DHCP_DISCOVER) { request->reply->code = PW_DHCP_OFFER; break; } else if (request->packet->code == PW_DHCP_REQUEST) { request->reply->code = PW_DHCP_ACK; break; } request->reply->code = PW_DHCP_NAK; break; default: case RLM_MODULE_REJECT: case RLM_MODULE_FAIL: case RLM_MODULE_INVALID: case RLM_MODULE_NOOP: case RLM_MODULE_NOTFOUND: if (request->packet->code == PW_DHCP_DISCOVER) { request->reply->code = 0; /* ignore the packet */ } else { request->reply->code = PW_DHCP_NAK; } break; case RLM_MODULE_HANDLED: break; } /* * Releases don't get replies. */ if (request->packet->code == PW_DHCP_RELEASE) { request->reply->code = 0; } return 1; }
static int dhcp_process(REQUEST *request) { int rcode; unsigned int i; VALUE_PAIR *vp; dhcp_socket_t *sock; vp = pairfind(request->packet->vps, DHCP2ATTR(53)); /* DHCP-Message-Type */ if (vp) { DICT_VALUE *dv = dict_valbyattr(DHCP2ATTR(53), vp->vp_integer); DEBUG("Trying sub-section dhcp %s {...}", dv->name ? dv->name : "<unknown>"); rcode = module_post_auth(vp->vp_integer, request); } else { DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!"); rcode = RLM_MODULE_FAIL; } vp = pairfind(request->reply->vps, DHCP2ATTR(53)); /* DHCP-Message-Type */ if (vp) { request->reply->code = vp->vp_integer; if ((request->reply->code != 0) && (request->reply->code < PW_DHCP_OFFSET)) { request->reply->code += PW_DHCP_OFFSET; } } else switch (rcode) { case RLM_MODULE_OK: case RLM_MODULE_UPDATED: if (request->packet->code == PW_DHCP_DISCOVER) { request->reply->code = PW_DHCP_OFFER; break; } else if (request->packet->code == PW_DHCP_REQUEST) { request->reply->code = PW_DHCP_ACK; break; } request->reply->code = PW_DHCP_NAK; break; default: case RLM_MODULE_REJECT: case RLM_MODULE_FAIL: case RLM_MODULE_INVALID: case RLM_MODULE_NOOP: case RLM_MODULE_NOTFOUND: if (request->packet->code == PW_DHCP_DISCOVER) { request->reply->code = 0; /* ignore the packet */ } else { request->reply->code = PW_DHCP_NAK; } break; case RLM_MODULE_HANDLED: request->reply->code = 0; /* ignore the packet */ break; } /* * TODO: Handle 'output' of RLM_MODULE when acting as a * DHCP relay We may want to not forward packets in * certain circumstances. */ /* * Handle requests when acting as a DHCP relay */ vp = pairfind(request->packet->vps, DHCP2ATTR(256)); /* DHCP-Opcode */ if (!vp) { RDEBUG("FAILURE: Someone deleted the DHCP-Opcode!"); return 1; } /* BOOTREPLY received on port 67 (i.e. from a server) */ if (vp->vp_integer == 2) { return dhcprelay_process_server_reply(request); } /* Packet from client, and we have DHCP-Relay-To-IP-Address */ if (pairfind(request->config_items, DHCP2ATTR(270))) { return dhcprelay_process_client_request(request); } /* else it's a packet from a client, without relaying */ rad_assert(vp->vp_integer == 1); /* BOOTREQUEST */ sock = request->listener->data; /* * Handle requests when acting as a DHCP server */ /* * Releases don't get replies. */ if (request->packet->code == PW_DHCP_RELEASE) { request->reply->code = 0; } if (request->reply->code == 0) { return 1; } request->reply->sockfd = request->packet->sockfd; /* * Copy specific fields from packet to reply, if they * don't already exist */ for (i = 0; i < sizeof(attrnums) / sizeof(attrnums[0]); i++) { uint32_t attr = attrnums[i]; if (pairfind(request->reply->vps, DHCP2ATTR(attr))) continue; if ((vp = pairfind(request->packet->vps, DHCP2ATTR(attr)))) { pairadd(&request->reply->vps, paircopyvp(vp)); } } vp = pairfind(request->reply->vps, DHCP2ATTR(256)); /* DHCP-Opcode */ rad_assert(vp != NULL); vp->vp_integer = 2; /* BOOTREPLY */ /* * Prepare the reply packet for sending through dhcp_socket_send() */ request->reply->dst_ipaddr.af = AF_INET; request->reply->src_ipaddr.af = AF_INET; request->reply->src_ipaddr.ipaddr.ip4addr.s_addr = sock->src_ipaddr.ipaddr.ip4addr.s_addr; request->reply->dst_port = request->packet->src_port; request->reply->src_port = request->packet->dst_port; vp = pairfind(request->reply->vps, DHCP2ATTR(266)); /* DHCP-Gateway-IP-Address */ if (vp && (vp->vp_ipaddr != htonl(INADDR_ANY))) { /* Answer to client's nearest DHCP relay */ request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; } else if ((request->reply->code == PW_DHCP_NAK) || ((vp = pairfind(request->reply->vps, DHCP2ATTR(262))) /* DHCP-Flags */ && (vp->vp_integer & 0x8000) && ((vp = pairfind(request->reply->vps, DHCP2ATTR(263))) /* DHCP-Client-IP-Address */ && (vp->vp_ipaddr == htonl(INADDR_ANY))))) { /* * RFC 2131, page 23 * * Broadcast on * - DHCPNAK * or * - Broadcast flag is set up and ciaddr == NULL */ request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_BROADCAST); } else { /* * RFC 2131, page 23 * * Unicast to * - ciaddr if present * otherwise to yiaddr */ if ((vp = pairfind(request->reply->vps, DHCP2ATTR(263))) /* DHCP-Client-IP-Address */ && (vp->vp_ipaddr != htonl(INADDR_ANY))) { request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; } else { vp = pairfind(request->reply->vps, DHCP2ATTR(264)); /* DHCP-Your-IP-Address */ if (!vp) { DEBUG("DHCP: Failed to find IP Address for request."); return -1; } request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; /* * When sending a DHCP_OFFER, make sure our ARP table * contains an entry for the client IP address, or else * packet may not be forwarded if it was the first time * the client was requesting an IP address. */ if (request->reply->code == PW_DHCP_OFFER) { VALUE_PAIR *hwvp = pairfind(request->reply->vps, DHCP2ATTR(267)); /* DHCP-Client-Hardware-Address */ if (!hwvp) return -1; if (fr_dhcp_add_arp_entry(request->reply->sockfd, sock->src_interface, hwvp, vp) < 0) { return -1; } } } } return 1; }