conerr_t smfu_get_property(char *fmri, char *pgname, char *propname, char *value, size_t n) { conerr_t err = ce_ok; scf_handle_t *scfhandle = handle_create(); scf_service_t *service = scf_service_create(scfhandle); scf_instance_t *instance = scf_instance_create(scfhandle); scf_propertygroup_t *pg = scf_pg_create(scfhandle); scf_property_t *prop = scf_property_create(scfhandle); scf_iter_t *iter = scf_iter_create(scfhandle); scf_value_t *val = scf_value_create(scfhandle); if (scfhandle == NULL || service == NULL || instance == NULL || pg == NULL || prop == NULL || iter == NULL || val == NULL) { err = ce_nomem; goto out; } if (scf_handle_decode_fmri(scfhandle, fmri, NULL, service, instance, NULL, NULL, 0) != SCF_SUCCESS) { rad_log(RL_ERROR, "couldn't decode '%s': %s\n", fmri, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } if (scf_instance_get_pg(instance, pgname, pg) != 0 || scf_pg_get_property(pg, propname, prop) != 0 || scf_iter_property_values(iter, prop) != 0) { rad_log(RL_ERROR, "couldn't get property: '%s/%s/%s': %s\n", fmri, pgname, propname, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } if (scf_iter_next_value(iter, val) > 0 && scf_value_get_as_string(val, value, n) == -1) { rad_log(RL_ERROR, "couldn't get property value: '%s/%s/%s': %s\n", fmri, pgname, propname, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } out: scf_value_destroy(val); scf_property_destroy(prop); scf_pg_destroy(pg); scf_iter_destroy(iter); scf_instance_destroy(instance); scf_service_destroy(service); scf_handle_destroy(scfhandle); return (err); }
/* * Returns a pointer to an allocated method context for the specified method * of the specified instance if it could retrieve it. Else, if there were * errors retrieving it, NULL is returned and the pointer referenced by * 'errstr' is set to point at an appropriate error string. */ struct method_context * read_method_context(const char *inst_fmri, const char *method, const char *path) { scf_instance_t *scf_inst = NULL; struct method_context *ret; uint_t retries; mc_error_t *tmperr; char *fail; fail = gettext("Failed to retrieve method context for the %s method of " "instance %s : %s"); for (retries = 0; retries <= REP_OP_RETRIES; retries++) { if (make_handle_bound(rep_handle) == -1) goto inst_failure; if (((scf_inst = scf_instance_create(rep_handle)) != NULL) && (scf_handle_decode_fmri(rep_handle, inst_fmri, NULL, NULL, scf_inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) == 0)) break; if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) { scf_instance_destroy(scf_inst); goto inst_failure; } (void) scf_instance_destroy(scf_inst); scf_inst = NULL; (void) scf_handle_unbind(rep_handle); } if (retries > REP_OP_RETRIES) goto inst_failure; if ((tmperr = restarter_get_method_context( RESTARTER_METHOD_CONTEXT_VERSION, scf_inst, NULL, method, path, &ret)) != NULL) { ret = NULL; error_msg(fail, method, inst_fmri, tmperr->msg); restarter_mc_error_destroy(tmperr); } scf_instance_destroy(scf_inst); return (ret); inst_failure: /* * We can rely on this string not becoming invalid * since we don't call bind_textdomain_codeset() or * setlocale(3C) after initialization. */ error_msg(fail, method, inst_fmri, gettext("failed to get instance from repository")); return (NULL); }
fs_smfhandle_t * fs_smf_init(char *fmri, char *instance) { fs_smfhandle_t *handle = NULL; char *svcname, srv[MAXPATHLEN]; /* * svc name is of the form svc://network/fs/server:instance1 * FMRI portion is /network/fs/server */ snprintf(srv, MAXPATHLEN, "%s", fmri + strlen("svc:/")); svcname = strrchr(srv, ':'); if (svcname != NULL) *svcname = '\0'; svcname = srv; handle = calloc(1, sizeof (fs_smfhandle_t)); if (handle != NULL) { handle->fs_handle = scf_handle_create(SCF_VERSION); if (handle->fs_handle == NULL) goto out; if (scf_handle_bind(handle->fs_handle) != 0) goto out; handle->fs_service = scf_service_create(handle->fs_handle); handle->fs_scope = scf_scope_create(handle->fs_handle); if (scf_handle_get_local_scope(handle->fs_handle, handle->fs_scope) != 0) goto out; if (scf_scope_get_service(handle->fs_scope, svcname, handle->fs_service) != SCF_SUCCESS) { goto out; } handle->fs_pg = scf_pg_create(handle->fs_handle); handle->fs_instance = scf_instance_create(handle->fs_handle); handle->fs_property = scf_property_create(handle->fs_handle); handle->fs_value = scf_value_create(handle->fs_handle); } else { fprintf(stderr, gettext("Cannot access SMF repository: %s\n"), fmri); } return (handle); out: fs_smf_fini(handle); fprintf(stderr, gettext("SMF Initialization problems..%s\n"), fmri); return (NULL); }
/* * Check if instance with given name exists for a service. * Returns 0 is instance exist */ int smb_smf_instance_exists(smb_scfhandle_t *handle, char *inst_name) { int ret = SMBC_SMF_OK; if (handle == NULL) { return (SMBC_SMF_SYSTEM_ERR); } handle->scf_instance = scf_instance_create(handle->scf_handle); if (scf_service_get_instance(handle->scf_service, inst_name, handle->scf_instance) != SCF_SUCCESS) { ret = SMBC_SMF_SYSTEM_ERR; } scf_instance_destroy(handle->scf_instance); handle->scf_instance = NULL; return (ret); }
targ_scf_t * mgmt_handle_init(void) { targ_scf_t *h; h = calloc(1, sizeof (targ_scf_t)); if (h == NULL) return (NULL); h->t_handle = scf_handle_create(SCF_VERSION); if (h->t_handle != NULL) { if (scf_handle_bind(h->t_handle) == 0) { h->t_scope = scf_scope_create(h->t_handle); h->t_service = scf_service_create(h->t_handle); h->t_pg = scf_pg_create(h->t_handle); h->t_instance = scf_instance_create(h->t_handle); if (scf_handle_get_scope(h->t_handle, SCF_SCOPE_LOCAL, h->t_scope) == 0) { if (scf_scope_get_service(h->t_scope, SA_TARGET_SVC_NAME, h->t_service) != 0) goto error; } else { syslog(LOG_ERR, "Got local scope which is wrong\n"); goto error; } } else goto error; } else { free(h); h = NULL; syslog(LOG_ERR, "iscsitgt could not access SMF repository: %s\n", scf_strerror(scf_error())); } return (h); error: mgmt_handle_fini(h); free(h); syslog(LOG_ERR, "iscsitgt SMF initialization problem: %s\n", scf_strerror(scf_error())); return (NULL); }
int main() { if (daemonize_self() == 1) return (1); max_scf_fmri_size = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH) + 1; max_scf_name_size = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; assert(max_scf_fmri_size > 0); assert(max_scf_name_size > 0); if ((h = scf_handle_create(SCF_VERSION)) == NULL) { syslog(LOG_ERR | LOG_DAEMON, "scf_handle_create failed: %s\n", scf_strerror(scf_error())); return (1); } repository_rebind(h); scratch_fmri = umem_alloc(max_scf_fmri_size, UMEM_DEFAULT); scratch_name = umem_alloc(max_scf_name_size, UMEM_DEFAULT); if (scratch_fmri == NULL || scratch_name == NULL) { syslog(LOG_ERR | LOG_DAEMON, "Out of memory"); return (1); } inst = scf_instance_create(h); snap = scf_snapshot_create(h); scratch_pg = scf_pg_create(h); scratch_prop = scf_property_create(h); scratch_v = scf_value_create(h); if (inst == NULL || snap == NULL || scratch_pg == NULL || scratch_prop == NULL || scratch_v == NULL) { syslog(LOG_ERR | LOG_DAEMON, "Initialization failed: %s\n", scf_strerror(scf_error())); return (1); } return (repository_event_wait()); }
/* * Create a service instance. returns 0 if successful. * If instance already exists enable it. */ int smb_smf_instance_create(smb_scfhandle_t *handle, char *serv_prefix, char *inst_name) { char *instance; int ret = SMBC_SMF_OK; int sz; if (handle == NULL) { return (SMBC_SMF_SYSTEM_ERR); } if (!serv_prefix || !inst_name) { return (SMBC_SMF_SYSTEM_ERR); } sz = strlen(serv_prefix) + strlen(inst_name) + 2; instance = malloc(sz); if (!instance) { return (SMBC_SMF_SYSTEM_ERR); } (void) snprintf(instance, sz, "%s:%s", serv_prefix, inst_name); handle->scf_instance = scf_instance_create(handle->scf_handle); if (scf_service_get_instance(handle->scf_service, inst_name, handle->scf_instance) != SCF_SUCCESS) { if (scf_service_add_instance(handle->scf_service, inst_name, handle->scf_instance) == SCF_SUCCESS) { if (smf_enable_instance(instance, 0)) ret = SMBC_SMF_SYSTEM_ERR; } else { ret = SMBC_SMF_SYSTEM_ERR; } } else { if (smf_enable_instance(instance, 0)) ret = SMBC_SMF_SYSTEM_ERR; } free(instance); return (ret); }
/* * Delete a specified instance. Return SMBC_SMF_OK for success. */ int smb_smf_instance_delete(smb_scfhandle_t *handle, char *inst_name) { int ret = SMBC_SMF_OK; if (handle == NULL) { return (SMBC_SMF_SYSTEM_ERR); } handle->scf_instance = scf_instance_create(handle->scf_handle); if (scf_service_get_instance(handle->scf_service, inst_name, handle->scf_instance) == SCF_SUCCESS) { if (scf_instance_delete(handle->scf_instance) == SCF_SUCCESS) { return (ret); } else { ret = SMBC_SMF_SYSTEM_ERR; } } else { smb_smf_scf_log_error(NULL); ret = SMBC_SMF_SYSTEM_ERR; } return (ret); }
/* * 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; }
/* * Load the instance for fmri from the repository into memory. The * property groups that define the instances pg_patterns and prop_patterns * are also loaded. * * Returns 0 on success and non-zero on failure. */ int load_instance(const char *fmri, const char *name, entity_t **inst_ptr) { entity_t *e = NULL; scf_instance_t *inst; pgroup_t *ipg; int rc; char *type = NULL; ssize_t tsize; assert(inst_ptr != NULL); if ((inst = scf_instance_create(g_hndl)) == NULL) { switch (scf_error()) { case SCF_ERROR_NO_MEMORY: case SCF_ERROR_NO_RESOURCES: rc = EAGAIN; goto errout; default: bad_error("scf_instance_create", scf_error()); } } if (scf_handle_decode_fmri(g_hndl, fmri, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_EXACT|SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { switch (scf_error()) { case SCF_ERROR_CONNECTION_BROKEN: rc = ECONNABORTED; goto errout; case SCF_ERROR_DELETED: case SCF_ERROR_NOT_FOUND: rc = ENOENT; goto errout; case SCF_ERROR_INVALID_ARGUMENT: rc = EINVAL; goto errout; case SCF_ERROR_CONSTRAINT_VIOLATED: rc = ENOTSUP; goto errout; default: bad_error("scf_handle_decode_fmri", scf_error()); } } if (scf_iter_instance_pgs_composed(load_pgiter, inst, NULL) != 0) { switch (scf_error()) { case SCF_ERROR_DELETED: rc = ECANCELED; goto errout; case SCF_ERROR_CONNECTION_BROKEN: rc = ECONNABORTED; goto errout; default: bad_error("scf_iter_instance_pgs_composed", scf_error()); } } tsize = scf_limit(SCF_LIMIT_MAX_PG_TYPE_LENGTH); type = uu_zalloc(tsize); if (type == NULL) { rc = ENOMEM; goto errout; } /* * Initialize our entity structure. */ e = internal_instance_new(name); if (e == NULL) { rc = ENOMEM; goto errout; } e->sc_fmri = uu_strdup(fmri); if (e->sc_fmri == NULL) { rc = ENOMEM; goto errout; } /* * Walk through the property group's of the instance and capture * the property groups that are of type * SCF_GROUP_TEMPLATE_PG_PATTERN and * SCF_GROUP_TEMPLATE_PROP_PATTERN. In other words grab the * pg_pattern and prop_pattern property groups. */ while ((rc = scf_iter_next_pg(load_pgiter, load_pgroup)) == 1) { if (scf_pg_get_type(load_pgroup, type, tsize) <= 0) { switch (scf_error()) { case SCF_ERROR_DELETED: rc = ENOENT; break; case SCF_ERROR_CONNECTION_BROKEN: rc = ECONNABORTED; break; default: bad_error("scf_pg_get_type", scf_error()); } goto errout; } if ((strcmp(type, SCF_GROUP_TEMPLATE_PG_PATTERN) != 0) && (strcmp(type, SCF_GROUP_TEMPLATE_PROP_PATTERN) != 0)) { continue; } if ((rc = load_pg(load_pgroup, &ipg, fmri, NULL)) != 0) { switch (rc) { case ECANCELED: case ECONNABORTED: case EACCES: case ENOMEM: break; default: bad_error("load_pg", rc); } goto errout; } if (internal_attach_pgroup(e, ipg) != 0) { rc = EBADF; goto errout; } } if (rc == -1) { /* Error in iteration. */ switch (scf_error()) { case SCF_ERROR_CONNECTION_BROKEN: rc = ECONNABORTED; break; case SCF_ERROR_DELETED: rc = ENOENT; break; case SCF_ERROR_NO_RESOURCES: rc = EAGAIN; break; default: bad_error("scf_iter_next_pg", scf_error()); } goto errout; } *inst_ptr = e; scf_instance_destroy(inst); return (0); errout: if (type != NULL) uu_free(type); if (inst != NULL) scf_instance_destroy(inst); if (e != NULL) internal_instance_free(e); return (rc); }
/* * 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); }
Status osDaemonIsEnabled( int inQuiet ) { Status isEnabled = sStatusNotEnabled; scf_handle_t * theHandle = scf_handle_create( SCF_VERSION ); if (inQuiet == 0) { writeInitialMessage( sOpIsEnabled ); } if ( theHandle != 0 ) { if ( scf_handle_bind( theHandle ) == 0 ) { scf_instance_t * theInstance = scf_instance_create( theHandle ); if ( theInstance != 0 ) { if ( scf_handle_decode_fmri( theHandle, sInstanceName, 0, 0, theInstance, 0, 0, SCF_DECODE_FMRI_EXACT ) != -1 ) { scf_handle_t * theInstanceHandle = scf_instance_handle( theInstance ); if ( theInstanceHandle != 0 ) { uint8_t theEnabled; scf_propertygroup_t * theGroup = scf_pg_create( theInstanceHandle ); scf_property_t * theProp = scf_property_create( theInstanceHandle ); scf_value_t * theValue = scf_value_create( theInstanceHandle ); if ( theGroup != 0 && theProp != 0 && theValue != 0 ) { if ( scf_instance_get_pg( theInstance, SCF_PG_GENERAL, theGroup ) == 0 && scf_pg_get_property( theGroup, SCF_PROPERTY_ENABLED, theProp ) == 0 && scf_property_get_value( theProp, theValue ) == 0 && scf_value_get_boolean( theValue, &theEnabled ) == 0 ) { isEnabled = theEnabled == 1 ? sStatusEnabled : sStatusNotEnabled; } } scf_pg_destroy( theGroup ); scf_property_destroy( theProp ); scf_value_destroy( theValue ); } } scf_instance_destroy( theInstance ); } } scf_handle_destroy( theHandle ); } if (inQuiet == 0) { writeFinalMessage( sOpIsEnabled, isEnabled ); } return isEnabled; }
conerr_t smfu_set_property(char *fmri, char *pgname, char *propname, char *value) { conerr_t err = ce_ok; scf_handle_t *scfhandle = handle_create(); scf_service_t *service = scf_service_create(scfhandle); scf_instance_t *instance = scf_instance_create(scfhandle); scf_propertygroup_t *pg = scf_pg_create(scfhandle); scf_property_t *prop = scf_property_create(scfhandle); scf_value_t *val = scf_value_create(scfhandle); scf_transaction_t *tx = scf_transaction_create(scfhandle); scf_transaction_entry_t *ent = scf_entry_create(scfhandle); scf_type_t type; if (scfhandle == NULL || service == NULL || instance == NULL || pg == NULL || prop == NULL || tx == NULL || ent == NULL || val == NULL) { err = ce_nomem; goto out; } if (scf_handle_decode_fmri(scfhandle, fmri, NULL, service, instance, NULL, NULL, 0) != SCF_SUCCESS) { rad_log(RL_ERROR, "couldn't decode '%s': %s\n", fmri, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } if (scf_instance_get_pg(instance, pgname, pg) != 0 || scf_pg_get_property(pg, propname, prop) != 0 || scf_property_type(prop, &type) != 0) { rad_log(RL_ERROR, "couldn't get property: '%s/%s/%s': %s\n", fmri, pgname, propname, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } top: if (scf_transaction_start(tx, pg) == -1 || scf_transaction_property_change(tx, ent, propname, type) != 0 || scf_value_set_from_string(val, type, value) != 0 || scf_entry_add_value(ent, val) != 0) { rad_log(RL_ERROR, "couldn't set property: '%s/%s/%s': %s\n", fmri, pgname, propname, scf_strerror(scf_error())); err = maperr(scf_error()); goto out; } switch (scf_transaction_commit(tx)) { /* success */ case 1: if (smf_refresh_instance(fmri) != 0) { err = maperr(scf_error()); goto out; } break; /* retry */ case 0: if (scf_pg_update(pg) != 0) { err = maperr(scf_error()); goto out; } scf_transaction_reset(tx); goto top; default: err = maperr(scf_error()); goto out; } out: scf_entry_destroy(ent); scf_transaction_destroy(tx); scf_value_destroy(val); scf_property_destroy(prop); scf_pg_destroy(pg); scf_instance_destroy(instance); scf_service_destroy(service); scf_handle_destroy(scfhandle); return (err); }
int delete_instance(const char *instance_name) { int status = FAILURE; char *buf; boolean_t errflag = B_FALSE; ssize_t max_fmri_len; scf_scope_t *scope; scf_service_t *svc; scf_handle_t *handle; scf_instance_t *instance; handle = scf_handle_create(SCF_VERSION); if (handle == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_create failed: %s\n", scf_strerror(scf_error())); goto out1; } KSSL_DEBUG("scf_handle_create succeeded\n"); if (scf_handle_bind(handle) == -1) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_bind failed: %s\n", scf_strerror(scf_error())); goto out1; } KSSL_DEBUG("scf_handle_bind succeeded\n"); if ((scope = scf_scope_create(handle)) == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_scope_create failed: %s\n", scf_strerror(scf_error())); goto out2; } KSSL_DEBUG("scf_scope_create succeeded\n"); if ((svc = scf_service_create(handle)) == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_service_create failed: %s\n", scf_strerror(scf_error())); goto out3; } KSSL_DEBUG("scf_service_create succeeded\n"); if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) == -1) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_get_scope failed: %s\n", scf_strerror(scf_error())); goto out4; } KSSL_DEBUG("scf_handle_get_scope succeeded\n"); if (scf_scope_get_service(scope, SERVICE_NAME, svc) < 0) { scf_error_t scf_errnum = scf_error(); if (scf_errnum != SCF_ERROR_NOT_FOUND) { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_scope_get_service failed: %s\n", scf_strerror(scf_errnum)); } goto out4; } else { KSSL_DEBUG("scf_scope_get_service succeeded\n"); } instance = scf_instance_create(handle); if (instance == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_instance_create failed: %s\n", scf_strerror(scf_error())); goto out4; } if (scf_service_get_instance(svc, instance_name, instance) != 0) { scf_error_t scf_errnum = scf_error(); if (scf_errnum == SCF_ERROR_NOT_FOUND) { status = SUCCESS; } else { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_scope_get_service failed: %s\n", scf_strerror(scf_errnum)); } scf_instance_destroy(instance); goto out4; } max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if ((buf = malloc(max_fmri_len + 1)) == NULL) goto out4; if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) { char *state; KSSL_DEBUG("instance_fmri=%s\n", buf); state = smf_get_state(buf); if (state) KSSL_DEBUG("state=%s\n", state); if (state && strcmp(state, "online") == 0) { if (smf_disable_instance(buf, 0) != 0) { errflag = B_TRUE; KSSL_DEBUG( "smf_disable_instance failed: %s\n", scf_strerror(scf_error())); } else { /* * Wait for some time till timeout to avoid * a race with scf_instance_delete() below. */ wait_till_to(buf); } } } if (scf_instance_delete(instance) != 0) { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_instance_delete failed: %s\n", scf_strerror(scf_error())); goto out4; } else { KSSL_DEBUG("deleted %s\n", instance_name); } status = SUCCESS; out4: scf_service_destroy(svc); out3: scf_scope_destroy(scope); out2: (void) scf_handle_unbind(handle); out1: if (handle != NULL) scf_handle_destroy(handle); if (errflag) (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); return (status); }
static void modify_defaults(int argc, char *argv[]) { int i, j; char *value; scf_instance_t *inst; inetd_prop_t *mod, *prop_table; size_t numprops; ssize_t max_val; int64_t new_int; if ((inst = scf_instance_create(h)) == NULL) scfdie(); if (scf_handle_decode_fmri(h, INETD_INSTANCE_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) == -1) { if (scf_error() == SCF_ERROR_NOT_FOUND) { uu_die(gettext("inetd instance missing in repository." "\n")); } else { scfdie(); } } if ((max_val = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH)) < 0) scfdie(); prop_table = get_prop_table(&numprops); if ((mod = malloc(numprops * sizeof (inetd_prop_t))) == NULL) uu_die(gettext("Error: Out of memory.\n")); (void) memcpy(mod, prop_table, numprops * sizeof (inetd_prop_t)); for (i = 0; i < argc; i++) { /* Separate argument into name and value pair */ if ((value = strchr(argv[i], '=')) == NULL) uu_die(gettext("Error: Malformed name=value pair \"%s" "\"\n"), argv[i]); *value = '\0'; value++; /* Find property name in array of defaults */ for (j = 0; mod[j].ip_name != NULL; j++) { if (!mod[j].ip_default) continue; if (strcmp(mod[j].ip_name, argv[i]) == 0) break; } if (mod[j].ip_name == NULL) uu_die(gettext("Error: \"%s\" is not a default inetd " "property.\n"), argv[i]); if (*value == '\0') uu_die(gettext("Cannot accept NULL values for default " "properties.\n")); switch (mod[j].ip_type) { case INET_TYPE_INTEGER: if (uu_strtoint(value, &new_int, sizeof (new_int), NULL, NULL, NULL) == -1) uu_die(gettext("Error: \"%s\" is not a valid " "integer value.\n"), value); mod[j].ip_value.iv_int = new_int; break; case INET_TYPE_STRING: if (strlen(value) >= max_val) uu_die(gettext("Error: String value is longer " "than %l characters.\n"), max_val); if ((mod[j].ip_value.iv_string = strdup(value)) == NULL) uu_die(gettext("Error: Out of memory.\n")); break; case INET_TYPE_BOOLEAN: if (strcasecmp(value, INETADM_TRUE_STR) == 0) mod[j].ip_value.iv_boolean = B_TRUE; else if (strcasecmp(value, INETADM_FALSE_STR) == 0) mod[j].ip_value.iv_boolean = B_FALSE; else uu_die(gettext("Error: \"%s\" is not a valid " "boolean value. (TRUE or FALSE)\n"), value); } /* mark property for modification */ mod[j].ip_error = IVE_VALID; } commit_props(inst, mod, B_TRUE); free(mod); scf_instance_destroy(inst); if (refresh_inetd() != 0) uu_warn(gettext("Warning: Unable to refresh inetd.\n")); }
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); }
/* * store_inetd_hash stores the string hash in inetd's configuration file hash * in the repository. On success, SCF_ERROR_NONE is returned. Otherwise, the * scf_error value is returned. */ scf_error_t store_inetd_hash(const char *hash) { int ret; scf_error_t rval = SCF_ERROR_NONE; scf_handle_t *h; scf_propertygroup_t *pg = NULL; scf_instance_t *inst = NULL; scf_transaction_t *tx = NULL; scf_transaction_entry_t *txent = NULL; scf_property_t *prop = NULL; scf_value_t *val = NULL; if ((h = scf_handle_create(SCF_VERSION)) == NULL || scf_handle_bind(h) == -1) goto error; if ((pg = scf_pg_create(h)) == NULL || (inst = scf_instance_create(h)) == NULL || scf_handle_decode_fmri(h, INETD_INSTANCE_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) == -1) goto error; if (scf_instance_get_pg(inst, HASH_PG, pg) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND || scf_instance_add_pg(inst, HASH_PG, SCF_GROUP_APPLICATION, 0, pg) == -1) goto error; } if ((tx = scf_transaction_create(h)) == NULL || (txent = scf_entry_create(h)) == NULL || (prop = scf_property_create(h)) == NULL || (val = scf_value_create(h)) == NULL) goto error; do { if (scf_transaction_start(tx, pg) == -1) goto error; if (scf_transaction_property_new(tx, txent, HASH_PROP, SCF_TYPE_ASTRING) == -1 && scf_transaction_property_change_type(tx, txent, HASH_PROP, SCF_TYPE_ASTRING) == -1) goto error; if (scf_value_set_astring(val, hash) == -1 || scf_entry_add_value(txent, val) == -1) goto error; if ((ret = scf_transaction_commit(tx)) == -1) goto error; if (ret == 0) { scf_transaction_reset(tx); if (scf_pg_update(pg) == -1) goto error; } } while (ret == 0); goto success; error: rval = scf_error(); success: scf_value_destroy(val); scf_property_destroy(prop); scf_entry_destroy(txent); scf_transaction_destroy(tx); scf_instance_destroy(inst); scf_pg_destroy(pg); scf_handle_destroy(h); return (rval); }
static int create_instance(scf_handle_t *handle, scf_service_t *svc, const char *instance_name, const char *kssl_entry, const char *command, const char *username, char *inaddr_any_name) { int status = FAILURE; char *buf; boolean_t errflag = B_FALSE; ssize_t max_fmri_len; scf_instance_t *instance; instance = scf_instance_create(handle); if (instance == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_instance_create failed: %s\n", scf_strerror(scf_error())); goto out; } KSSL_DEBUG("scf_instance_create succeeded\n"); if (scf_service_get_instance(svc, inaddr_any_name, instance) == 0) { /* Let the caller deal with the duplicate instance */ status = INSTANCE_ANY_EXISTS; goto out; } if (scf_service_add_instance(svc, instance_name, instance) != 0) { if (scf_error() == SCF_ERROR_EXISTS) { /* Let the caller deal with the duplicate instance */ status = INSTANCE_OTHER_EXISTS; goto out; } errflag = B_TRUE; KSSL_DEBUG("scf_service_add_instance failed: %s\n", scf_strerror(scf_error())); goto out; } KSSL_DEBUG("scf_service_add_instance succeeded\n"); if ((add_pg_method(handle, instance, kssl_entry, "start", command, username) != SUCCESS) || (add_pg_method(handle, instance, kssl_entry, "refresh", command, username) != SUCCESS) || (add_pg_method(handle, instance, kssl_entry, "stop", "", username) != SUCCESS)) { scf_instance_destroy(instance); return (status); } /* enabling the instance */ max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if ((buf = malloc(max_fmri_len + 1)) == NULL) goto out; if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) { KSSL_DEBUG("instance_fmri=%s\n", buf); if (smf_enable_instance(buf, 0) != 0) { errflag = B_TRUE; KSSL_DEBUG( "smf_enable_instance failed: %s\n", scf_strerror(scf_error())); goto out; } status = SUCCESS; } out: if (instance != NULL) scf_instance_destroy(instance); if (errflag) (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); return (status); }