Example #1
0
static void
delete_prop(const scf_instance_t *inst, const char *pg, const char *prop)
{
	scf_transaction_t		*tx;
	scf_transaction_entry_t		*ent;
	scf_propertygroup_t		*gpg;
	scf_property_t			*eprop;
	int				ret;

	if ((gpg = scf_pg_create(h)) == NULL ||
	    (eprop = scf_property_create(h)) == NULL ||
	    (tx = scf_transaction_create(h)) == NULL ||
	    (ent = scf_entry_create(h)) == NULL)
		scfdie();

	if (scf_instance_get_pg(inst, pg, gpg) != SCF_SUCCESS) {
		if (scf_error() != SCF_ERROR_NOT_FOUND)
			scfdie();

		uu_die(gettext("Error: \"%s\" property group missing.\n"), pg);
	}

	do {
		if (scf_transaction_start(tx, gpg) != SCF_SUCCESS) {
			if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
				scfdie();

			uu_die(gettext("Error: Permission denied.\n"));
		}

		if (scf_transaction_property_delete(tx, ent,
		    prop) != SCF_SUCCESS) {
			if (scf_error() != SCF_ERROR_NOT_FOUND)
				scfdie();

			uu_die(
			    gettext("Error: \"%s\" property does not exist.\n"),
			    prop);
		}

		ret = scf_transaction_commit(tx);
		if (ret < 0) {
			if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
				scfdie();

			uu_die(gettext("Error: Permission denied.\n"));
		}
		if (ret == 0) {
			scf_transaction_reset(tx);
			if (scf_pg_update(gpg) == -1)
				scfdie();
		}
	} while (ret == 0);

	(void) scf_entry_destroy(ent);
	scf_transaction_destroy(tx);
	scf_property_destroy(eprop);
	scf_pg_destroy(gpg);
}
Example #2
0
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);
}
Example #3
0
/*
 * smb_smf_delete_instance_pgroup(handle, pgroup)
 *
 * remove the property group from the current instance.
 * but only if it actually exists.
 */
int
smb_smf_delete_instance_pgroup(smb_scfhandle_t *handle, char *pgroup)
{
	int ret = SMBC_SMF_OK;
	int err;

	if (handle == NULL) {
		return (SMBC_SMF_SYSTEM_ERR);
	}

	/*
	 * only create a handle if it doesn't exist. It is ok to exist
	 * since the pg handle will be set as a side effect.
	 */
	if (handle->scf_pg == NULL) {
		handle->scf_pg = scf_pg_create(handle->scf_handle);
	}

	/*
	 * only delete if it does exist.
	 */
	if (scf_instance_get_pg(handle->scf_instance,
	    pgroup, handle->scf_pg) == 0) {
		/* does exist so delete it */
		if (scf_pg_delete(handle->scf_pg) != 0) {
			ret = SMBC_SMF_SYSTEM_ERR;
			err = scf_error();
			if (err != SCF_ERROR_NONE) {
				smb_smf_scf_log_error("SMF delpg "
				    "problem: %s\n");
			}
		}
	} else {
		err = scf_error();
		if (err != SCF_ERROR_NONE)
			smb_smf_scf_log_error("SMF getpg problem: %s\n");
		ret = SMBC_SMF_SYSTEM_ERR;
	}
	if (ret == SMBC_SMF_SYSTEM_ERR &&
	    scf_error() == SCF_ERROR_PERMISSION_DENIED) {
		ret = SMBC_SMF_NO_PERMISSION;
	}
	return (ret);
}
Example #4
0
/*
 * smb_smf_create_instance_pgroup(handle, pgroup)
 *
 * create a new property group at instance level.
 */
