static int sql_groupcmp(void *instance, REQUEST *request, UNUSED VALUE_PAIR *request_vp, VALUE_PAIR *check, UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs) { rlm_sql_handle_t *handle; rlm_sql_t *inst = instance; rlm_sql_grouplist_t *head, *entry; RDEBUG("sql_groupcmp"); if (!check || !check->length){ RDEBUG("sql_groupcmp: Illegal group name"); return 1; } if (!request){ RDEBUG("sql_groupcmp: NULL request"); return 1; } /* * Set, escape, and check the user attr here */ if (sql_set_user(inst, request, NULL) < 0) return 1; /* * Get a socket for this lookup */ handle = sql_get_socket(inst); if (!handle) { return 1; } /* * Get the list of groups this user is a member of */ if (sql_get_grouplist(inst, handle, request, &head) < 0) { REDEBUG("Error getting group membership"); sql_release_socket(inst, handle); return 1; } for (entry = head; entry != NULL; entry = entry->next) { if (strcmp(entry->name, check->vp_strvalue) == 0){ RDEBUG("sql_groupcmp finished: User is a member of group %s", check->vp_strvalue); talloc_free(head); sql_release_socket(inst, handle); return 0; } } /* Free the grouplist */ talloc_free(head); sql_release_socket(inst,handle); RDEBUG("sql_groupcmp finished: User is NOT a member of group %s", check->vp_strvalue); return 1; }
static rlm_rcode_t rlm_sql_process_groups(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t *handle, bool *dofallthrough) { rlm_rcode_t rcode = RLM_MODULE_NOOP; VALUE_PAIR *check_tmp = NULL, *reply_tmp = NULL, *sql_group = NULL; rlm_sql_grouplist_t *head = NULL, *entry = NULL; char *expanded = NULL; int rows; rad_assert(request != NULL); rad_assert(request->packet != NULL); /* * Get the list of groups this user is a member of */ rows = sql_get_grouplist(inst, handle, request, &head); if (rows < 0) { REDEBUG("Error retrieving group list"); return RLM_MODULE_FAIL; } if (rows == 0) { RDEBUG2("User not found in any groups"); rcode = RLM_MODULE_NOTFOUND; goto finish; } RDEBUG2("User found in the group table"); for (entry = head; entry != NULL && (*dofallthrough != 0); entry = entry->next) { /* * Add the Sql-Group attribute to the request list so we know * which group we're retrieving attributes for */ sql_group = pairmake_packet("Sql-Group", entry->name, T_OP_EQ); if (!sql_group) { REDEBUG("Error creating Sql-Group attribute"); rcode = RLM_MODULE_FAIL; goto finish; } if (inst->config->authorize_group_check_query && (inst->config->authorize_group_check_query != '\0')) { /* * Expand the group query */ if (radius_axlat(&expanded, request, inst->config->authorize_group_check_query, sql_escape_func, inst) < 0) { REDEBUG("Error generating query"); rcode = RLM_MODULE_FAIL; goto finish; } rows = sql_getvpdata(inst, &handle, request, &check_tmp, expanded); TALLOC_FREE(expanded); if (rows < 0) { REDEBUG("Error retrieving check pairs for group %s", entry->name); rcode = RLM_MODULE_FAIL; goto finish; } /* * If we got check rows we need to process them before we decide to process the reply rows */ if ((rows > 0) && (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) != 0)) { pairfree(&check_tmp); pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); continue; } RDEBUG2("Group \"%s\" check items matched", entry->name); rcode = RLM_MODULE_OK; radius_pairmove(request, &request->config_items, check_tmp, true); check_tmp = NULL; } if (inst->config->authorize_group_reply_query && (inst->config->authorize_group_reply_query != '\0')) { /* * Now get the reply pairs since the paircompare matched */ if (radius_axlat(&expanded, request, inst->config->authorize_group_reply_query, sql_escape_func, inst) < 0) { REDEBUG("Error generating query"); rcode = RLM_MODULE_FAIL; goto finish; } rows = sql_getvpdata(inst, &handle, request->reply, &reply_tmp, expanded); TALLOC_FREE(expanded); if (rows < 0) { REDEBUG("Error retrieving reply pairs for group %s", entry->name); rcode = RLM_MODULE_FAIL; goto finish; } *dofallthrough = fallthrough(reply_tmp); RDEBUG2("Group \"%s\" reply items processed", entry->name); rcode = RLM_MODULE_OK; radius_pairmove(request, &request->reply->vps, reply_tmp, true); reply_tmp = NULL; } pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); } finish: talloc_free(head); pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); return rcode; }
static int rlm_sql_process_groups(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t *handle, int *dofallthrough) { VALUE_PAIR *check_tmp = NULL; VALUE_PAIR *reply_tmp = NULL; rlm_sql_grouplist_t *group_list, *group_list_tmp; VALUE_PAIR *sql_group = NULL; char querystr[MAX_QUERY_LEN]; int found = 0; int rows; /* * Get the list of groups this user is a member of */ if (sql_get_grouplist(inst, handle, request, &group_list) < 0) { radlog_request(L_ERR, 0, request, "Error retrieving group list"); return -1; } for (group_list_tmp = group_list; group_list_tmp != NULL && *dofallthrough != 0; group_list_tmp = group_list_tmp->next) { /* * Add the Sql-Group attribute to the request list so we know * which group we're retrieving attributes for */ sql_group = pairmake("Sql-Group", group_list_tmp->groupname, T_OP_EQ); if (!sql_group) { radlog_request(L_ERR, 0, request, "Error creating Sql-Group attribute"); sql_grouplist_free(&group_list); return -1; } pairadd(&request->packet->vps, sql_group); if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_check_query, request, sql_escape_func, inst)) { radlog_request(L_ERR, 0, request, "Error generating query; rejecting user"); /* Remove the grouup we added above */ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); sql_grouplist_free(&group_list); return -1; } rows = sql_getvpdata(inst, &handle, &check_tmp, querystr); if (rows < 0) { radlog_request(L_ERR, 0, request, "Error retrieving check pairs for group %s", group_list_tmp->groupname); /* Remove the grouup we added above */ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); pairfree(&check_tmp); sql_grouplist_free(&group_list); return -1; } else if (rows > 0) { /* * Only do this if *some* check pairs were returned */ if (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0) { found = 1; RDEBUG2("User found in group %s", group_list_tmp->groupname); /* * Now get the reply pairs since the paircompare matched */ if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func, inst)) { radlog_request(L_ERR, 0, request, "Error generating query; rejecting user"); /* Remove the grouup we added above */ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); pairfree(&check_tmp); sql_grouplist_free(&group_list); return -1; } if (sql_getvpdata(inst, &handle, &reply_tmp, querystr) < 0) { radlog_request(L_ERR, 0, request, "Error retrieving reply pairs for group %s", group_list_tmp->groupname); /* Remove the grouup we added above */ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); pairfree(&check_tmp); pairfree(&reply_tmp); sql_grouplist_free(&group_list); return -1; } *dofallthrough = fallthrough(reply_tmp); radius_xlat_move(request, &request->reply->vps, &reply_tmp); radius_xlat_move(request, &request->config_items, &check_tmp); } } else { /* * rows == 0. This is like having the username on a line * in the user's file with no check vp's. As such, we treat * it as found and add the reply attributes, so that we * match expected behavior */ found = 1; RDEBUG2("User found in group %s", group_list_tmp->groupname); /* * Now get the reply pairs since the paircompare matched */ if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func, inst)) { radlog_request(L_ERR, 0, request, "Error generating query; rejecting user"); /* Remove the grouup we added above */ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); pairfree(&check_tmp); sql_grouplist_free(&group_list); return -1; } if (sql_getvpdata(inst, &handle, &reply_tmp, querystr) < 0) { radlog_request(L_ERR, 0, request, "Error retrieving reply pairs for group %s", group_list_tmp->groupname); /* Remove the grouup we added above */ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); pairfree(&check_tmp); pairfree(&reply_tmp); sql_grouplist_free(&group_list); return -1; } *dofallthrough = fallthrough(reply_tmp); radius_xlat_move(request, &request->reply->vps, &reply_tmp); radius_xlat_move(request, &request->config_items, &check_tmp); } /* * Delete the Sql-Group we added above * And clear out the pairlists */ pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); pairfree(&check_tmp); pairfree(&reply_tmp); } sql_grouplist_free(&group_list); return found; }
static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp, VALUE_PAIR *check, VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs) { rlm_sql_handle_t *handle; rlm_sql_t *inst = instance; rlm_sql_grouplist_t *group_list, *group_list_tmp; check_pairs = check_pairs; reply_pairs = reply_pairs; request_vp = request_vp; RDEBUG("sql_groupcmp"); if (!check || !check->length){ RDEBUG("sql_groupcmp: Illegal group name"); return 1; } if (!request){ RDEBUG("sql_groupcmp: NULL request"); return 1; } /* * Set, escape, and check the user attr here */ if (sql_set_user(inst, request, NULL) < 0) return 1; /* * Get a socket for this lookup */ handle = sql_get_socket(inst); if (handle == NULL) { return 1; } /* * Get the list of groups this user is a member of */ if (sql_get_grouplist(inst, handle, request, &group_list) < 0) { radlog_request(L_ERR, 0, request, "Error getting group membership"); sql_release_socket(inst, handle); return 1; } for (group_list_tmp = group_list; group_list_tmp != NULL; group_list_tmp = group_list_tmp->next) { if (strcmp(group_list_tmp->groupname, check->vp_strvalue) == 0){ RDEBUG("sql_groupcmp finished: User is a member of group %s", check->vp_strvalue); /* Free the grouplist */ sql_grouplist_free(&group_list); sql_release_socket(inst, handle); return 0; } } /* Free the grouplist */ sql_grouplist_free(&group_list); sql_release_socket(inst,handle); RDEBUG("sql_groupcmp finished: User is NOT a member of group %s", check->vp_strvalue); return 1; }
static rlm_rcode_t rlm_sql_process_groups(rlm_sql_t *inst, REQUEST *request, rlm_sql_handle_t **handle, sql_fall_through_t *do_fall_through) { rlm_rcode_t rcode = RLM_MODULE_NOOP; VALUE_PAIR *check_tmp = NULL, *reply_tmp = NULL, *sql_group = NULL; rlm_sql_grouplist_t *head = NULL, *entry = NULL; char *expanded = NULL; int rows; rad_assert(request->packet != NULL); /* * Get the list of groups this user is a member of */ rows = sql_get_grouplist(inst, handle, request, &head); if (rows < 0) { REDEBUG("Error retrieving group list"); return RLM_MODULE_FAIL; } if (rows == 0) { RDEBUG2("User not found in any groups"); rcode = RLM_MODULE_NOTFOUND; *do_fall_through = FALL_THROUGH_DEFAULT; goto finish; } rad_assert(head); RDEBUG2("User found in the group table"); /* * Add the Sql-Group attribute to the request list so we know * which group we're retrieving attributes for */ sql_group = pairmake_packet("Sql-Group", NULL, T_OP_EQ); if (!sql_group) { REDEBUG("Error creating Sql-Group attribute"); rcode = RLM_MODULE_FAIL; goto finish; } entry = head; do { next: rad_assert(entry != NULL); pairstrcpy(sql_group, entry->name); if (inst->config->authorize_group_check_query) { vp_cursor_t cursor; VALUE_PAIR *vp; /* * Expand the group query */ if (radius_axlat(&expanded, request, inst->config->authorize_group_check_query, sql_escape_func, inst) < 0) { REDEBUG("Error generating query"); rcode = RLM_MODULE_FAIL; goto finish; } rows = sql_getvpdata(request, inst, request, handle, &check_tmp, expanded); TALLOC_FREE(expanded); if (rows < 0) { REDEBUG("Error retrieving check pairs for group %s", entry->name); rcode = RLM_MODULE_FAIL; goto finish; } /* * If we got check rows we need to process them before we decide to * process the reply rows */ if ((rows > 0) && (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) != 0)) { pairfree(&check_tmp); entry = entry->next; goto next; /* != continue */ } RDEBUG2("Group \"%s\": Conditional check items matched", entry->name); rcode = RLM_MODULE_OK; RDEBUG2("Group \"%s\": Merging assignment check items", entry->name); RINDENT(); for (vp = fr_cursor_init(&cursor, &check_tmp); vp; vp = fr_cursor_next(&cursor)) { if (!fr_assignment_op[vp->op]) continue; rdebug_pair(L_DBG_LVL_2, request, vp, NULL); } REXDENT(); radius_pairmove(request, &request->config_items, check_tmp, true); check_tmp = NULL; } if (inst->config->authorize_group_reply_query) { /* * Now get the reply pairs since the paircompare matched */ if (radius_axlat(&expanded, request, inst->config->authorize_group_reply_query, sql_escape_func, inst) < 0) { REDEBUG("Error generating query"); rcode = RLM_MODULE_FAIL; goto finish; } rows = sql_getvpdata(request->reply, inst, request, handle, &reply_tmp, expanded); TALLOC_FREE(expanded); if (rows < 0) { REDEBUG("Error retrieving reply pairs for group %s", entry->name); rcode = RLM_MODULE_FAIL; goto finish; } *do_fall_through = fall_through(reply_tmp); RDEBUG2("Group \"%s\": Merging reply items", entry->name); rcode = RLM_MODULE_OK; rdebug_pair_list(L_DBG_LVL_2, request, reply_tmp, NULL); radius_pairmove(request, &request->reply->vps, reply_tmp, true); reply_tmp = NULL; /* * If there's no reply query configured, then we assume * FALL_THROUGH_NO, which is the same as the users file if you * had no reply attributes. */ } else { *do_fall_through = FALL_THROUGH_DEFAULT; } entry = entry->next; } while (entry != NULL && (*do_fall_through == FALL_THROUGH_YES)); finish: talloc_free(head); pairdelete(&request->packet->vps, PW_SQL_GROUP, 0, TAG_ANY); return rcode; }
static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp, VALUE_PAIR *check, VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs) { SQLSOCK *sqlsocket; SQL_INST *inst = instance; char sqlusername[MAX_STRING_LEN]; SQL_GROUPLIST *group_list, *group_list_tmp; check_pairs = check_pairs; reply_pairs = reply_pairs; request_vp = request_vp; RDEBUG("sql_groupcmp"); if (!check || !check->vp_strvalue || !check->length){ RDEBUG("sql_groupcmp: Illegal group name"); return 1; } if (!request){ RDEBUG("sql_groupcmp: NULL request"); return 1; } /* * Set, escape, and check the user attr here */ if (sql_set_user(inst, request, sqlusername, NULL) < 0) return 1; /* * Get a socket for this lookup */ sqlsocket = sql_get_socket(inst); if (sqlsocket == NULL) { /* Remove the username we (maybe) added above */ pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); return 1; } /* * Get the list of groups this user is a member of */ if (sql_get_grouplist(inst, sqlsocket, request, &group_list) < 0) { radlog_request(L_ERR, 0, request, "Error getting group membership"); /* Remove the username we (maybe) added above */ pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); sql_release_socket(inst, sqlsocket); return 1; } for (group_list_tmp = group_list; group_list_tmp != NULL; group_list_tmp = group_list_tmp->next) { if (strcmp(group_list_tmp->groupname, check->vp_strvalue) == 0){ RDEBUG("sql_groupcmp finished: User is a member of group %s", check->vp_strvalue); /* Free the grouplist */ sql_grouplist_free(&group_list); /* Remove the username we (maybe) added above */ pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); sql_release_socket(inst, sqlsocket); return 0; } } /* Free the grouplist */ sql_grouplist_free(&group_list); /* Remove the username we (maybe) added above */ pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); sql_release_socket(inst,sqlsocket); RDEBUG("sql_groupcmp finished: User is NOT a member of group %s", check->vp_strvalue); return 1; }
static int sql_groupcmp(void *instance, REQUEST *request, UNUSED VALUE_PAIR *request_vp, VALUE_PAIR *check, UNUSED VALUE_PAIR *check_pairs, UNUSED VALUE_PAIR **reply_pairs) { rlm_sql_handle_t *handle; rlm_sql_t *inst = instance; rlm_sql_grouplist_t *head, *entry; /* * No group queries, don't do group comparisons. */ if (!inst->config->groupmemb_query) { RWARN("Cannot do group comparison when group_membership_query is not set"); return 1; } RDEBUG("sql_groupcmp"); if (check->vp_length == 0){ RDEBUG("sql_groupcmp: Illegal group name"); return 1; } /* * Set, escape, and check the user attr here */ if (sql_set_user(inst, request, NULL) < 0) return 1; /* * Get a socket for this lookup */ handle = fr_connection_get(inst->pool); if (!handle) { return 1; } /* * Get the list of groups this user is a member of */ if (sql_get_grouplist(inst, &handle, request, &head) < 0) { REDEBUG("Error getting group membership"); fr_connection_release(inst->pool, handle); return 1; } for (entry = head; entry != NULL; entry = entry->next) { if (strcmp(entry->name, check->vp_strvalue) == 0){ RDEBUG("sql_groupcmp finished: User is a member of group %s", check->vp_strvalue); talloc_free(head); fr_connection_release(inst->pool, handle); return 0; } } /* Free the grouplist */ talloc_free(head); fr_connection_release(inst->pool, handle); RDEBUG("sql_groupcmp finished: User is NOT a member of group %s", check->vp_strvalue); return 1; }