/* * Determine whether a given instance is a RPC service. Repository and * libscf errors are treated as if the service isn't an RPC service, * returning B_FALSE to indicate validation failure. */ static boolean_t service_is_rpc(const scf_instance_t *inst) { scf_snapshot_t *lsnap = NULL; uint8_t isrpc; if (scf_instance_get_snapshot(inst, SCF_SNAPSHOT_RUNNING, snap) != 0) { syslog(LOG_DEBUG | LOG_DAEMON, "Could not get running snapshot, using editing value\n"); } else { lsnap = snap; } if (scf_instance_get_pg_composed(inst, lsnap, SCF_PG_INETD, scratch_pg) == -1) { switch (scf_error()) { case SCF_ERROR_NOT_FOUND: case SCF_ERROR_DELETED: break; default: syslog(LOG_ERR | LOG_DAEMON, "scf_instance_get_pg_composed failed: %s\n", scf_strerror(scf_error())); return (B_FALSE); } if (scf_instance_get_pg_composed(inst, lsnap, SCF_PG_FW_CONTEXT, scratch_pg) == -1) { switch (scf_error()) { case SCF_ERROR_NOT_FOUND: case SCF_ERROR_DELETED: break; default: syslog(LOG_ERR | LOG_DAEMON, "scf_instance_get_pg_composed failed: %s\n", scf_strerror(scf_error())); } return (B_FALSE); } } if (pg_get_prop_value(scratch_pg, SCF_PROPERTY_ISRPC, scratch_v) == -1) return (B_FALSE); if (scf_value_get_boolean(scratch_v, &isrpc) == -1) { syslog(LOG_ERR | LOG_DAEMON, "scf_value_get_boolean failed: " "%s\n", scf_strerror(scf_error())); return (B_FALSE); } if (isrpc) return (B_TRUE); else return (B_FALSE); }
static void kbd_defaults(int kbd) { scf_handle_t *h = NULL; scf_snapshot_t *snap = NULL; scf_instance_t *inst = NULL; scf_propertygroup_t *pg = NULL; scf_property_t *prop = NULL; scf_value_t *val = NULL; int layout_num; char *val_layout = NULL, *val_abort = NULL; uint8_t val_click; int64_t val_delay, val_rate; int64_t val_kbd_beeper, val_console_beeper; if ((h = scf_handle_create(SCF_VERSION)) == NULL || scf_handle_bind(h) != 0 || (inst = scf_instance_create(h)) == NULL || (snap = scf_snapshot_create(h)) == NULL || (pg = scf_pg_create(h)) == NULL || (prop = scf_property_create(h)) == NULL || (val = scf_value_create(h)) == NULL) { goto out; } if (scf_handle_decode_fmri(h, KBD_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { goto out; } if (scf_instance_get_snapshot(inst, "running", snap) != 0) { scf_snapshot_destroy(snap); snap = NULL; } if (scf_instance_get_pg_composed(inst, snap, KBD_PG, pg) != 0) { goto out; } if ((val_abort = malloc(KBD_MAX_NAME_LEN)) == NULL) { (void) fprintf(stderr, "Can not alloc memory for keyboard properties\n"); goto out; } if ((val_layout = malloc(KBD_MAX_NAME_LEN)) == NULL) { (void) fprintf(stderr, "Can not alloc memory for keyboard properties\n"); goto out; } if (scf_pg_get_property(pg, KBD_PROP_KEYCLICK, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_boolean(val, &val_click) == -1) { (void) fprintf(stderr, "Can not get KEYCLICK\n"); } if (val_click == 1) (void) click("on", kbd); else if (val_click == 0) (void) click("off", kbd); else (void) fprintf(stderr, BAD_DEFAULT_INT, KBD_PROP_KEYCLICK, val_click); if (scf_pg_get_property(pg, KBD_PROP_KEYBOARD_ABORT, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_astring(val, val_abort, KBD_MAX_NAME_LEN) == -1) { (void) fprintf(stderr, "Can not get KEYBOARD_ABORT\n"); } if (*val_abort != '\0') { /* * ABORT must equal "enable", "disable" or "alternate" */ if ((strcmp(val_abort, "enable") == 0) || (strcmp(val_abort, "alternate") == 0) || (strcmp(val_abort, "disable") == 0)) (void) abort_enable(val_abort, kbd); else (void) fprintf(stderr, BAD_DEFAULT_STR, KBD_PROP_KEYBOARD_ABORT, val_abort); } if (scf_pg_get_property(pg, KBD_PROP_RPTDELAY, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_delay) == -1) { (void) fprintf(stderr, "Can not get RPTDELAY\n"); } if (val_delay > 0) (void) set_rptdelay(val_delay, kbd); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_RPTDELAY, val_delay); if (scf_pg_get_property(pg, KBD_PROP_RPTRATE, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_rate) == -1) { (void) fprintf(stderr, "Can not get RPTRATE\n"); } if (val_rate > 0) (void) set_rptrate(val_rate, kbd); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_RPTRATE, val_rate); if (scf_pg_get_property(pg, KBD_PROP_LAYOUT, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_astring(val, val_layout, KBD_MAX_NAME_LEN) == -1) { (void) fprintf(stderr, "Can not get LAYOUT\n"); } if (*val_layout != '\0') { /* * LAYOUT must be one of the layouts supported in kbd_layouts */ if (get_layouts() != 0) goto out; if ((layout_num = get_layout_number(val_layout)) == -1) { (void) fprintf(stderr, BAD_DEFAULT_STR, KBD_PROP_LAYOUT, val_layout); goto out; } (void) set_layout(kbd, layout_num); } if (scf_pg_get_property(pg, KBD_PROP_FREQ, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_kbd_beeper) == -1) { (void) fprintf(stderr, "Can not get FREQ\n"); } if (val_kbd_beeper >= 0 && val_kbd_beeper <= INT16_MAX) (void) set_beep_freq(kbd, "keyboard", val_kbd_beeper); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_FREQ, val_kbd_beeper); if (scf_pg_get_property(pg, KBD_PROP_CONSFREQ, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_console_beeper) == -1) { (void) fprintf(stderr, "Can not get CONSFREQ\n"); } if (val_console_beeper >= 0 && val_console_beeper <= INT16_MAX) (void) set_beep_freq(kbd, "console", val_console_beeper); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_CONSFREQ, val_console_beeper); out: if (val_layout != NULL) free(val_layout); if (val_abort != NULL) free(val_abort); if (snap != NULL) scf_snapshot_destroy(snap); scf_value_destroy(val); scf_property_destroy(prop); scf_pg_destroy(pg); scf_instance_destroy(inst); scf_handle_destroy(h); }
/* * Returns a zone ID of Solaris when the TZ value is "localtime". * First, it tries scf. If scf fails, it looks for the same file as * /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/. */ static char * getSolarisDefaultZoneID() { char *tz = NULL; struct stat statbuf; size_t size; char *buf; int fd; /* scf specific variables */ scf_handle_t *h = NULL; scf_snapshot_t *snap = NULL; scf_instance_t *inst = NULL; scf_propertygroup_t *pg = NULL; scf_property_t *prop = NULL; scf_value_t *val = NULL; if ((h = scf_handle_create(SCF_VERSION)) != NULL && scf_handle_bind(h) == 0 && (inst = scf_instance_create(h)) != NULL && (snap = scf_snapshot_create(h)) != NULL && (pg = scf_pg_create(h)) != NULL && (prop = scf_property_create(h)) != NULL && (val = scf_value_create(h)) != NULL && scf_handle_decode_fmri(h, TIMEZONE_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) == 0 && scf_instance_get_snapshot(inst, "running", snap) == 0 && scf_instance_get_pg_composed(inst, snap, TIMEZONE_PG, pg) == 0 && scf_pg_get_property(pg, LOCALTIME_PROP, prop) == 0 && scf_property_get_value(prop, val) == 0) { ssize_t len; /* Gets the length of the zone ID string */ len = scf_value_get_astring(val, NULL, 0); if (len != -1) { tz = malloc(++len); /* +1 for a null byte */ if (tz != NULL && scf_value_get_astring(val, tz, len) != -1) { cleanupScf(h, snap, inst, pg, prop, val, NULL); return tz; } } } cleanupScf(h, snap, inst, pg, prop, val, tz); if (stat(DEFAULT_ZONEINFO_FILE, &statbuf) == -1) { return NULL; } size = (size_t) statbuf.st_size; buf = malloc(size); if (buf == NULL) { return NULL; } if ((fd = open(DEFAULT_ZONEINFO_FILE, O_RDONLY)) == -1) { free((void *) buf); return NULL; } if (read(fd, buf, size) != (ssize_t) size) { (void) close(fd); free((void *) buf); return NULL; } (void) close(fd); tz = findZoneinfoFile(buf, size, ZONEINFO_DIR); free((void *) buf); return tz; }
/* * Inputs: * lpg is the property group to look up * lprop is the property within that group to look up * Outputs: * res is a pointer to an scf_resources_t. This is an internal * structure that holds all the handles needed to get a specific * property from the running snapshot; on a successful return it * contains the scf_value_t that should be passed to the desired * scf_value_get_foo() function, and must be freed after use by * calling release_scf_resources(). On a failure return, any * resources that may have been assigned to res are released, so * the caller does not need to do any cleanup in the failure case. * Returns: * 0 on success * -1 on failure */ static int get_property_value(const char *lpg, const char *lprop, scf_resources_t *res) { res->sr_inst = NULL; res->sr_snap = NULL; res->sr_pg = NULL; res->sr_prop = NULL; res->sr_val = NULL; if ((res->sr_handle = scf_handle_create(SCF_VERSION)) == NULL) { syslog(LOG_ERR, "scf_handle_create() failed: %s", scf_strerror(scf_error())); return (-1); } if (scf_handle_bind(res->sr_handle) != 0) { scf_handle_destroy(res->sr_handle); syslog(LOG_ERR, "scf_handle_destroy() failed: %s", scf_strerror(scf_error())); return (-1); } if ((res->sr_inst = scf_instance_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_instance_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_handle_decode_fmri(res->sr_handle, OUR_FMRI, NULL, NULL, res->sr_inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { syslog(LOG_ERR, "scf_handle_decode_fmri() failed: %s", scf_strerror(scf_error())); goto failure; } if ((res->sr_snap = scf_snapshot_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_snapshot_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_instance_get_snapshot(res->sr_inst, "running", res->sr_snap) != 0) { syslog(LOG_ERR, "scf_instance_get_snapshot() failed: %s", scf_strerror(scf_error())); goto failure; } if ((res->sr_pg = scf_pg_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_pg_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_instance_get_pg_composed(res->sr_inst, res->sr_snap, lpg, res->sr_pg) != 0) { syslog(LOG_ERR, "scf_instance_get_pg_composed(%s) failed: %s", lpg, scf_strerror(scf_error())); goto failure; } if ((res->sr_prop = scf_property_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_property_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_pg_get_property(res->sr_pg, lprop, res->sr_prop) != 0) { syslog(LOG_ERR, "scf_pg_get_property(%s) failed: %s", lprop, scf_strerror(scf_error())); goto failure; } if ((res->sr_val = scf_value_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_value_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_property_get_value(res->sr_prop, res->sr_val) != 0) { syslog(LOG_ERR, "scf_property_get_value() failed: %s", scf_strerror(scf_error())); goto failure; } return (0); failure: release_scf_resources(res); return (-1); }
static int instance_has_firewall(scf_instance_t *inst) { scf_snapshot_t *lsnap = NULL; if (scf_instance_get_snapshot(inst, SCF_SNAPSHOT_RUNNING, snap) == -1) { switch (scf_error()) { case SCF_ERROR_CONNECTION_BROKEN: syslog(LOG_ERR | LOG_DAEMON, "scf_instance_get_snapshot failed: %s\n", scf_strerror(scf_error())); repository_setup(); return (-1); case SCF_ERROR_DELETED: default: /* * If running snapshot is not available for * other reasons, fall back to current values. */ syslog(LOG_DEBUG | LOG_DAEMON, "Could not get " "running snapshot, using current value\n"); } } else { lsnap = snap; } /* * Update service's IPfilter configuration if either * SCF_PG_FW_CONTEXT or SCF_PG_FW_CONFIG exists. */ if (scf_instance_get_pg_composed(inst, lsnap, SCF_PG_FW_CONTEXT, scratch_pg) == 0) { return (1); } else { switch (scf_error()) { case SCF_ERROR_NOT_FOUND: case SCF_ERROR_DELETED: break; case SCF_ERROR_CONNECTION_BROKEN: repository_setup(); /* FALLTHROUGH */ default: syslog(LOG_ERR | LOG_DAEMON, "scf_instance_get_pg_composed failed: %s\n", scf_strerror(scf_error())); return (-1); } } if (scf_instance_get_pg_composed(inst, lsnap, SCF_PG_FW_CONFIG, scratch_pg) == -1) { /* * It's either a non-firewall service or a failure to * read firewall pg, just continue and listen for * future events. */ switch (scf_error()) { case SCF_ERROR_NOT_FOUND: case SCF_ERROR_DELETED: return (0); case SCF_ERROR_CONNECTION_BROKEN: repository_setup(); /* FALLTHROUGH */ default: syslog(LOG_ERR | LOG_DAEMON, "scf_instance_get_pg_composed failed: %s\n", scf_strerror(scf_error())); return (-1); } } return (1); }
/* * Entity (service or instance): If there are -p options, * display_{pg,prop}() the named property groups and/or properties. Otherwise * display_pg() all property groups. */ static void process_ent(scf_entityp_t ent) { scf_snapshot_t *snap = NULL; scf_propertygroup_t *pg; scf_property_t *prop; scf_iter_t *iter; svcprop_prop_node_t *spn; int ret, err; if (uu_list_numnodes(prop_list) == 0) { if (quiet) return; if ((pg = scf_pg_create(hndl)) == NULL || (iter = scf_iter_create(hndl)) == NULL) scfdie(); if (cflag || Cflag || ent.type != ENT_INSTANCE) { if (scf_iter_entity_pgs(iter, ent) == -1) scfdie(); } else { if (snapshot != NULL) snap = get_snapshot(ent.u.inst, snapshot); if (scf_iter_instance_pgs_composed(iter, ent.u.inst, snap) == -1) scfdie(); if (snap) scf_snapshot_destroy(snap); } while ((ret = scf_iter_next_pg(iter, pg)) == 1) display_pg(pg); if (ret == -1) scfdie(); /* * In normal usage, i.e. against the running snapshot, * we must iterate over the current non-persistent * pg's. */ if (sflag == 0 && snap != NULL) { scf_iter_reset(iter); if (scf_iter_instance_pgs_composed(iter, ent.u.inst, NULL) == -1) scfdie(); while ((ret = scf_iter_next_pg(iter, pg)) == 1) { uint32_t flags; if (scf_pg_get_flags(pg, &flags) == -1) scfdie(); if (flags & SCF_PG_FLAG_NONPERSISTENT) display_pg(pg); } } if (ret == -1) scfdie(); scf_iter_destroy(iter); scf_pg_destroy(pg); return; } if ((pg = scf_pg_create(hndl)) == NULL || (prop = scf_property_create(hndl)) == NULL) scfdie(); if (ent.type == ENT_INSTANCE && snapshot != NULL) snap = get_snapshot(ent.u.inst, snapshot); for (spn = uu_list_first(prop_list); spn != NULL; spn = uu_list_next(prop_list, spn)) { if (ent.type == ENT_INSTANCE) { if (Cflag) ret = scf_instance_get_pg(ent.u.inst, spn->spn_comp1, pg); else ret = scf_instance_get_pg_composed(ent.u.inst, snap, spn->spn_comp1, pg); err = scf_error(); /* * If we didn't find it in the specified snapshot, use * the current values if the pg is nonpersistent. */ if (ret == -1 && !Cflag &&snap != NULL && err == SCF_ERROR_NOT_FOUND) { ret = scf_instance_get_pg_composed( ent.u.inst, NULL, spn->spn_comp1, pg); if (ret == 0) { uint32_t flags; if (scf_pg_get_flags(pg, &flags) == -1) scfdie(); if ((flags & SCF_PG_FLAG_NONPERSISTENT) == 0) { ret = -1; } } } } else { /* * If we are displaying properties for a service, * treat it as though it were a composed, current * lookup. (implicit cflag) However, if a snapshot * was specified, fail. */ if (sflag) die(gettext("Only instances have " "snapshots.\n")); ret = scf_entity_get_pg(ent, spn->spn_comp1, pg); err = scf_error(); } if (ret == -1) { if (err != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_entity_to_fmri(ent, buf, max_scf_fmri_length + 1) == -1) scfdie(); uu_warn(gettext("Couldn't find property group " "`%s' for %s `%s'.\n"), spn->spn_comp1, SCF_ENTITY_TYPE_NAME(ent), buf); free(buf); } noprop_common_action(); continue; } if (spn->spn_comp2 == NULL) { if (!quiet) display_pg(pg); continue; } if (scf_pg_get_property(pg, spn->spn_comp2, prop) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); if (PRINT_NOPROP_ERRORS) { char *buf; buf = safe_malloc(max_scf_fmri_length + 1); if (scf_entity_to_fmri(ent, buf, max_scf_fmri_length + 1) == -1) scfdie(); /* FMRI syntax knowledge */ uu_warn(gettext("Couldn't find property " "`%s/%s' for %s `%s'.\n"), spn->spn_comp1, spn->spn_comp2, SCF_ENTITY_TYPE_NAME(ent), buf); free(buf); } noprop_common_action(); continue; } if (!quiet) display_prop(pg, prop); } scf_property_destroy(prop); scf_pg_destroy(pg); if (snap) scf_snapshot_destroy(snap); }