int
smb_smf_create_instance_pgroup(smb_scfhandle_t *handle, char *pgroup)
{
	int ret = SMBC_SMF_OK;
	int err;

	if (handle == NULL) {
		return (SMBC_SMF_SYSTEM_ERR);
	}

	/*
	 * only create a handle if it doesn't exist. It is ok to exist
	 * since the pg handle will be set as a side effect.
	 */
	if (handle->scf_pg == NULL) {
		handle->scf_pg = scf_pg_create(handle->scf_handle);
	}

	/*
	 * if the pgroup exists, we are done. If it doesn't, then we
	 * need to actually add one to the service instance.
	 */
	if (scf_instance_get_pg(handle->scf_instance,
	    pgroup, handle->scf_pg) != 0) {
		/* doesn't exist so create one */
		if (scf_instance_add_pg(handle->scf_instance, pgroup,
		    SCF_GROUP_APPLICATION, 0, handle->scf_pg) != 0) {
			err = scf_error();
			if (err != SCF_ERROR_NONE)
				smb_smf_scf_log_error(NULL);
			switch (err) {
			case SCF_ERROR_PERMISSION_DENIED:
				ret = SMBC_SMF_NO_PERMISSION;
				break;
			default:
				ret = SMBC_SMF_SYSTEM_ERR;
				break;
			}
		}
	}
	return (ret);
}
Example #5
0
/*
 * 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);
}
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;
}
Example #7
0
int
fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf,
    char *instance, scf_type_t sctype, char *fmri, int *bufsz)
{
	fs_smfhandle_t *phandle = NULL;
	scf_handle_t *handle;
	scf_propertygroup_t *pg;
	scf_property_t *prop;
	scf_value_t *val;
	scf_instance_t *inst;
	int ret = 0, len = 0, length;
	int64_t valint = 0;
	char srv[MAXPATHLEN], *p, *svcname;
	const char *pgname;
	uint8_t bval;

	/*
	 * The SVC names we are using currently are already
	 * appended by default. Fix this for instances project.
	 */
	snprintf(srv, MAXPATHLEN, "%s", fmri);
	p = strstr(fmri, ":default");
	if (p == NULL) {
		strcat(srv, ":");
		if (instance == NULL)
			instance = "default";
		if (strlen(srv) + strlen(instance) > MAXPATHLEN)
			goto out;
		strncat(srv, instance, strlen(instance));
	}
	svcname = srv;
	phandle = fs_smf_init(fmri, instance);
	if (phandle == NULL)
		return (SMF_SYSTEM_ERR);
	handle = phandle->fs_handle;
	pg = phandle->fs_pg;
	inst = phandle->fs_instance;
	prop = phandle->fs_property;
	val = phandle->fs_value;

	if (handle == NULL || pg == NULL || prop == NULL || val == NULL ||
	    inst == NULL)  {
		return (SMF_SYSTEM_ERR);
	}


	if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
	    phandle->fs_service, inst, NULL, NULL, 0) != 0) {
		ret = scf_error();
		goto out;
	}

	if (fstype == AUTOFS_SMF)
		pgname = AUTOFS_PROPS_PGNAME;
	else
		pgname = NFS_PROPS_PGNAME;

	if (scf_instance_get_pg(inst, pgname, pg) != -1) {
		if (scf_pg_get_property(pg, prop_name,
		    prop) != SCF_SUCCESS) {
			ret = scf_error();
			goto out;
		}
		if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
			ret = scf_error();
			goto out;
		}
		switch (sctype) {
		case SCF_TYPE_ASTRING:
			len = scf_value_get_astring(val, cbuf, *bufsz);
			if (len < 0 || len > *bufsz) {
				ret = scf_error();
				goto out;
			}
			ret = 0;
			*bufsz = len;
		break;
		case SCF_TYPE_INTEGER:
			if (scf_value_get_integer(val, &valint) != 0) {
				ret = scf_error();
				goto out;
			}
			length =  snprintf(cbuf, *bufsz, "%lld", valint);
			if (length < 0 || length > *bufsz) {
				ret = SA_BAD_VALUE;
				goto out;
			}
			ret = 0;
		break;
		case SCF_TYPE_BOOLEAN:
			if (scf_value_get_boolean(val, &bval) != 0) {
				ret = scf_error();
				goto out;
			}
			if (bval == 1) {
				length = snprintf(cbuf, *bufsz, "%s", "true");
			} else {
				length = snprintf(cbuf, *bufsz, "%s", "false");
			}
			if (length < 0 || length > *bufsz) {
				ret = SA_BAD_VALUE;
				goto out;
			}
		break;
		}
	} else {
		ret = scf_error();
	}
	if ((ret != 0) && scf_error() != SCF_ERROR_NONE) {
		/*
		 * This is a workaround for the NFS service manifests not
		 * containing the proper properties in local zones.
		 *
		 * When in a local zone and the property doesn't exist on an NFS
		 * service (most likely nfs/server or nfs/client), don't print
		 * the error.  The caller will still see the correct error code,
		 * but a user creating a delegated dataset or mounting an NFS
		 * share won't see this spurious error.
		 */
		if (getzoneid() == GLOBAL_ZONEID ||
		    scf_error() != SCF_ERROR_NOT_FOUND) {
			fprintf(stdout, gettext("%s\n"), scf_strerror(ret));
		}
	}

