static bool write_GRM_chunk(IOStream *ios, size_t chunk_size) { if (!chunk_begin(ios, "GRM ", chunk_size) || !write_int32(ios, get_num_nonterm()) || !write_int32(ios, get_num_rules()) || !write_int32(ios, get_num_symrefs())) return false; GrammarRuleSet **rulesets = AR_data(&ar_grammar); size_t nruleset = AR_size(&ar_grammar), n, m; for (n = 0; n < nruleset; ++n) { if (!write_int32(ios, (int)rulesets[n]->nrule)) return false; for (m = 0; m < rulesets[n]->nrule; ++m) { if (!write_grammar_rule(ios, rulesets[n]->rules[m])) return false; } } return chunk_end(ios, chunk_size); }
static int sysctl_control(SYSCTL_HANDLER_ARGS) { secadm_command_t cmd; secadm_reply_t reply; int err; if (!(req->newptr) || (req->newlen != sizeof(secadm_command_t))) return (EINVAL); if (!(req->oldptr) || (req->oldlen) != sizeof(secadm_reply_t)) return (EINVAL); err = SYSCTL_IN(req, &cmd, sizeof(secadm_command_t)); if (err) return (err); /* Access control comes first */ switch (cmd.sc_type) { case secadm_flush_rules: case secadm_set_rules: /* XXX Should we cache the ucred for local use in the * sysctl lifecycle? */ // XXXOP LOCKING if (req->td->td_ucred->cr_uid != 0) { printf("[SECADM] Disallowed command: 0x%x by uid: %d\n", cmd.sc_type, req->td->td_ucred->cr_uid); return (EPERM); } // XXXOP LOCKING if (securelevel_gt(req->td->td_ucred, 0)) { printf("[SECADM] Disallowed command: 0x%x by uid: %d\n", cmd.sc_type, req->td->td_ucred->cr_uid); return (EPERM); } break; default: break; } /* XXX We should relax this check once we get stable releases. */ if (cmd.sc_version < SECADM_VERSION) return (EINVAL); memset(&reply, 0x00, sizeof(reply)); if ((err = copyin(req->oldptr, &reply, sizeof(reply)))) return (err); reply.sr_version = SECADM_VERSION; reply.sr_id = cmd.sc_id; switch (cmd.sc_type) { case secadm_get_version: if (cmd.sc_bufsize < sizeof(unsigned long)) return (EINVAL); handle_version_command(&cmd, &reply); break; case secadm_set_rules: if (cmd.sc_size != sizeof(secadm_rule_t)) return (EINVAL); handle_add_rule(req->td, &cmd, &reply); break; case secadm_flush_rules: flush_rules(req->td); break; case secadm_get_rule_size: handle_get_rule_size(req->td, &cmd, &reply); break; case secadm_get_num_rules: get_num_rules(req->td, &cmd, &reply); break; case secadm_get_rule: handle_get_rule(req->td, &cmd, &reply); break; case secadm_get_rules: case secadm_get_admins: case secadm_set_admins: case secadm_get_views: case secadm_set_views: return (ENOTSUP); default: // XXXOP LOCKING printf("[SECADM] Unknown command: 0x%x by uid: %d\n", cmd.sc_type, req->td->td_ucred->cr_uid); return (EINVAL); } err = SYSCTL_OUT(req, &reply, sizeof(secadm_reply_t)); return (err); }
static size_t get_GRM_chunk_size() { return 12 + 4*get_num_nonterm() + 4*get_num_rules() + 4*get_num_symrefs(); }