xref: /illumos-gate/usr/src/lib/libsmbfs/smb/rc_scf.c (revision adee6784)
1*adee6784SGordon Ross /*
2*adee6784SGordon Ross  * This file and its contents are supplied under the terms of the
3*adee6784SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4*adee6784SGordon Ross  * You may only use this file in accordance with the terms of version
5*adee6784SGordon Ross  * 1.0 of the CDDL.
6*adee6784SGordon Ross  *
7*adee6784SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8*adee6784SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9*adee6784SGordon Ross  * http://www.illumos.org/license/CDDL.
10*adee6784SGordon Ross  */
11*adee6784SGordon Ross 
12*adee6784SGordon Ross /*
13*adee6784SGordon Ross  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
14*adee6784SGordon Ross  */
15*adee6784SGordon Ross 
16*adee6784SGordon Ross /*
17*adee6784SGordon Ross  * Support functions for getting things libsmbfs needs
18*adee6784SGordon Ross  * from the SMF configuration (using libscf).
19*adee6784SGordon Ross  */
20*adee6784SGordon Ross 
21*adee6784SGordon Ross #include <sys/types.h>
22*adee6784SGordon Ross #include <sys/queue.h>
23*adee6784SGordon Ross 
24*adee6784SGordon Ross #include <ctype.h>
25*adee6784SGordon Ross #include <errno.h>
26*adee6784SGordon Ross #include <stdio.h>
27*adee6784SGordon Ross #include <string.h>
28*adee6784SGordon Ross #include <strings.h>
29*adee6784SGordon Ross #include <stdlib.h>
30*adee6784SGordon Ross #include <unistd.h>
31*adee6784SGordon Ross #include <libscf.h>
32*adee6784SGordon Ross 
33*adee6784SGordon Ross #include <cflib.h>
34*adee6784SGordon Ross #include "rcfile_priv.h"
35*adee6784SGordon Ross 
36*adee6784SGordon Ross #define	IDMAP_SERVICE_FMRI		"svc:/system/idmap"
37*adee6784SGordon Ross #define	IDMAP_PG_NAME			"config"
38*adee6784SGordon Ross #define	MACHINE_UUID			"machine_uuid"
39*adee6784SGordon Ross 
40*adee6784SGordon Ross #define	SMBC_DEFAULT_INSTANCE_FMRI	"svc:/network/smb/client:default"
41*adee6784SGordon Ross 
42*adee6784SGordon Ross scf_handle_t *_scf_handle_create_and_bind(scf_version_t ver);
43*adee6784SGordon Ross 
44*adee6784SGordon Ross /*
45*adee6784SGordon Ross  * Get the "machine_uuid" from idmap, as a string (allocated)
46*adee6784SGordon Ross  */
47*adee6784SGordon Ross char *
cf_get_client_uuid(void)48*adee6784SGordon Ross cf_get_client_uuid(void)
49*adee6784SGordon Ross {
50*adee6784SGordon Ross 	char val_buf[64];
51*adee6784SGordon Ross 	char *ret = NULL;
52*adee6784SGordon Ross 
53*adee6784SGordon Ross 	scf_handle_t		*h = NULL;
54*adee6784SGordon Ross 	scf_service_t		*svc = NULL;
55*adee6784SGordon Ross 	scf_propertygroup_t	*pg = NULL;
56*adee6784SGordon Ross 	scf_property_t		*prop = NULL;
57*adee6784SGordon Ross 	scf_value_t		*val = NULL;
58*adee6784SGordon Ross 
59*adee6784SGordon Ross 	if ((h = _scf_handle_create_and_bind(SCF_VERSION)) == NULL)
60*adee6784SGordon Ross 		goto out;
61*adee6784SGordon Ross 
62*adee6784SGordon Ross 	if ((svc = scf_service_create(h)) == NULL ||
63*adee6784SGordon Ross 	    (pg = scf_pg_create(h)) == NULL ||
64*adee6784SGordon Ross 	    (prop = scf_property_create(h)) == NULL ||
65*adee6784SGordon Ross 	    (val = scf_value_create(h)) == NULL)
66*adee6784SGordon Ross 		goto out;
67*adee6784SGordon Ross 
68*adee6784SGordon Ross 	if (scf_handle_decode_fmri(h, IDMAP_SERVICE_FMRI,
69*adee6784SGordon Ross 	    NULL, svc, NULL, NULL, NULL, 0) == -1)
70*adee6784SGordon Ross 		goto out;
71*adee6784SGordon Ross 
72*adee6784SGordon Ross 
73*adee6784SGordon Ross 	if (scf_service_get_pg(svc, IDMAP_PG_NAME, pg) != 0)
74*adee6784SGordon Ross 		goto out;
75*adee6784SGordon Ross 	if (scf_pg_get_property(pg, MACHINE_UUID, prop) != 0)
76*adee6784SGordon Ross 		goto out;
77*adee6784SGordon Ross 	if (scf_property_get_value(prop, val) != 0)
78*adee6784SGordon Ross 		goto out;
79*adee6784SGordon Ross 	if (scf_value_get_as_string(val, val_buf, sizeof (val_buf)) < 0)
80*adee6784SGordon Ross 		goto out;
81*adee6784SGordon Ross 
82*adee6784SGordon Ross 	ret = strdup(val_buf);
83*adee6784SGordon Ross 
84*adee6784SGordon Ross out:
85*adee6784SGordon Ross 	scf_value_destroy(val);
86*adee6784SGordon Ross 	scf_property_destroy(prop);
87*adee6784SGordon Ross 	scf_pg_destroy(pg);
88*adee6784SGordon Ross 	scf_service_destroy(svc);
89*adee6784SGordon Ross 
90*adee6784SGordon Ross 	if (h != NULL)
91*adee6784SGordon Ross 		scf_handle_destroy(h);
92*adee6784SGordon Ross 
93*adee6784SGordon Ross 	return (ret);
94*adee6784SGordon Ross }
95*adee6784SGordon Ross 
96*adee6784SGordon Ross /*
97*adee6784SGordon Ross  * Get the output of "sharectl get smbfs" into a file, without an
98*adee6784SGordon Ross  * actual fork/exec of sharectl.
99*adee6784SGordon Ross  *
100*adee6784SGordon Ross  * Each section of the smbfs settings are represented as an SMF
101*adee6784SGordon Ross  * property group with an "S-" prefix and a UUID, and the section
102*adee6784SGordon Ross  * name itself a property which can have a more flexible name than
103*adee6784SGordon Ross  * a property group name can have.
104*adee6784SGordon Ross  */
105*adee6784SGordon Ross int
rc_scf_get_sharectl(FILE * fp)106*adee6784SGordon Ross rc_scf_get_sharectl(FILE *fp)
107*adee6784SGordon Ross {
108*adee6784SGordon Ross 	char sect_name[256];
109*adee6784SGordon Ross 	char prop_name[256];
110*adee6784SGordon Ross 	char val_buf[1024];
111*adee6784SGordon Ross 
112*adee6784SGordon Ross 	scf_handle_t		*h = NULL;
113*adee6784SGordon Ross 	scf_service_t		*svc = NULL;
114*adee6784SGordon Ross 	scf_instance_t		*inst = NULL;
115*adee6784SGordon Ross 	scf_propertygroup_t	*pg = NULL;
116*adee6784SGordon Ross 	scf_property_t		*prop = NULL;
117*adee6784SGordon Ross 	scf_value_t		*val = NULL;
118*adee6784SGordon Ross 	scf_iter_t		*pgiter = NULL;
119*adee6784SGordon Ross 	scf_iter_t		*propiter = NULL;
120*adee6784SGordon Ross 	scf_iter_t		*valiter = NULL;
121*adee6784SGordon Ross 	int ret = -1;
122*adee6784SGordon Ross 
123*adee6784SGordon Ross 	if ((h = _scf_handle_create_and_bind(SCF_VERSION)) == NULL)
124*adee6784SGordon Ross 		goto out;
125*adee6784SGordon Ross 
126*adee6784SGordon Ross 	if ((svc = scf_service_create(h)) == NULL ||
127*adee6784SGordon Ross 	    (inst = scf_instance_create(h)) == NULL ||
128*adee6784SGordon Ross 	    (pgiter = scf_iter_create(h)) == NULL ||
129*adee6784SGordon Ross 	    (propiter = scf_iter_create(h)) == NULL ||
130*adee6784SGordon Ross 	    (valiter = scf_iter_create(h)) == NULL ||
131*adee6784SGordon Ross 	    (pg = scf_pg_create(h)) == NULL ||
132*adee6784SGordon Ross 	    (prop = scf_property_create(h)) == NULL ||
133*adee6784SGordon Ross 	    (val = scf_value_create(h)) == NULL)
134*adee6784SGordon Ross 		goto out;
135*adee6784SGordon Ross 
136*adee6784SGordon Ross 	if (scf_handle_decode_fmri(h, SMBC_DEFAULT_INSTANCE_FMRI,
137*adee6784SGordon Ross 	    NULL, svc, inst, NULL, NULL, 0) == -1)
138*adee6784SGordon Ross 		goto out;
139*adee6784SGordon Ross 
140*adee6784SGordon Ross 	if (scf_iter_instance_pgs_composed(pgiter, inst, NULL) == -1)
141*adee6784SGordon Ross 		goto out;
142*adee6784SGordon Ross 	while ((ret = scf_iter_next_pg(pgiter, pg)) == 1) {
143*adee6784SGordon Ross 		/*
144*adee6784SGordon Ross 		 * Using prop_name array for pg name temporarily.
145*adee6784SGordon Ross 		 * Skip any property groups names other than "S-*".
146*adee6784SGordon Ross 		 */
147*adee6784SGordon Ross 		if (scf_pg_get_name(pg, prop_name, sizeof (prop_name)) < 0)
148*adee6784SGordon Ross 			continue;
149*adee6784SGordon Ross 		if (strncmp(prop_name, "S-", 2) != 0)
150*adee6784SGordon Ross 			continue;
151*adee6784SGordon Ross 
152*adee6784SGordon Ross 		/*
153*adee6784SGordon Ross 		 * Get the "section" name, which is a property of
154*adee6784SGordon Ross 		 * this property group.
155*adee6784SGordon Ross 		 */
156*adee6784SGordon Ross 		if (scf_pg_get_property(pg, "section", prop) != 0)
157*adee6784SGordon Ross 			continue;
158*adee6784SGordon Ross 		if (scf_property_get_value(prop, val) != 0)
159*adee6784SGordon Ross 			continue;
160*adee6784SGordon Ross 		if (scf_value_get_as_string(val, sect_name,
161*adee6784SGordon Ross 		    sizeof (sect_name)) < 0)
162*adee6784SGordon Ross 			continue;
163*adee6784SGordon Ross 
164*adee6784SGordon Ross 		/*
165*adee6784SGordon Ross 		 * Have an S-* property group with a "section" name.
166*adee6784SGordon Ross 		 * Print the section start.
167*adee6784SGordon Ross 		 */
168*adee6784SGordon Ross 		fprintf(fp, "[%s]\n", sect_name);
169*adee6784SGordon Ross 
170*adee6784SGordon Ross 		/*
171*adee6784SGordon Ross 		 * Now print the remaining properties in this PG,
172*adee6784SGordon Ross 		 * but skip the special "section" (name) prop.
173*adee6784SGordon Ross 		 */
174*adee6784SGordon Ross 		if (scf_iter_pg_properties(propiter, pg) == -1)
175*adee6784SGordon Ross 			goto out;
176*adee6784SGordon Ross 		while ((ret = scf_iter_next_property(propiter, prop)) == 1) {
177*adee6784SGordon Ross 
178*adee6784SGordon Ross 			if (scf_property_get_name(prop, prop_name,
179*adee6784SGordon Ross 			    sizeof (prop_name)) < 0)
180*adee6784SGordon Ross 				continue;
181*adee6784SGordon Ross 
182*adee6784SGordon Ross 			/* Skip the "section" prop. now */
183*adee6784SGordon Ross 			if (strcmp(prop_name, "section") == 0)
184*adee6784SGordon Ross 				continue;
185*adee6784SGordon Ross 
186*adee6784SGordon Ross 			if (scf_property_get_value(prop, val) != 0)
187*adee6784SGordon Ross 				continue;
188*adee6784SGordon Ross 
189*adee6784SGordon Ross 			if (scf_value_get_as_string(val, val_buf,
190*adee6784SGordon Ross 			    sizeof (val_buf)) < 0)
191*adee6784SGordon Ross 				continue;
192*adee6784SGordon Ross 
193*adee6784SGordon Ross 			fprintf(fp, "%s=%s\n", prop_name, val_buf);
194*adee6784SGordon Ross 		}
195*adee6784SGordon Ross 	}
196*adee6784SGordon Ross 	ret = 0;
197*adee6784SGordon Ross 
198*adee6784SGordon Ross out:
199*adee6784SGordon Ross 	fflush(fp);
200*adee6784SGordon Ross 
201*adee6784SGordon Ross 	scf_value_destroy(val);
202*adee6784SGordon Ross 	scf_property_destroy(prop);
203*adee6784SGordon Ross 	scf_pg_destroy(pg);
204*adee6784SGordon Ross 	scf_iter_destroy(valiter);
205*adee6784SGordon Ross 	scf_iter_destroy(propiter);
206*adee6784SGordon Ross 	scf_iter_destroy(pgiter);
207*adee6784SGordon Ross 	scf_instance_destroy(inst);
208*adee6784SGordon Ross 	scf_service_destroy(svc);
209*adee6784SGordon Ross 
210*adee6784SGordon Ross 	if (h != NULL)
211*adee6784SGordon Ross 		scf_handle_destroy(h);
212*adee6784SGordon Ross 
213*adee6784SGordon Ross 	return (ret);
214*adee6784SGordon Ross }
215*adee6784SGordon Ross 
216*adee6784SGordon Ross /*
217*adee6784SGordon Ross  * Simple test wrapper.  Compile with:
218*adee6784SGordon Ross  * cc -o rc_scf_test -I.. -DTEST_MAIN rc_scf.c -lscf
219*adee6784SGordon Ross  */
220*adee6784SGordon Ross #ifdef	TEST_MAIN
221*adee6784SGordon Ross int
main(int argc,char ** arv)222*adee6784SGordon Ross main(int argc, char **arv)
223*adee6784SGordon Ross {
224*adee6784SGordon Ross 	char *s;
225*adee6784SGordon Ross 	int rc;
226*adee6784SGordon Ross 
227*adee6784SGordon Ross 	rc = rc_scf_get_sharectl(stdout);
228*adee6784SGordon Ross 	printf("# rc=%d\n", rc);
229*adee6784SGordon Ross 	return (0);
230*adee6784SGordon Ross }
231*adee6784SGordon Ross #endif	/* TEST_MAIN */
232