out:
	fs_smf_fini(phandle);
	return (ret);
}
Example #8
0
int
fs_smf_set_prop(smf_fstype_t fstype, char *prop_name, char *valbuf,
    char *instance, scf_type_t sctype, char *fmri)
{
	fs_smfhandle_t *phandle = NULL;
	scf_handle_t *handle;
	scf_propertygroup_t *pg;
	scf_property_t *prop;
	scf_transaction_t *tran = NULL;
	scf_transaction_entry_t *entry = NULL;
	scf_instance_t *inst;
	scf_value_t *val;
	int valint;
	int index = 0;
	int ret = 0;
	char *p = NULL;
	char *svcname, srv[MAXPATHLEN];
	const char *pgname;

	/*
	 * The SVC names we are using currently are already
	 * appended by default. Fix this for instances project.
	 */
	snprintf(srv, MAXPATHLEN, "%s", fmri);
	p = strstr(fmri, ":default");
	if (p == NULL) {
		strcat(srv, ":");
		if (instance == NULL)
			instance = "default";
		if (strlen(srv) + strlen(instance) > MAXPATHLEN)
			goto out;
		strncat(srv, instance, strlen(instance));
	}
	svcname = srv;
	phandle = fs_smf_init(fmri, instance);
	if (phandle == NULL) {
		return (SMF_SYSTEM_ERR);
	}
	handle = phandle->fs_handle;
	pg = phandle->fs_pg;
	prop = phandle->fs_property;
	inst = phandle->fs_instance;
	val = phandle->fs_value;
	tran = scf_transaction_create(handle);
	entry = scf_entry_create(handle);

	if (handle == NULL || pg == NULL || prop == NULL ||
	    val == NULL|| tran == NULL || entry == NULL || inst == NULL) {
		ret = SMF_SYSTEM_ERR;
		goto out;
	}

	if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
	    phandle->fs_service, inst, NULL, NULL, 0) != 0) {
		ret = scf_error();
		goto out;
	}
	if (fstype == AUTOFS_SMF)
		pgname = AUTOFS_PROPS_PGNAME;
	else
		pgname = NFS_PROPS_PGNAME;

	if (scf_instance_get_pg(inst, pgname,
	    pg) != -1) {
		uint8_t	vint;
		if (scf_transaction_start(tran, pg) == -1) {
			ret = scf_error();
			goto out;
		}
		switch (sctype) {
		case SCF_TYPE_INTEGER:
			errno = 0;
			valint = strtoul(valbuf, NULL, 0);
			if (errno != 0) {
				ret = SMF_SYSTEM_ERR;
				goto out;
			}
			if (scf_transaction_property_change(tran,
			    entry, prop_name, SCF_TYPE_INTEGER) == 0) {
				scf_value_set_integer(val, valint);
				if (scf_entry_add_value(entry, val) < 0) {
					ret = scf_error();
					goto out;
				}
			}
			break;
		case SCF_TYPE_ASTRING:
			if (scf_transaction_property_change(tran, entry,
			    prop_name, SCF_TYPE_ASTRING) == 0) {
				if (scf_value_set_astring(val,
				    valbuf) == 0) {
					if (scf_entry_add_value(entry,
					    val) != 0) {
						ret = scf_error();
						goto out;
					}
				} else
					ret = SMF_SYSTEM_ERR;
			} else
				ret = SMF_SYSTEM_ERR;
			break;
		case SCF_TYPE_BOOLEAN:
			if (strcmp(valbuf, "1") == 0) {
				vint = 1;
			} else if (strcmp(valbuf, "0") == 0) {
				vint = 0;
			} else  {
				ret = SMF_SYSTEM_ERR;
				break;
			}
			if (scf_transaction_property_change(tran, entry,
			    prop_name, SCF_TYPE_BOOLEAN) == 0) {
				scf_value_set_boolean(val, (uint8_t)vint);
				if (scf_entry_add_value(entry, val) != 0) {
					ret = scf_error();
					goto out;
				}
			} else {
				ret = SMF_SYSTEM_ERR;
			}
			break;
		}
		if (ret != SMF_SYSTEM_ERR)
			scf_transaction_commit(tran);
	}
