Print this page
NEX-14666 Need to provide SMB 2.1 Client
NEX-17187 panic in smbfs_acl_store
NEX-17231 smbfs create xattr files finds wrong file
NEX-17224 smbfs lookup EINVAL should be ENOENT
NEX-17260 SMB1 client fails to list directory after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
and: (cleanup)
4295 libshare sa_get_proto_status sometimes returns unallocated strings
Reviewed by: Marcel Telka <marcel@telka.sk>
Approved by: Garrett D'Amore <garrett@damore.org>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libshare/smbfs/libshare_smbfs.c
+++ new/usr/src/lib/libshare/smbfs/libshare_smbfs.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 + *
26 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
25 27 */
26 28
27 29 /*
28 30 * SMB specific functions
29 31 */
30 32 #include <stdio.h>
31 33 #include <string.h>
32 34 #include <ctype.h>
33 35 #include <stdlib.h>
34 36 #include <unistd.h>
35 37 #include <zone.h>
36 38 #include <errno.h>
37 39 #include <locale.h>
38 40 #include <signal.h>
39 41 #include <fcntl.h>
40 42 #include <sys/types.h>
41 43 #include <sys/stat.h>
42 44 #include <syslog.h>
43 45 #include "libshare.h"
44 46 #include "libshare_impl.h"
45 47 #include <pwd.h>
46 48 #include <limits.h>
47 49 #include <libscf.h>
48 50 #include <strings.h>
49 51 #include "libshare_smbfs.h"
50 52 #include <rpcsvc/daemon_utils.h>
51 53 #include <arpa/inet.h>
52 54 #include <uuid/uuid.h>
53 55 #include <netsmb/smb_lib.h>
54 56
55 57 #define SMBFS_PROTOCOL_NAME "smbfs"
56 58
57 59 /* internal functions */
58 60 static uint64_t smbfs_features();
59 61 static int smbfs_init();
60 62 static void smbfs_fini();
61 63 static int smbfs_set_proto_prop(sa_property_t);
62 64 static sa_protocol_properties_t smbfs_get_proto_set();
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
63 65 static char *smbfs_get_status();
64 66 static int smbfs_delete_section(char *);
65 67 static int smbfs_delete_property_group(char *);
66 68
67 69 static int range_check_validator(int, char *, char *);
68 70 static int string_length_check_validator(int, char *, char *);
69 71 static int yes_no_validator(int, char *, char *);
70 72 static int ip_address_validator(int, char *, char *);
71 73 static int minauth_validator(int, char *, char *);
72 74 static int password_validator(int, char *, char *);
75 +static int protocol_validator(int, char *, char *);
73 76 static int signing_validator(int, char *, char *);
74 77
75 78 int propset_changed = 0;
76 79
77 80 /*
78 81 * ops vector that provides the protocol specific info and operations
79 82 * for share management.
80 83 */
81 84
82 85 struct sa_plugin_ops sa_plugin_ops = {
83 86 SA_PLUGIN_VERSION,
84 87 SMBFS_PROTOCOL_NAME,
85 88 smbfs_init,
86 89 smbfs_fini,
87 90 NULL, /* share */
88 91 NULL, /* unshare */
89 92 NULL, /* valid_prop */
90 93 NULL, /* valid_space */
91 94 NULL, /* security_prop */
92 95 NULL, /* legacy_opts */
93 96 NULL, /* legacy_format */
94 97 smbfs_set_proto_prop,
95 98 smbfs_get_proto_set,
96 99 smbfs_get_status,
97 100 NULL, /* space_alias */
98 101 NULL, /* update_legacy */
99 102 NULL, /* delete_legacy */
100 103 NULL, /* change_notify */
101 104 NULL, /* enable_resource */
102 105 NULL, /* disable_resource */
103 106 smbfs_features,
104 107 NULL, /* get_transient_shares */
105 108 NULL, /* notify_resource */
106 109 NULL, /* rename_resource */
107 110 NULL, /* run_command */
108 111 NULL, /* command_help */
109 112 smbfs_delete_section,
110 113 };
111 114
112 115 /*
113 116 * is_a_number(number)
114 117 *
115 118 * is the string a number in one of the forms we want to use?
116 119 */
117 120
118 121 static int
119 122 is_a_number(char *number)
120 123 {
121 124 int ret = 1;
122 125 int hex = 0;
123 126
124 127 if (strncmp(number, "0x", 2) == 0) {
125 128 number += 2;
126 129 hex = 1;
127 130 } else if (*number == '-') {
128 131 number++; /* skip the minus */
129 132 }
130 133
131 134 while (ret == 1 && *number != '\0') {
132 135 if (hex) {
133 136 ret = isxdigit(*number++);
134 137 } else {
135 138 ret = isdigit(*number++);
136 139 }
137 140 }
138 141 return (ret);
139 142 }
140 143
141 144 /*
142 145 * Protocol management functions
143 146 *
144 147 * properties defined in the default files are defined in
145 148 * proto_option_defs for parsing and validation.
146 149 */
147 150
148 151 struct smbclnt_proto_option_defs smbclnt_proto_options[] = {
149 152 { "section", NULL, PROTO_OPT_SECTION,
150 153 0, 0, MAX_VALUE_BUFLEN,
151 154 string_length_check_validator},
152 155 { "addr", NULL, PROTO_OPT_ADDR,
153 156 0, 0, MAX_VALUE_BUFLEN,
154 157 ip_address_validator},
155 158 { "minauth", NULL, PROTO_OPT_MINAUTH,
156 159 0, 0, MAX_VALUE_BUFLEN,
157 160 minauth_validator},
158 161 { "nbns_broadcast", NULL, PROTO_OPT_NBNS_BROADCAST,
159 162 0, 0, 0,
160 163 yes_no_validator},
161 164 { "nbns_enable", NULL, PROTO_OPT_NBNS_ENABLE,
162 165 0, 0, 0,
163 166 yes_no_validator},
164 167 { "nbns", NULL, PROTO_OPT_NBNSADDR,
165 168 0, 0, MAX_VALUE_BUFLEN,
166 169 ip_address_validator},
167 170 { "password", NULL, PROTO_OPT_PASSWORD,
168 171 0, 0, MAX_VALUE_BUFLEN,
169 172 password_validator},
170 173 { "timeout", NULL, PROTO_OPT_TIMEOUT,
171 174 0, 0, 60,
172 175 range_check_validator},
173 176 { "user", NULL, PROTO_OPT_USER,
174 177 0, 0, MAX_VALUE_BUFLEN,
|
↓ open down ↓ |
92 lines elided |
↑ open up ↑ |
175 178 string_length_check_validator},
176 179 { "domain", NULL, PROTO_OPT_DOMAIN,
177 180 0, 0, MAX_VALUE_BUFLEN,
178 181 string_length_check_validator},
179 182 { "workgroup", NULL, PROTO_OPT_WORKGROUP,
180 183 0, 0, MAX_VALUE_BUFLEN,
181 184 string_length_check_validator},
182 185 { "signing", NULL, PROTO_OPT_SIGNING,
183 186 0, 0, MAX_VALUE_BUFLEN,
184 187 signing_validator},
188 + { "min_protocol", NULL, PROTO_OPT_MIN_PROTOCOL,
189 + 0, 0, MAX_VALUE_BUFLEN,
190 + protocol_validator},
191 + { "max_protocol", NULL, PROTO_OPT_MAX_PROTOCOL,
192 + 0, 0, MAX_VALUE_BUFLEN,
193 + protocol_validator},
185 194 {NULL}
186 195 };
187 196
188 197 /*
189 198 * Check the range of value as int range.
190 199 */
191 200 /*ARGSUSED*/
192 201 static int
193 202 range_check_validator(int index, char *section, char *value)
194 203 {
195 204 int ret = SA_OK;
196 205
197 206 if (value == NULL)
198 207 return (SA_BAD_VALUE);
199 208 if (strlen(value) == 0)
200 209 return (SA_OK);
201 210 if (!is_a_number(value)) {
202 211 ret = SA_BAD_VALUE;
203 212 } else {
204 213 int val;
205 214 val = strtoul(value, NULL, 0);
206 215 if (val < smbclnt_proto_options[index].minval ||
207 216 val > smbclnt_proto_options[index].maxval)
208 217 ret = SA_BAD_VALUE;
209 218 }
210 219 return (ret);
211 220 }
212 221
213 222 /*
214 223 * Check the length of the string
215 224 */
216 225 /*ARGSUSED*/
217 226 static int
218 227 string_length_check_validator(int index, char *section, char *value)
219 228 {
220 229 int ret = SA_OK;
221 230
222 231 if (value == NULL)
223 232 return (SA_BAD_VALUE);
224 233 if (strlen(value) == 0)
225 234 return (SA_OK);
226 235 if (strlen(value) > smbclnt_proto_options[index].maxval)
227 236 ret = SA_BAD_VALUE;
228 237 return (ret);
229 238 }
230 239
231 240 /*
232 241 * Check yes/no
233 242 */
234 243 /*ARGSUSED*/
235 244 static int
236 245 yes_no_validator(int index, char *section, char *value)
237 246 {
238 247 if (value == NULL)
239 248 return (SA_BAD_VALUE);
240 249 if (strlen(value) == 0)
241 250 return (SA_OK);
242 251 if ((strcasecmp(value, "yes") == 0) ||
243 252 (strcasecmp(value, "no") == 0) ||
244 253 (strcasecmp(value, "true") == 0) ||
245 254 (strcasecmp(value, "false") == 0))
246 255 return (SA_OK);
247 256 return (SA_BAD_VALUE);
248 257 }
249 258
250 259 /*
251 260 * Check IP address.
252 261 */
253 262 /*ARGSUSED*/
254 263 static int
255 264 ip_address_validator(int index, char *section, char *value)
256 265 {
257 266 int len;
258 267
259 268 if (value == NULL)
260 269 return (SA_BAD_VALUE);
261 270 len = strlen(value);
262 271 if (len == 0)
|
↓ open down ↓ |
68 lines elided |
↑ open up ↑ |
263 272 return (SA_OK);
264 273 if (len > MAX_VALUE_BUFLEN)
265 274 return (SA_BAD_VALUE);
266 275 return (SA_OK);
267 276 }
268 277
269 278 /*ARGSUSED*/
270 279 static int
271 280 minauth_validator(int index, char *section, char *value)
272 281 {
282 + int ival;
283 +
273 284 if (value == NULL)
274 285 return (SA_BAD_VALUE);
275 - if (strlen(value) == 0)
276 - return (SA_OK);
277 - if (strcmp(value, "kerberos") == 0 ||
278 - strcmp(value, "ntlmv2") == 0 ||
279 - strcmp(value, "ntlm") == 0 ||
280 - strcmp(value, "lm") == 0 ||
281 - strcmp(value, "none") == 0)
282 - return (SA_OK);
283 - else
286 + ival = smb_cf_minauth_from_str(value);
287 + if (ival == -1)
284 288 return (SA_BAD_VALUE);
289 +
290 + return (SA_OK);
285 291 }
286 292
293 +/*ARGSUSED*/
294 +static int
295 +protocol_validator(int index, char *section, char *value)
296 +{
297 + int ival;
298 +
299 + if (value == NULL)
300 + return (SA_BAD_VALUE);
301 + ival = smb_cf_version_from_str(value);
302 + if (ival == -1)
303 + return (SA_BAD_VALUE);
304 +
305 + return (SA_OK);
306 +}
307 +
287 308 /*ARGSUSED*/
288 309 static int
289 310 signing_validator(int index, char *section, char *value)
290 311 {
291 312 if (value == NULL)
292 313 return (SA_BAD_VALUE);
293 314 if (strlen(value) == 0)
294 315 return (SA_OK);
295 316 if (strcmp(value, "disabled") == 0 ||
296 317 strcmp(value, "enabled") == 0 ||
297 318 strcmp(value, "required") == 0)
298 319 return (SA_OK);
299 320 else
300 321 return (SA_BAD_VALUE);
301 322 }
302 323
303 324 /*ARGSUSED*/
304 325 static int
305 326 password_validator(int index, char *section, char *value)
306 327 {
307 328 char buffer[100];
308 329
309 330 /* mangled passwords will start with this pattern */
310 331 if (strlen(value) == 0)
311 332 return (SA_OK);
312 333 if (strncmp(value, "$$1", 3) != 0)
313 334 return (SA_PASSWORD_ENC);
314 335 if (smb_simpledecrypt(buffer, value) != 0)
315 336 return (SA_BAD_VALUE);
316 337 return (SA_OK);
317 338 }
318 339
319 340
320 341 /*
321 342 * the protoset holds the defined options so we don't have to read
322 343 * them multiple times
323 344 */
324 345 sa_protocol_properties_t protoset;
325 346
326 347 static int
327 348 findprotoopt(char *name)
328 349 {
329 350 int i;
330 351 for (i = 0; smbclnt_proto_options[i].name != NULL; i++) {
331 352 if (strcasecmp(smbclnt_proto_options[i].name, name) == 0)
332 353 return (i);
333 354 }
334 355 return (-1);
335 356 }
336 357
337 358 /*
338 359 * Load the persistent settings from SMF. Each section is an SMF
339 360 * property group with an "S-" prefix and a UUID, and the section
340 361 * is itself a property which can have a more flexible name than
341 362 * a property group name can have. The section name need not be
342 363 * the first property, so we have to be a little flexible, but
343 364 * the change of name of the property groups is a reliable way
344 365 * to know that we're seeing a different section.
345 366 */
346 367 int
347 368 smbclnt_config_load()
348 369 {
349 370 scf_simple_app_props_t *props = NULL;
350 371 scf_simple_prop_t *prop = NULL, *lastprop = NULL;
351 372 char *lastpgname = NULL, *pgname = NULL;
352 373 char *name = NULL, *value = NULL;
353 374 sa_property_t sect, node;
354 375
355 376 props = scf_simple_app_props_get(NULL, SMBC_DEFAULT_INSTANCE_FMRI);
356 377 if (props == NULL)
357 378 return (-1);
358 379
359 380 for (;;) {
360 381 lastprop = prop;
361 382 prop = (scf_simple_prop_t *)
362 383 scf_simple_app_props_next(props, lastprop);
363 384 if (prop == NULL)
364 385 break;
365 386
366 387 /* Ignore properties that don't have our prefix */
367 388 pgname = scf_simple_prop_pgname(prop);
368 389 if (strncmp("S-", pgname, 2) != 0)
369 390 continue;
370 391
371 392 /*
372 393 * Note property group name changes, which mark sections
373 394 *
374 395 * The memory allocated by sa_create_section is
375 396 * linked into the list of children under protoset,
376 397 * and will eventually be freed via that list.
377 398 */
378 399 if (lastpgname == NULL || strcmp(lastpgname, pgname) != 0) {
379 400 sect = sa_create_section(NULL, pgname+2);
380 401 (void) xmlSetProp(sect, (xmlChar *)"type",
381 402 (xmlChar *)SMBFS_PROTOCOL_NAME);
382 403 (void) sa_add_protocol_property(protoset, sect);
383 404 if (lastpgname)
384 405 free(lastpgname);
385 406 lastpgname = strdup(pgname);
386 407 }
387 408 name = scf_simple_prop_name(prop);
388 409 value = scf_simple_prop_next_astring(prop);
389 410
390 411 /* If we get a section name, apply it and consume it */
391 412 if (strncmp("section", name, 7) == 0 && value != NULL) {
392 413 (void) xmlSetProp(sect, (xmlChar *)"name",
393 414 (xmlChar *)value);
394 415 continue;
395 416 }
396 417
397 418 /*
398 419 * We have an ordinary property. Add to the section.
399 420 *
400 421 * The memory allocated by sa_create_property is
401 422 * linked into the list of children under "sect",
402 423 * and will eventually be freed via that list.
403 424 */
404 425 node = sa_create_property(name, value);
405 426 (void) sa_add_protocol_property(sect, node);
406 427 }
407 428 scf_simple_app_props_free(props);
408 429
409 430 if (lastpgname)
410 431 free(lastpgname);
411 432 return (0);
412 433 }
413 434
414 435 /*
415 436 * Save the set of properties for a particular section, which is
416 437 * stored as a single property group. Properties will have been
417 438 * changed earlier by one or more calls to smbfs_save_property(),
418 439 * which only set the value in our array and marked them as
419 440 * SMBC_MODIFIED.
420 441 */
421 442 int
422 443 smbfs_save_propset()
423 444 {
424 445 smb_scfhandle_t *handle = NULL;
425 446 char propgroup[256];
426 447 char *section = smbclnt_proto_options[PROTO_OPT_SECTION].value;
427 448 char *uu = NULL;
428 449 uuid_t uuid;
429 450 int i, ret = 0;
430 451 sa_property_t propset;
431 452 int new = 0, nonnull = 0;
432 453
433 454 propset = sa_get_protocol_section(protoset, section);
434 455 (void) strlcpy(propgroup, SMBC_PG_PREFIX, sizeof (propgroup));
435 456 propgroup[SMBC_PG_PREFIX_LEN] = '\0';
436 457 uu = sa_get_property_attr(propset, "extra");
437 458 if (uu != NULL) {
438 459 (void) strlcat(propgroup, uu, sizeof (propgroup));
439 460 free(uu);
440 461 } else {
441 462 new = 1;
442 463 smbclnt_proto_options[PROTO_OPT_SECTION].flags |= SMBC_MODIFIED;
443 464 uuid_generate(uuid);
444 465 uuid_unparse(uuid, &propgroup[SMBC_PG_PREFIX_LEN]);
445 466 }
446 467
447 468 handle = smb_smf_scf_init(SMBC_FMRI_PREFIX);
448 469 if (handle == NULL) {
449 470 return (1);
450 471 }
451 472
452 473 if ((ret = smb_smf_instance_create(handle, SMBC_FMRI_PREFIX,
453 474 SMBC_PG_INSTANCE)) != SMBC_SMF_OK) {
454 475 goto out;
455 476 }
456 477
457 478 if ((ret = smb_smf_create_instance_pgroup(handle, propgroup))
458 479 != SMBC_SMF_OK) {
459 480 goto out;
460 481 }
461 482
462 483 if ((ret = smb_smf_start_transaction(handle)) != SMBC_SMF_OK) {
463 484 goto out;
464 485 }
465 486
466 487 for (i = PROTO_OPT_SECTION+1; i <= SMBC_OPT_MAX; i++) {
467 488 if ((smbclnt_proto_options[i].flags & SMBC_MODIFIED) == 0)
468 489 continue;
469 490 if (strcmp(smbclnt_proto_options[i].value, "") == 0)
470 491 ret = smb_smf_delete_property(handle,
471 492 smbclnt_proto_options[i].name);
472 493 else {
473 494 ret = smb_smf_set_string_property(handle,
474 495 smbclnt_proto_options[i].name,
475 496 smbclnt_proto_options[i].value);
476 497 nonnull = 1;
477 498 }
478 499 free(smbclnt_proto_options[i].value);
479 500 smbclnt_proto_options[i].value = NULL;
480 501 smbclnt_proto_options[i].flags &= ~SMBC_MODIFIED;
481 502 if (ret != SMBC_SMF_OK)
482 503 goto outtrans;
483 504 }
484 505 /*
485 506 * Suppress new, null entries by not saving the section name.
486 507 */
487 508 if (!new || nonnull) {
488 509 ret = smb_smf_set_string_property(handle,
489 510 smbclnt_proto_options[PROTO_OPT_SECTION].name,
490 511 smbclnt_proto_options[PROTO_OPT_SECTION].value);
491 512 free(smbclnt_proto_options[PROTO_OPT_SECTION].value);
492 513 smbclnt_proto_options[PROTO_OPT_SECTION].value = NULL;
493 514 smbclnt_proto_options[PROTO_OPT_SECTION].flags &=
494 515 ~SMBC_MODIFIED;
495 516 }
496 517 propset_changed = 0;
497 518
498 519 outtrans:
499 520 ret = smb_smf_end_transaction(handle);
500 521 out:
501 522 smb_smf_scf_fini(handle);
502 523 return (ret);
503 524 }
504 525
505 526 /*
506 527 * initprotofromdefault()
507 528 *
508 529 * read the default file(s) and add the defined values to the
509 530 * protoset. Note that default values are known from the built in
510 531 * table in case the file doesn't have a definition.
511 532 */
512 533
513 534 static int
514 535 initprotofromdefault()
515 536 {
516 537 protoset = sa_create_protocol_properties(SMBFS_PROTOCOL_NAME);
517 538 if (protoset == NULL)
518 539 return (SA_NO_MEMORY);
519 540 if (smbclnt_config_load() != 0)
520 541 return (SA_OK);
521 542
522 543 return (SA_OK);
523 544 }
524 545
525 546 /*
526 547 *
527 548 * smbfs_features()
528 549 *
529 550 * Report the plugin's features
530 551 */
531 552 static uint64_t
532 553 smbfs_features()
533 554 {
534 555 return (SA_FEATURE_HAS_SECTIONS | SA_FEATURE_ADD_PROPERTIES);
535 556 }
536 557
537 558 /*
538 559 * smbfs_init()
539 560 *
540 561 * Initialize the smb plugin.
541 562 */
542 563
543 564 static int
544 565 smbfs_init()
545 566 {
546 567 int ret = SA_OK;
547 568
548 569 if (sa_plugin_ops.sa_init != smbfs_init) {
549 570 return (SA_SYSTEM_ERR);
550 571 }
551 572
552 573 if (initprotofromdefault() != SA_OK) {
553 574 return (SA_SYSTEM_ERR);
554 575 }
555 576
556 577 return (ret);
557 578 }
558 579
559 580 /*
560 581 * smbfs_fini()
561 582 *
562 583 * uninitialize the smb plugin. Want to avoid memory leaks.
563 584 */
564 585
565 586 static void
566 587 smbfs_fini()
567 588 {
568 589 if (propset_changed)
569 590 (void) smbfs_save_propset();
570 591 xmlFreeNode(protoset);
571 592 protoset = NULL;
572 593 }
573 594
574 595 /*
575 596 * smbfs_get_proto_set()
576 597 *
577 598 * Return an optionset with all the protocol specific properties in
578 599 * it.
579 600 */
580 601
581 602 static sa_protocol_properties_t
582 603 smbfs_get_proto_set()
583 604 {
584 605 return (protoset);
585 606 }
586 607
587 608 /*
588 609 * smbfs_validate_proto_prop(index, name, value)
589 610 *
590 611 * Verify that the property specifed by name can take the new
591 612 * value. This is a sanity check to prevent bad values getting into
592 613 * the default files.
593 614 */
594 615 static int
595 616 smbfs_validate_proto_prop(int index, char *section, char *name, char *value)
596 617 {
597 618 if ((section == NULL) || (name == NULL) || (index < 0))
598 619 return (SA_BAD_VALUE);
599 620
600 621 if (smbclnt_proto_options[index].validator == NULL)
601 622 return (SA_OK);
602 623
603 624 return (smbclnt_proto_options[index].validator(index, section, value));
604 625 }
605 626
606 627 /*
607 628 * Save a property to our array; it will be stored to SMF later by
608 629 * smbfs_save_propset().
609 630 */
610 631 int
611 632 smbfs_save_property(int index, char *section, char *value)
612 633 {
613 634 char *s;
614 635
615 636 if (index == PROTO_OPT_WORKGROUP) {
616 637 index = PROTO_OPT_DOMAIN;
617 638 }
618 639 propset_changed = 1;
619 640 s = strdup(section);
620 641 if (s == NULL)
621 642 return (-1);
622 643 smbclnt_proto_options[PROTO_OPT_SECTION].value = s;
623 644 s = strdup(value);
624 645 if (s == NULL)
625 646 return (-1);
626 647 smbclnt_proto_options[index].value = s;
627 648 smbclnt_proto_options[index].flags |= SMBC_MODIFIED;
628 649 return (0);
629 650 }
630 651
631 652 /*
632 653 * smbfs_set_proto_prop(prop)
633 654 *
634 655 * check that prop is valid.
635 656 */
636 657 /*ARGSUSED*/
637 658 static int
638 659 smbfs_set_proto_prop(sa_property_t prop)
639 660 {
640 661 int ret = SA_OK;
641 662 char *name;
642 663 char *value;
643 664 char *section;
644 665 int i = -1;
645 666
646 667 section = sa_get_property_attr(prop, "section");
647 668 if (section == NULL)
648 669 return (SA_NO_SECTION);
649 670 name = sa_get_property_attr(prop, "type");
650 671 value = sa_get_property_attr(prop, "value");
651 672 if (name != NULL && value != NULL) {
652 673 i = findprotoopt(name);
653 674 if (i >= 0) {
654 675 ret = smbfs_validate_proto_prop(i, section,
655 676 name, value);
656 677 if (ret == SA_OK) {
657 678 if (smbfs_save_property(i, section,
658 679 value) != 0) {
659 680 ret = SA_SYSTEM_ERR;
660 681 errno = EIO;
661 682 }
662 683 }
663 684 } else
664 685 ret = SA_INVALID_NAME;
665 686 }
666 687 if (name != NULL)
667 688 sa_free_attr_string(name);
668 689 if (value != NULL)
669 690 sa_free_attr_string(value);
670 691 if (section != NULL)
671 692 sa_free_attr_string(section);
672 693
673 694 return (ret);
674 695 }
675 696
676 697 /*
677 698 * smbfs_get_status()
678 699 *
679 700 * What is the current status of the smbd? We use the SMF state here.
680 701 * Caller must free the returned value.
681 702 */
682 703
683 704 static char *
684 705 smbfs_get_status()
685 706 {
686 707 return (smf_get_state(SMBC_DEFAULT_INSTANCE_FMRI));
687 708 }
688 709
689 710 /*
690 711 * Delete a section by its name, which we will have read into an
691 712 * XML optionset above. We need to find it and find its UUID to
692 713 * be able to generate the property group name in order to call
693 714 * smbfs_delete_property_group().
694 715 */
695 716 static int
696 717 smbfs_delete_section(char *section)
697 718 {
698 719 char propgroup[256];
699 720 char *uu = NULL;
700 721 sa_property_t propset;
701 722 int ret = SA_SYSTEM_ERR;
702 723
703 724 propset = sa_get_protocol_section(protoset, section);
704 725 (void) strlcpy(propgroup, SMBC_PG_PREFIX, sizeof (propgroup));
705 726 propgroup[SMBC_PG_PREFIX_LEN] = '\0';
706 727 uu = sa_get_property_attr(propset, "extra");
707 728 if (uu == NULL)
708 729 goto out;
709 730 (void) strlcat(propgroup, uu, sizeof (propgroup));
710 731 free(uu);
711 732 if ((ret = smbfs_delete_property_group(propgroup)) != SMBC_SMF_OK)
712 733 goto out;
713 734 ret = SA_OK;
714 735 out:
715 736 return (ret);
716 737 }
717 738
718 739 /*
719 740 * Delete a property group by its name. Called to do a 'delsect'
720 741 * or called when smbclnt_config_load() notices an empty section
721 742 * at the end of the properties.
722 743 */
723 744 static int
724 745 smbfs_delete_property_group(char *propgroup)
725 746 {
726 747 smb_scfhandle_t *handle = NULL;
727 748 int ret = SA_SYSTEM_ERR;
728 749
729 750 handle = smb_smf_scf_init(SMBC_FMRI_PREFIX);
730 751 if (handle == NULL)
731 752 goto out;
732 753
733 754 if ((ret = smb_smf_instance_create(handle, SMBC_FMRI_PREFIX,
734 755 SMBC_PG_INSTANCE)) != SMBC_SMF_OK)
735 756 goto out;
736 757
737 758 if ((ret = smb_smf_delete_instance_pgroup(handle, propgroup))
738 759 != SMBC_SMF_OK)
739 760 goto out;
740 761 ret = SA_OK;
741 762 out:
742 763 smb_smf_scf_fini(handle);
743 764 return (ret);
744 765 }
|
↓ open down ↓ |
448 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX