1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <syslog.h>
27 #include <stdarg.h>
28 #include "smfcfg.h"
29
30 fs_smfhandle_t *
fs_smf_init(char * fmri,char * instance)31 fs_smf_init(char *fmri, char *instance)
32 {
33 fs_smfhandle_t *handle = NULL;
34 char *svcname, srv[MAXPATHLEN];
35
36 /*
37 * svc name is of the form svc://network/fs/server:instance1
38 * FMRI portion is /network/fs/server
39 */
40 snprintf(srv, MAXPATHLEN, "%s", fmri + strlen("svc:/"));
41 svcname = strrchr(srv, ':');
42 if (svcname != NULL)
43 *svcname = '\0';
44 svcname = srv;
45
46 handle = calloc(1, sizeof (fs_smfhandle_t));
47 if (handle != NULL) {
48 handle->fs_handle = scf_handle_create(SCF_VERSION);
49 if (handle->fs_handle == NULL)
50 goto out;
51 if (scf_handle_bind(handle->fs_handle) != 0)
52 goto out;
53 handle->fs_service =
54 scf_service_create(handle->fs_handle);
55 handle->fs_scope =
56 scf_scope_create(handle->fs_handle);
57 if (scf_handle_get_local_scope(handle->fs_handle,
58 handle->fs_scope) != 0)
59 goto out;
60 if (scf_scope_get_service(handle->fs_scope,
61 svcname, handle->fs_service) != SCF_SUCCESS) {
62 goto out;
63 }
64 handle->fs_pg =
65 scf_pg_create(handle->fs_handle);
66 handle->fs_instance =
67 scf_instance_create(handle->fs_handle);
68 handle->fs_property =
69 scf_property_create(handle->fs_handle);
70 handle->fs_value =
71 scf_value_create(handle->fs_handle);
72 } else {
73 fprintf(stderr,
74 gettext("Cannot access SMF repository: %s\n"), fmri);
75 }
76 return (handle);
77
78 out:
79 fs_smf_fini(handle);
80 fprintf(stderr, gettext("SMF Initialization problems..%s\n"), fmri);
81 return (NULL);
82 }
83
84
85 void
fs_smf_fini(fs_smfhandle_t * handle)86 fs_smf_fini(fs_smfhandle_t *handle)
87 {
88 if (handle != NULL) {
89 scf_scope_destroy(handle->fs_scope);
90 scf_instance_destroy(handle->fs_instance);
91 scf_service_destroy(handle->fs_service);
92 scf_pg_destroy(handle->fs_pg);
93 scf_property_destroy(handle->fs_property);
94 scf_value_destroy(handle->fs_value);
95 if (handle->fs_handle != NULL) {
96 scf_handle_unbind(handle->fs_handle);
97 scf_handle_destroy(handle->fs_handle);
98 }
99 free(handle);
100 }
101 }
102
103 int
fs_smf_set_prop(smf_fstype_t fstype,char * prop_name,char * valbuf,char * instance,scf_type_t sctype,char * fmri)104 fs_smf_set_prop(smf_fstype_t fstype, char *prop_name, char *valbuf,
105 char *instance, scf_type_t sctype, char *fmri)
106 {
107 fs_smfhandle_t *phandle;
108 scf_handle_t *handle;
109 scf_propertygroup_t *pg;
110 scf_property_t *prop;
111 scf_transaction_t *tran;
112 scf_transaction_entry_t *entry;
113 scf_instance_t *inst;
114 scf_value_t *val;
115 int valint;
116 int index = 0;
117 int ret = 0;
118 char *p = NULL;
119 char *svcname, srv[MAXPATHLEN];
120 const char *pgname;
121
122 /*
123 * The SVC names we are using currently are already
124 * appended by default. Fix this for instances project.
125 */
126 snprintf(srv, MAXPATHLEN, "%s", fmri);
127 p = strstr(fmri, ":default");
128 if (p == NULL) {
129 strcat(srv, ":");
130 if (instance == NULL)
131 instance = "default";
132 if (strlen(srv) + strlen(instance) > MAXPATHLEN)
133 goto out;
134 strncat(srv, instance, strlen(instance));
135 }
136 svcname = srv;
137 phandle = fs_smf_init(fmri, instance);
138 if (phandle == NULL) {
139 return (SMF_SYSTEM_ERR);
140 }
141 handle = phandle->fs_handle;
142 pg = phandle->fs_pg;
143 prop = phandle->fs_property;
144 inst = phandle->fs_instance;
145 val = phandle->fs_value;
146 tran = scf_transaction_create(handle);
147 entry = scf_entry_create(handle);
148
149 if (handle == NULL || pg == NULL || prop == NULL ||
150 val == NULL|| tran == NULL || entry == NULL || inst == NULL) {
151 ret = SMF_SYSTEM_ERR;
152 goto out;
153 }
154
155 if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
156 phandle->fs_service, inst, NULL, NULL, 0) != 0) {
157 ret = scf_error();
158 goto out;
159 }
160 if (fstype == AUTOFS_SMF)
161 pgname = AUTOFS_PROPS_PGNAME;
162 else
163 pgname = NFS_PROPS_PGNAME;
164
165 if (scf_instance_get_pg(inst, pgname,
166 pg) != -1) {
167 uint8_t vint;
168 if (scf_transaction_start(tran, pg) == -1) {
169 ret = scf_error();
170 goto out;
171 }
172 switch (sctype) {
173 case SCF_TYPE_INTEGER:
174 errno = 0;
175 valint = strtoul(valbuf, NULL, 0);
176 if (errno != 0) {
177 ret = SMF_SYSTEM_ERR;
178 goto out;
179 }
180 if (scf_transaction_property_change(tran,
181 entry, prop_name, SCF_TYPE_INTEGER) == 0) {
182 scf_value_set_integer(val, valint);
183 if (scf_entry_add_value(entry, val) < 0) {
184 ret = scf_error();
185 goto out;
186 }
187 }
188 break;
189 case SCF_TYPE_ASTRING:
190 if (scf_transaction_property_change(tran, entry,
191 prop_name, SCF_TYPE_ASTRING) == 0) {
192 if (scf_value_set_astring(val,
193 valbuf) == 0) {
194 if (scf_entry_add_value(entry,
195 val) != 0) {
196 ret = scf_error();
197 goto out;
198 }
199 } else
200 ret = SMF_SYSTEM_ERR;
201 } else
202 ret = SMF_SYSTEM_ERR;
203 break;
204 case SCF_TYPE_BOOLEAN:
205 if (strcmp(valbuf, "1") == 0) {
206 vint = 1;
207 } else if (strcmp(valbuf, "0") == 0) {
208 vint = 0;
209 } else {
210 ret = SMF_SYSTEM_ERR;
211 break;
212 }
213 if (scf_transaction_property_change(tran, entry,
214 prop_name, SCF_TYPE_BOOLEAN) == 0) {
215 scf_value_set_boolean(val, (uint8_t)vint);
216 if (scf_entry_add_value(entry, val) != 0) {
217 ret = scf_error();
218 goto out;
219 }
220 } else {
221 ret = SMF_SYSTEM_ERR;
222 }
223 break;
224 }
225 if (ret != SMF_SYSTEM_ERR)
226 scf_transaction_commit(tran);
227 }
228 out:
229 if (tran != NULL)
230 scf_transaction_destroy(tran);
231 if (entry != NULL)
232 scf_entry_destroy(entry);
233 fs_smf_fini(phandle);
234 return (ret);
235 }
236
237 int
fs_smf_get_prop(smf_fstype_t fstype,char * prop_name,char * cbuf,char * instance,scf_type_t sctype,char * fmri,int * bufsz)238 fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf,
239 char *instance, scf_type_t sctype, char *fmri, int *bufsz)
240 {
241 fs_smfhandle_t *phandle;
242 scf_handle_t *handle;
243 scf_propertygroup_t *pg;
244 scf_property_t *prop;
245 scf_value_t *val;
246 scf_instance_t *inst;
247 int ret = 0, len = 0, length;
248 int64_t valint = 0;
249 char srv[MAXPATHLEN], *p, *svcname;
250 const char *pgname;
251 uint8_t bval;
252
253 /*
254 * The SVC names we are using currently are already
255 * appended by default. Fix this for instances project.
256 */
257 snprintf(srv, MAXPATHLEN, "%s", fmri);
258 p = strstr(fmri, ":default");
259 if (p == NULL) {
260 strcat(srv, ":");
261 if (instance == NULL)
262 instance = "default";
263 if (strlen(srv) + strlen(instance) > MAXPATHLEN)
264 goto out;
265 strncat(srv, instance, strlen(instance));
266 }
267 svcname = srv;
268 phandle = fs_smf_init(fmri, instance);
269 if (phandle == NULL)
270 return (SMF_SYSTEM_ERR);
271 handle = phandle->fs_handle;
272 pg = phandle->fs_pg;
273 inst = phandle->fs_instance;
274 prop = phandle->fs_property;
275 val = phandle->fs_value;
276
277 if (handle == NULL || pg == NULL || prop == NULL || val == NULL ||
278 inst == NULL) {
279 return (SMF_SYSTEM_ERR);
280 }
281
282
283 if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
284 phandle->fs_service, inst, NULL, NULL, 0) != 0) {
285 ret = scf_error();
286 goto out;
287 }
288
289 if (fstype == AUTOFS_SMF)
290 pgname = AUTOFS_PROPS_PGNAME;
291 else
292 pgname = NFS_PROPS_PGNAME;
293
294 if (scf_instance_get_pg(inst, pgname, pg) != -1) {
295 if (scf_pg_get_property(pg, prop_name,
296 prop) != SCF_SUCCESS) {
297 ret = scf_error();
298 goto out;
299 }
300 if (scf_property_get_value(prop, val) != SCF_SUCCESS) {
301 ret = scf_error();
302 goto out;
303 }
304 switch (sctype) {
305 case SCF_TYPE_ASTRING:
306 len = scf_value_get_astring(val, cbuf, *bufsz);
307 if (len < 0 || len > *bufsz) {
308 ret = scf_error();
309 goto out;
310 }
311 ret = 0;
312 *bufsz = len;
313 break;
314 case SCF_TYPE_INTEGER:
315 if (scf_value_get_integer(val, &valint) != 0) {
316 ret = scf_error();
317 goto out;
318 }
319 length = snprintf(cbuf, *bufsz, "%lld", valint);
320 if (length < 0 || length > *bufsz) {
321 ret = SA_BAD_VALUE;
322 goto out;
323 }
324 ret = 0;
325 break;
326 case SCF_TYPE_BOOLEAN:
327 if (scf_value_get_boolean(val, &bval) != 0) {
328 ret = scf_error();
329 goto out;
330 }
331 if (bval == 1) {
332 length = snprintf(cbuf, *bufsz, "%s", "true");
333 } else {
334 length = snprintf(cbuf, *bufsz, "%s", "false");
335 }
336 if (length < 0 || length > *bufsz) {
337 ret = SA_BAD_VALUE;
338 goto out;
339 }
340 break;
341 }
342 } else {
343 ret = scf_error();
344 }
345 if ((ret != 0) && scf_error() != SCF_ERROR_NONE)
346 fprintf(stdout, gettext("%s\n"), scf_strerror(ret));
347 out:
348 fs_smf_fini(phandle);
349 return (ret);
350 }
351
352
353 int
nfs_smf_get_prop(char * prop_name,char * propbuf,char * instance,scf_type_t sctype,char * svc_name,int * bufsz)354 nfs_smf_get_prop(char *prop_name, char *propbuf, char *instance,
355 scf_type_t sctype, char *svc_name, int *bufsz)
356 {
357 return (fs_smf_get_prop(NFS_SMF, prop_name, propbuf,
358 instance, sctype, svc_name, bufsz));
359 }
360
361 int
nfs_smf_set_prop(char * prop_name,char * value,char * instance,scf_type_t type,char * svc_name)362 nfs_smf_set_prop(char *prop_name, char *value, char *instance,
363 scf_type_t type, char *svc_name)
364 {
365 return (fs_smf_set_prop(NFS_SMF, prop_name, value, instance,
366 type, svc_name));
367 }
368
369 int
autofs_smf_set_prop(char * prop_name,char * value,char * instance,scf_type_t type,char * svc_name)370 autofs_smf_set_prop(char *prop_name, char *value, char *instance,
371 scf_type_t type, char *svc_name)
372 {
373 return (fs_smf_set_prop(AUTOFS_SMF, prop_name, value, instance,
374 type, svc_name));
375 }
376
377 int
autofs_smf_get_prop(char * prop_name,char * propbuf,char * instance,scf_type_t sctype,char * svc_name,int * bufsz)378 autofs_smf_get_prop(char *prop_name, char *propbuf, char *instance,
379 scf_type_t sctype, char *svc_name, int *bufsz)
380 {
381 return (fs_smf_get_prop(AUTOFS_SMF, prop_name, propbuf,
382 instance, sctype, svc_name, bufsz));
383 }
384
385 boolean_t
string_to_boolean(const char * str)386 string_to_boolean(const char *str)
387 {
388 if (strcasecmp(str, "true") == 0 || atoi(str) == 1 ||
389 strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0) {
390 return (B_TRUE);
391 } else
392 return (B_FALSE);
393 }
394