out:
	if (tran != NULL)
		scf_transaction_destroy(tran);
	if (entry != NULL)
		scf_entry_destroy(entry);
	fs_smf_fini(phandle);
	return (ret);
}
Example #9
0
/* ARGSUSED */
static int
do_wait(void *unused, scf_walkinfo_t *wip)
{
	scf_property_t *prop;
	scf_propertygroup_t *lpg, *pg;
	const char *propname;
	svcprop_prop_node_t *p;

	const char *emsg_not_found = gettext("Not found.\n");

	if ((lpg = scf_pg_create(hndl)) == NULL ||
	    (prop = scf_property_create(hndl)) == NULL)
		scfdie();

	if (wip->prop != NULL) {
		if (uu_list_numnodes(prop_list) > 0)
			uu_xdie(UU_EXIT_USAGE, gettext("-p cannot be used with "
			    "property FMRIs.\n"));
		pg = wip->pg;

		assert(strrchr(wip->fmri, '/') != NULL);
		propname = strrchr(wip->fmri, '/') + 1;

	} else if (wip->pg != NULL) {
		p = uu_list_first(prop_list);

		if (p != NULL) {
			if (p->spn_comp2 != NULL)
				uu_xdie(UU_EXIT_USAGE, gettext("-p argument "
				    "\"%s/%s\" has too many components for "
				    "property group %s.\n"),
				    p->spn_comp1, p->spn_comp2, wip->fmri);

			propname = p->spn_comp1;

			if (scf_pg_get_property(wip->pg, propname, prop) !=
			    SCF_SUCCESS) {
				switch (scf_error()) {
				case SCF_ERROR_INVALID_ARGUMENT:
					uu_xdie(UU_EXIT_USAGE,
					    gettext("Invalid property name "
					    "\"%s\".\n"), propname);

					/* NOTREACHED */

				case SCF_ERROR_NOT_FOUND:
					die(emsg_not_found);

					/* NOTREACHED */

				default:
					scfdie();
				}
			}
		} else {
			propname = NULL;
		}

		pg = wip->pg;

	} else if (wip->inst != NULL) {

		p = uu_list_first(prop_list);
		if (p == NULL)
			uu_xdie(UU_EXIT_USAGE,
			    gettext("Cannot wait for an instance.\n"));

		if (scf_instance_get_pg(wip->inst, p->spn_comp1, lpg) !=
		    SCF_SUCCESS) {
			switch (scf_error()) {
			case SCF_ERROR_INVALID_ARGUMENT:
				uu_xdie(UU_EXIT_USAGE, gettext("Invalid "
				    "property group name \"%s\".\n"),
				    p->spn_comp1);

			case SCF_ERROR_NOT_FOUND:
				die(emsg_not_found);

				/* NOTREACHED */

			default:
				scfdie();
			}
		}

		propname = p->spn_comp2;

		if (propname != NULL) {
			if (scf_pg_get_property(lpg, propname, prop) !=
			    SCF_SUCCESS) {
				switch (scf_error()) {
				case SCF_ERROR_INVALID_ARGUMENT:
					uu_xdie(UU_EXIT_USAGE,
					    gettext("Invalid property name "
					    "\"%s\".\n"), propname);

				case SCF_ERROR_NOT_FOUND:
					die(emsg_not_found);

					/* NOTREACHED */

				default:
					scfdie();
				}
			}
		}

		pg = lpg;

	} else if (wip->svc != NULL) {

		p = uu_list_first(prop_list);
		if (p == NULL)
			uu_xdie(UU_EXIT_USAGE,
			    gettext("Cannot wait for a service.\n"));

		if (scf_service_get_pg(wip->svc, p->spn_comp1, lpg) !=
		    SCF_SUCCESS) {
			switch (scf_error()) {
			case SCF_ERROR_INVALID_ARGUMENT:
				uu_xdie(UU_EXIT_USAGE, gettext("Invalid "
				    "property group name \"%s\".\n"),
				    p->spn_comp1);

			case SCF_ERROR_NOT_FOUND:
				die(emsg_not_found);

			default:
				scfdie();
			}
		}

		propname = p->spn_comp2;

		if (propname != NULL) {
			if (scf_pg_get_property(lpg, propname, prop) !=
			    SCF_SUCCESS) {
				switch (scf_error()) {
				case SCF_ERROR_INVALID_ARGUMENT:
					uu_xdie(UU_EXIT_USAGE,
					    gettext("Invalid property name "
					    "\"%s\".\n"), propname);

					/* NOTREACHED */

				case SCF_ERROR_NOT_FOUND:
					die(emsg_not_found);

					/* NOTREACHED */

				default:
					scfdie();
				}
			}
		}

		pg = lpg;

	} else {
		uu_xdie(UU_EXIT_USAGE, gettext("FMRI must specify an entity, "
		    "property group, or property.\n"));
	}

	for (;;) {
		int ret;

		ret = _scf_pg_wait(pg, -1);
		if (ret != SCF_SUCCESS)
			scfdie();

		ret = scf_pg_update(pg);
		if (ret < 0) {
			if (scf_error() != SCF_ERROR_DELETED)
				scfdie();

			die(emsg_not_found);
		}
		if (ret == SCF_COMPLETE)
			break;
	}

	if (propname != NULL) {
		if (scf_pg_get_property(pg, propname, prop) == SCF_SUCCESS) {
			if (!quiet)
				display_prop(pg, prop);
		} else {
			if (scf_error() != SCF_ERROR_NOT_FOUND)
				scfdie();

			if (PRINT_NOPROP_ERRORS)
				uu_warn(emsg_not_found);

			return_code = UU_EXIT_FATAL;
		}
	} else {
		if (!quiet)
			display_pg(pg);
	}

	scf_property_destroy(prop);
	scf_pg_destroy(lpg);

	return (0);
}
Example #10
0
/*
 * 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);
}
Example #11
0
int
fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf,
    char *instance, scf_type_t sctype, char *fmri, int *bufsz)
{
	fs_smfhandle_t *phandle = NULL;
	scf_handle_t *handle;
	scf_propertygroup_t *pg;
	scf_property_t *prop;
	scf_value_t *val;
	scf_instance_t *inst;
	int ret = 0, len = 0, length;
	int64_t valint = 0;
	char srv[MAXPATHLEN], *p, *svcname;
	const char *pgname;
	uint8_t bval;

	/*
	 * The SVC names we are using currently are already
	 * appended by default. Fix this for instances project.
	 */
	snprintf(srv, MAXPATHLEN, "%s", fmri);
	p = strstr(fmri, ":default");
	if (p == NULL) {
		strcat(srv, ":");
		if (instance == NULL)
			instance = "default";
		if (strlen(srv) + strlen(instance) > MAXPATHLEN)
			goto out;
		strncat(srv, instance, strlen(instance));
	}
	svcname = srv;
	phandle = fs_smf_init(fmri, instance);
	if (phandle == NULL)
		return (SMF_SYSTEM_ERR);
	handle = phandle->fs_handle;
	pg = phandle->fs_pg;
	inst = phandle->fs_instance;
	prop = phandle->fs_property;
	val = phandle->fs_value;

	if (handle == NULL || pg == NULL || prop == NULL || val == NULL ||
	    inst == NULL)  {
		return (SMF_SYSTEM_ERR);
	}


	if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
	    phandle->fs_service, inst, NULL, NULL, 0) != 0) {
		ret = scf_error();
		goto out;
	}

	if (fstype == AUTOFS_SMF)
		pgname = AUTOFS_PROPS_PGNAME;
	else
		pgname = NFS_PROPS_PGNAME;

	if (scf_instance_get_pg(inst, pgname, pg) != -1) {
		if (scf_pg_get_property(pg, prop_name,
		    prop) != SCF_SUCCESS) {
			ret = scf_error();
			goto out;
		}
		if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
			ret = scf_error();
			goto out;
		}
		switch (sctype) {
		case SCF_TYPE_ASTRING:
			len = scf_value_get_astring(val, cbuf, *bufsz);
			if (len < 0 || len > *bufsz) {
				ret = scf_error();
				goto out;
			}
			ret = 0;
			*bufsz = len;
		break;
		case SCF_TYPE_INTEGER:
			if (scf_value_get_integer(val, &valint) != 0) {
				ret = scf_error();
				goto out;
			}
			length =  snprintf(cbuf, *bufsz, "%lld", valint);
			if (length < 0 || length > *bufsz) {
				ret = SA_BAD_VALUE;
				goto out;
			}
			ret = 0;
		break;
		case SCF_TYPE_BOOLEAN:
			if (scf_value_get_boolean(val, &bval) != 0) {
				ret = scf_error();
				goto out;
			}
			if (bval == 1) {
				length = snprintf(cbuf, *bufsz, "%s", "true");
			} else {
				length = snprintf(cbuf, *bufsz, "%s", "false");
			}
			if (length < 0 || length > *bufsz) {
				ret = SA_BAD_VALUE;
				goto out;
			}
		break;
		}
	} else {
		ret = scf_error();
	}
	if ((ret != 0) && scf_error() != SCF_ERROR_NONE)
		fprintf(stdout, gettext("%s\n"), scf_strerror(ret));
out:
	fs_smf_fini(phandle);
	return (ret);
}
Example #12
0
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);
}
Example #13
0
static void
modify_prop(const scf_instance_t *inst, const char *pg, const char *prop,
    scf_type_t type, void *value)
{
	scf_transaction_t		*tx;
	scf_transaction_entry_t		*ent;
	scf_propertygroup_t		*gpg;
	scf_property_t			*eprop;
	scf_value_t			*v;
	int				ret, create = 0;
	char				*fmri;
	ssize_t				max_fmri_len;

	if ((gpg = scf_pg_create(h)) == NULL ||
	    (eprop = scf_property_create(h)) == NULL ||
	    (v = scf_value_create(h)) == NULL)
		scfdie();

	/* Get the property group or create it if it is missing. */
	if (scf_instance_get_pg(inst, pg, gpg) == -1) {
		if (scf_error() != SCF_ERROR_NOT_FOUND)
			scfdie();

		max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH);
		if ((fmri = malloc(max_fmri_len + 1)) == NULL)
			uu_die(gettext("Error: Out of memory.\n"));

		if (scf_instance_to_fmri(inst, fmri, max_fmri_len + 1) < 0)
			scfdie();

		syslog(LOG_NOTICE, "inetadm: Property group \"%s\" missing "
		    "from \"%s\", attempting to add it.\n", pg, fmri);
		free(fmri);

		if (scf_instance_add_pg(inst, pg, SCF_GROUP_FRAMEWORK, 0,
		    gpg) == -1) {
			switch (scf_error()) {
			case SCF_ERROR_EXISTS:
				break;
			case SCF_ERROR_PERMISSION_DENIED:
				uu_die(gettext("Error: Permission denied.\n"));
			default:
				scfdie();
			}
		}
	}

	if (scf_pg_get_property(gpg, prop, eprop) == -1) {
		if (scf_error() != SCF_ERROR_NOT_FOUND)
			scfdie();

		create = 1;
	}

	if ((tx = scf_transaction_create(h)) == NULL ||
	    (ent = scf_entry_create(h)) == NULL)
		scfdie();

	do {
		uu_list_t	*sv_list;

		if (scf_transaction_start(tx, gpg) == -1) {
			if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
				scfdie();

			uu_die(gettext("Error: Permission denied.\n"));
		}

		/* Modify the property or create it if it is missing */
		if (create)
			ret = scf_transaction_property_new(tx, ent, prop, type);
		else
			ret = scf_transaction_property_change_type(tx, ent,
			    prop, type);
		if (ret == -1)
			scfdie();

		switch (type) {
		case SCF_TYPE_BOOLEAN:
			scf_value_set_boolean(v, *(uint8_t *)value);
			break;
		case SCF_TYPE_INTEGER:
			scf_value_set_integer(v, *(int64_t *)value);
			break;
		case SCF_TYPE_ASTRING:
			if (strcmp(prop, PR_PROTO_NAME) == 0) {
				add_proto_list(ent, h, (char **)value,
				    &sv_list);
			} else if (scf_value_set_astring(v, value) == -1) {
				scfdie();
			}
			break;
		default:
			uu_die(gettext("Error: Internal inetadm error"));
		}

		if ((strcmp(prop, PR_PROTO_NAME) != 0) &&
		    (scf_entry_add_value(ent, v) == -1))
			scfdie();

		ret = scf_transaction_commit(tx);
		if (ret == -1) {
			if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
				scfdie();

			uu_die(gettext("Error: Permission denied.\n"));
		}

		scf_transaction_reset(tx);

		if (ret == 0) {
			if (scf_pg_update(gpg) == -1)
				scfdie();
		}

		if (strcmp(prop, PR_PROTO_NAME) == 0)
			remove_proto_list(ent, sv_list);

	} while (ret == 0);

	scf_value_destroy(v);
	scf_entry_destroy(ent);
	scf_transaction_destroy(tx);
	scf_property_destroy(eprop);
	scf_pg_destroy(gpg);
}