Mercurial > illumos > illumos-gate
changeset 4345:20eb5d8abe27
6548000 sharemgr dumps core on allocation failure
6549790 NFS sharemgr dumps core on allocation failure
6559696 sharemgr: get_one_filesystem() leaks zfs handles
6559699 sharemgr: sa_scf_init() leaks scf instance and scope
author | dougm |
---|---|
date | Tue, 29 May 2007 15:54:57 -0700 |
parents | 4cd49af6f951 |
children | 9468114ab29a |
files | usr/src/lib/libshare/common/libshare.c usr/src/lib/libshare/common/libshare_zfs.c usr/src/lib/libshare/common/scfutil.c usr/src/lib/libshare/nfs/libshare_nfs.c |
diffstat | 4 files changed, 1277 insertions(+), 1129 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libshare/common/libshare.c Tue May 29 15:28:30 2007 -0700 +++ b/usr/src/lib/libshare/common/libshare.c Tue May 29 15:54:57 2007 -0700 @@ -974,11 +974,23 @@ if (impl_handle != NULL && impl_handle->tree != NULL) { if (groupname != NULL) { group = strdup(groupname); - subgroup = strchr(group, '/'); - if (subgroup != NULL) - *subgroup++ = '\0'; + if (group != NULL) { + subgroup = strchr(group, '/'); + if (subgroup != NULL) + *subgroup++ = '\0'; + } } - node = find_group_by_name(impl_handle->tree, (xmlChar *)group); + /* + * We want to find the, possibly, named group. If + * group is not NULL, then lookup the name. If it is + * NULL, we only do the find if groupname is also + * NULL. This allows lookup of the "first" group in + * the internal list. + */ + if (group != NULL || groupname == NULL) + node = find_group_by_name(impl_handle->tree, + (xmlChar *)group); + /* if a subgroup, find it before returning */ if (subgroup != NULL && node != NULL) node = find_group_by_name(node, (xmlChar *)subgroup);
--- a/usr/src/lib/libshare/common/libshare_zfs.c Tue May 29 15:28:30 2007 -0700 +++ b/usr/src/lib/libshare/common/libshare_zfs.c Tue May 29 15:54:57 2007 -0700 @@ -28,6 +28,7 @@ #include <libzfs.h> #include <string.h> +#include <strings.h> #include <libshare.h> #include "libshare_impl.h" #include <libintl.h> @@ -48,6 +49,7 @@ zfs_handle_t **cb_handles; size_t cb_alloc; size_t cb_used; + uint_t cb_types; } get_all_cbdata_t; /* @@ -80,17 +82,24 @@ sa_zfs_fini(sa_handle_impl_t impl_handle) { if (impl_handle->zfs_libhandle != NULL) { - libzfs_fini(impl_handle->zfs_libhandle); - impl_handle->zfs_libhandle = NULL; if (impl_handle->zfs_list != NULL) { + zfs_handle_t **zhp = impl_handle->zfs_list; + size_t i; + /* - * contents of zfs_list were already freed by - * the call to libzfs_fini(). + * Contents of zfs_list need to be freed so we + * don't lose ZFS handles. */ + for (i = 0; i < impl_handle->zfs_list_count; i++) { + zfs_close(zhp[i]); + } free(impl_handle->zfs_list); impl_handle->zfs_list = NULL; impl_handle->zfs_list_count = 0; } + + libzfs_fini(impl_handle->zfs_libhandle); + impl_handle->zfs_libhandle = NULL; } } @@ -100,17 +109,32 @@ * an interator function called while iterating through the ZFS * root. It accumulates into an array of file system handles that can * be used to derive info about those file systems. + * + * Note that as this function is called, we close all zhp handles that + * are not going to be places into the cp_handles list. We don't want + * to close the ones we are keeping, but all others would be leaked if + * not closed here. */ static int get_one_filesystem(zfs_handle_t *zhp, void *data) { get_all_cbdata_t *cbp = data; + zfs_type_t type = zfs_get_type(zhp); /* - * Skip any zvols + * Interate over any nested datasets. */ - if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { + if (type == ZFS_TYPE_FILESYSTEM && + zfs_iter_filesystems(zhp, get_one_filesystem, data) != 0) { + zfs_close(zhp); + return (1); + } + + /* + * Skip any datasets whose type does not match. + */ + if ((type & cbp->cb_types) == 0) { zfs_close(zhp); return (0); } @@ -123,13 +147,15 @@ else cbp->cb_alloc *= 2; - handles = calloc(1, cbp->cb_alloc * sizeof (void *)); + handles = (zfs_handle_t **)calloc(1, + cbp->cb_alloc * sizeof (void *)); + if (handles == NULL) { + zfs_close(zhp); return (0); } - if (cbp->cb_handles) { - (void) memcpy(handles, cbp->cb_handles, + bcopy(cbp->cb_handles, handles, cbp->cb_used * sizeof (void *)); free(cbp->cb_handles); } @@ -139,7 +165,7 @@ cbp->cb_handles[cbp->cb_used++] = zhp; - return (zfs_iter_filesystems(zhp, get_one_filesystem, data)); + return (0); } /* @@ -156,6 +182,7 @@ zfs_handle_t ***fslist, size_t *count) { get_all_cbdata_t cb = { 0 }; + cb.cb_types = ZFS_TYPE_FILESYSTEM; if (impl_handle->zfs_list != NULL) { *fslist = impl_handle->zfs_list; @@ -512,11 +539,11 @@ * put it on the share. */ options = strdup(shareopts); - if (options != NULL) + if (options != NULL) { err = sa_parse_legacy_options(share, options, "nfs"); - if (options != NULL) free(options); + } } /* unmark the share's changed state */ set_node_attr(share, "changed", NULL); @@ -644,14 +671,14 @@ zfsgroup, dataset); if (group == NULL) { static int err = 0; - /* - * there is a problem, - * but we can't do - * anything about it - * at this point so we - * issue a warning an - * move on. - */ + /* + * there is a problem, + * but we can't do + * anything about it + * at this point so we + * issue a warning an + * move on. + */ zfs_grp_error(err); err = 1; continue;
--- a/usr/src/lib/libshare/common/scfutil.c Tue May 29 15:28:30 2007 -0700 +++ b/usr/src/lib/libshare/common/scfutil.c Tue May 29 15:54:57 2007 -0700 @@ -72,8 +72,10 @@ unbind = 1; scf_scope_destroy(handle->scope); } + if (handle->instance != NULL) + scf_instance_destroy(handle->instance); if (handle->service != NULL) - scf_service_destroy(handle->service); + scf_service_destroy(handle->service); if (handle->pg != NULL) scf_pg_destroy(handle->pg); if (handle->handle != NULL) { @@ -112,7 +114,13 @@ handle->scope = scf_scope_create(handle->handle); handle->service = scf_service_create(handle->handle); handle->pg = scf_pg_create(handle->handle); + + /* make sure we have sufficient SMF running */ handle->instance = scf_instance_create(handle->handle); + if (handle->scope == NULL || handle->service == NULL || + handle->pg == NULL || handle->instance == NULL) + goto err; + if (scf_handle_get_scope(handle->handle, SCF_SCOPE_LOCAL, handle->scope) == 0) { if (scf_scope_get_service(handle->scope,
--- a/usr/src/lib/libshare/nfs/libshare_nfs.c Tue May 29 15:28:30 2007 -0700 +++ b/usr/src/lib/libshare/nfs/libshare_nfs.c Tue May 29 15:54:57 2007 -0700 @@ -179,10 +179,10 @@ { int i; if (name != NULL) { - for (i = 0; optdefs[i].tag != NULL; i++) { - if (strcmp(optdefs[i].tag, name) == 0) - return (i); - } + for (i = 0; optdefs[i].tag != NULL; i++) { + if (strcmp(optdefs[i].tag, name) == 0) + return (i); + } } return (-1); } @@ -200,7 +200,7 @@ optdef = findopt(name); if (optdef != -1) - return (optdefs[optdef].type); + return (optdefs[optdef].type); return (OPT_TYPE_ANY); } @@ -219,7 +219,7 @@ (void) memset(&secinfo, '\0', sizeof (secinfo)); err = nfs_getseconfig_byname(mode, &secinfo); if (err == SC_NOERROR) - return (1); + return (1); return (0); } @@ -236,8 +236,8 @@ int i; for (i = 0; seclist[i] != NULL; i++) { - if (strcmp(tok, seclist[i]) == 0) - return (1); + if (strcmp(tok, seclist[i]) == 0) + return (1); } return (0); } @@ -253,9 +253,9 @@ find_security(struct securities *seclist, sa_security_t sec) { while (seclist != NULL) { - if (seclist->security == sec) - return (1); - seclist = seclist->next; + if (seclist->security == sec) + return (1); + seclist = seclist->next; } return (0); } @@ -277,52 +277,52 @@ int freetok = 0; for (tok = securitymodes; tok != NULL; tok = next) { - next = strchr(tok, ':'); - if (next != NULL) - *next++ = '\0'; - if (strcmp(tok, "default") == 0) { - /* resolve default into the real type */ - tok = nfs_space_alias(tok); - freetok = 1; - } - check = sa_get_security(group, tok, proto); + next = strchr(tok, ':'); + if (next != NULL) + *next++ = '\0'; + if (strcmp(tok, "default") == 0) { + /* resolve default into the real type */ + tok = nfs_space_alias(tok); + freetok = 1; + } + check = sa_get_security(group, tok, proto); - /* add to the security list if it isn't there already */ - if (check == NULL || !find_security(headp, check)) { - curp = (struct securities *)calloc(1, - sizeof (struct securities)); - if (curp != NULL) { - if (check == NULL) { - curp->security = sa_create_security(group, tok, - proto); - } else { - curp->security = check; - } - /* - * note that the first time through the loop, - * headp will be NULL and prev will be - * undefined. Since headp is NULL, we set - * both it and prev to the curp (first - * structure to be allocated). - * - * later passes through the loop will have - * headp not being NULL and prev will be used - * to allocate at the end of the list. - */ - if (headp == NULL) { - headp = curp; - prev = curp; - } else { - prev->next = curp; - prev = curp; - } + /* add to the security list if it isn't there already */ + if (check == NULL || !find_security(headp, check)) { + curp = (struct securities *)calloc(1, + sizeof (struct securities)); + if (curp != NULL) { + if (check == NULL) { + curp->security = sa_create_security( + group, tok, proto); + } else { + curp->security = check; + } + /* + * note that the first time through the loop, + * headp will be NULL and prev will be + * undefined. Since headp is NULL, we set + * both it and prev to the curp (first + * structure to be allocated). + * + * later passes through the loop will have + * headp not being NULL and prev will be used + * to allocate at the end of the list. + */ + if (headp == NULL) { + headp = curp; + prev = curp; + } else { + prev->next = curp; + prev = curp; + } + } } - } - if (freetok) { - freetok = 0; - sa_free_attr_string(tok); - } + if (freetok) { + freetok = 0; + sa_free_attr_string(tok); + } } return (headp); } @@ -332,10 +332,10 @@ { struct securities *next; if (sec != NULL) { - for (next = sec->next; sec != NULL; sec = next) { - next = sec->next; - free(sec); - } + for (next = sec->next; sec != NULL; sec = next) { + next = sec->next; + free(sec); + } } } @@ -355,7 +355,7 @@ len = strlen(str1) + strlen(str2) + 2; newstr = (char *)malloc(len); if (newstr != NULL) - (void) snprintf(newstr, len, "%s%c%s", str1, sep, str2); + (void) snprintf(newstr, len, "%s%c%s", str1, sep, str2); return (newstr); } @@ -374,12 +374,13 @@ int ret = SA_OK; for (; sec != NULL; sec = sec->next) { - if (value == NULL) { - if (strcmp(name, SHOPT_RW) == 0 || strcmp(name, SHOPT_RO) == 0) - value = "*"; - else - value = "true"; - } + if (value == NULL) { + if (strcmp(name, SHOPT_RW) == 0 || + strcmp(name, SHOPT_RO) == 0) + value = "*"; + else + value = "true"; + } /* * Get the existing property, if it exists, so we can @@ -390,56 +391,65 @@ * rw="host2" is seen, the values are merged into a * single rw="host1:host2". */ - prop = sa_get_property(sec->security, name); + prop = sa_get_property(sec->security, name); - if (prop != NULL) { - char *oldvalue; - char *newvalue; + if (prop != NULL) { + char *oldvalue; + char *newvalue; - /* - * The security options of ro/rw/root might appear - * multiple times. If they do, the values need to be - * merged into an access list. If it was previously - * empty, the new value alone is added. - */ - oldvalue = sa_get_property_attr(prop, "value"); - if (oldvalue != NULL) { /* - * The general case is to concatenate the new - * value onto the old value for multiple - * rw(ro/root) properties. A special case - * exists when either the old or new is the - * "all" case. In the special case, if both - * are "all", then it is "all", else if one is - * an access-list, that replaces the "all". + * The security options of ro/rw/root might appear + * multiple times. If they do, the values need to be + * merged into an access list. If it was previously + * empty, the new value alone is added. */ - if (strcmp(oldvalue, "*") == 0) { - /* Replace old value with new value. */ - newvalue = strdup(value); - } else if (strcmp(value, "*") == 0) { - /* Keep old value and ignore the new value. */ - newvalue = NULL; - } else { - /* Make a new list of old plus new access-list. */ - newvalue = nfs_alistcat(oldvalue, value, ':'); - } + oldvalue = sa_get_property_attr(prop, "value"); + if (oldvalue != NULL) { + /* + * The general case is to concatenate the new + * value onto the old value for multiple + * rw(ro/root) properties. A special case + * exists when either the old or new is the + * "all" case. In the special case, if both + * are "all", then it is "all", else if one is + * an access-list, that replaces the "all". + */ + if (strcmp(oldvalue, "*") == 0) { + /* Replace old value with new value. */ + newvalue = strdup(value); + } else if (strcmp(value, "*") == 0) { + /* + * Keep old value and ignore + * the new value. + */ + newvalue = NULL; + } else { + /* + * Make a new list of old plus new + * access-list. + */ + newvalue = nfs_alistcat(oldvalue, + value, ':'); + } - if (newvalue != NULL) { - (void) sa_remove_property(prop); - prop = sa_create_property(name, newvalue); + if (newvalue != NULL) { + (void) sa_remove_property(prop); + prop = sa_create_property(name, + newvalue); + ret = sa_add_property(sec->security, + prop); + free(newvalue); + } + if (oldvalue != NULL) + sa_free_attr_string(oldvalue); + } + } else { + prop = sa_create_property(name, value); ret = sa_add_property(sec->security, prop); - free(newvalue); - } - if (oldvalue != NULL) - sa_free_attr_string(oldvalue); } - } else { - prop = sa_create_property(name, value); - ret = sa_add_property(sec->security, prop); - } - if (ret == SA_OK && !iszfs) { - ret = sa_commit_properties(sec->security, !persist); - } + if (ret == SA_OK && !iszfs) { + ret = sa_commit_properties(sec->security, !persist); + } } return (ret); } @@ -455,9 +465,9 @@ type = sa_get_group_attr(group, "type"); if (type != NULL && strcmp(type, "persist") != 0) - persist = 0; + persist = 0; if (type != NULL) - sa_free_attr_string(type); + sa_free_attr_string(type); return (persist); } @@ -476,28 +486,29 @@ copy = strdup(options); token = base = copy; while (token != NULL && ret == 0) { - token = strtok(base, ","); - base = NULL; - if (token != NULL) { - value = strchr(token, '='); - if (value != NULL) - *value++ = '\0'; - if (strcmp(token, "sec") == 0) { - /* have security flavors so check them */ - char *tok, *next; - for (next = NULL, tok = value; tok != NULL; tok = next) { - next = strchr(tok, ':'); - if (next != NULL) - *next++ = '\0'; - ret = !nfs_validate_security_mode(tok); - if (ret) - break; - } + token = strtok(base, ","); + base = NULL; + if (token != NULL) { + value = strchr(token, '='); + if (value != NULL) + *value++ = '\0'; + if (strcmp(token, "sec") == 0) { + /* HAVE security flavors so check them */ + char *tok, *next; + for (next = NULL, tok = value; tok != NULL; + tok = next) { + next = strchr(tok, ':'); + if (next != NULL) + *next++ = '\0'; + ret = !nfs_validate_security_mode(tok); + if (ret) + break; + } + } } - } } if (copy != NULL) - free(copy); + free(copy); return (ret); } @@ -526,8 +537,8 @@ /* do we have an existing optionset? */ optionset = sa_get_optionset(group, "nfs"); if (optionset == NULL) { - /* didn't find existing optionset so create one */ - optionset = sa_create_optionset(group, "nfs"); + /* didn't find existing optionset so create one */ + optionset = sa_create_optionset(group, "nfs"); } else { /* * have an existing optionset so we need to compare @@ -536,7 +547,7 @@ * and the others will be the same. This needs to be * fixed before the final code is ready. */ - return (ret); + return (ret); } if (strcmp(options, SHOPT_RW) == 0) { @@ -545,7 +556,7 @@ * being the default option. We don't have to do * anything. */ - return (ret); + return (ret); } /* @@ -554,7 +565,7 @@ */ if (invalid_security(options)) { - return (SA_INVALID_SECURITY); + return (SA_INVALID_SECURITY); } /* @@ -562,17 +573,17 @@ * absolutely necessary, we never do it in the legacy parsing. */ if (sa_is_share(group)) { - char *zfs; - parent = sa_get_parent_group(group); - if (parent != NULL) { - zfs = sa_get_group_attr(parent, "zfs"); - if (zfs != NULL) { - sa_free_attr_string(zfs); - iszfs++; + char *zfs; + parent = sa_get_parent_group(group); + if (parent != NULL) { + zfs = sa_get_group_attr(parent, "zfs"); + if (zfs != NULL) { + sa_free_attr_string(zfs); + iszfs++; + } } - } } else { - iszfs = sa_group_is_zfs(group); + iszfs = sa_group_is_zfs(group); } /* @@ -587,96 +598,116 @@ token = dup; lasts = NULL; while (token != NULL && ret == SA_OK) { - ret = SA_OK; - token = strtok_r(base, ",", &lasts); - base = NULL; - if (token != NULL) { - char *value; - /* - * if the option has a value, it will have an '=' to - * separate the name from the value. The following - * code will result in value != NULL and token - * pointing to just the name if there is a value. - */ - value = strchr(token, '='); - if (value != NULL) { - *value++ = '\0'; - } - if (strcmp(token, "sec") == 0 || strcmp(token, "secure") == 0) { - /* - * Once in security parsing, we only - * do security. We do need to move - * between the security node and the - * toplevel. The security tag goes on - * the root while the following ones - * go on the security. - */ - if (security_list != NULL) { - /* have an old list so close it and start the new */ - free_security_list(security_list); - } - if (strcmp(token, "secure") == 0) { - value = "dh"; - } else { - if (value == NULL) { - ret = SA_SYNTAX_ERR; - break; - } - } - security_list = make_security_list(group, value, "nfs"); - } else { + ret = SA_OK; + token = strtok_r(base, ",", &lasts); + base = NULL; + if (token != NULL) { + char *value; /* - * Note that the "old" syntax allowed a - * default security model This must be - * accounted for and internally converted to - * "standard" security structure. + * if the option has a value, it will have an '=' to + * separate the name from the value. The following + * code will result in value != NULL and token + * pointing to just the name if there is a value. */ - if (nfs_is_security_opt(token)) { - if (security_list == NULL) { + value = strchr(token, '='); + if (value != NULL) { + *value++ = '\0'; + } + if (strcmp(token, "sec") == 0 || + strcmp(token, "secure") == 0) { /* - * need to have a security option. This - * will be "closed" when a defined "sec=" - * option is seen. This is technically an - * error but will be allowed with warning. + * Once in security parsing, we only + * do security. We do need to move + * between the security node and the + * toplevel. The security tag goes on + * the root while the following ones + * go on the security. */ - security_list = make_security_list(group, - "default", - "nfs"); - } - if (security_list != NULL) { - ret = add_security_prop(security_list, token, - value, persist, - iszfs); + if (security_list != NULL) { + /* + * have an old list so close it and + * start the new + */ + free_security_list(security_list); + } + if (strcmp(token, "secure") == 0) { + value = "dh"; + } else { + if (value == NULL) { + ret = SA_SYNTAX_ERR; + break; + } + } + security_list = make_security_list(group, + value, "nfs"); } else { - ret = SA_NO_MEMORY; + /* + * Note that the "old" syntax allowed a + * default security model This must be + * accounted for and internally converted to + * "standard" security structure. + */ + if (nfs_is_security_opt(token)) { + if (security_list == NULL) { + /* + * need to have a + * security + * option. This will + * be "closed" when a + * defined "sec=" + * option is + * seen. This is + * technically an + * error but will be + * allowed with + * warning. + */ + security_list = + make_security_list(group, + "default", + "nfs"); + } + if (security_list != NULL) { + ret = add_security_prop( + security_list, token, + value, persist, iszfs); + } else { + ret = SA_NO_MEMORY; + } + } else { + /* regular options */ + if (value == NULL) { + if (strcmp(token, SHOPT_RW) == + 0 || strcmp(token, + SHOPT_RO) == 0) { + value = "*"; + } else { + value = "global"; + if (strcmp(token, + SHOPT_LOG) != 0) { + value = "true"; + } + } + prop = sa_create_property( + token, value); + ret = + sa_add_property(optionset, + prop); + if (ret != SA_OK) + break; + } + if (!iszfs) { + ret = sa_commit_properties( + optionset, !persist); + } + } } - } else { - /* regular options */ - if (value == NULL) { - if (strcmp(token, SHOPT_RW) == 0 || - strcmp(token, SHOPT_RO) == 0) - value = "*"; - else if (strcmp(token, SHOPT_LOG) == 0) - value = "global"; - else - value = "true"; - } - prop = sa_create_property(token, value); - ret = sa_add_property(optionset, prop); - if (ret != SA_OK) { - break; - } - if (!iszfs) { - ret = sa_commit_properties(optionset, !persist); - } - } } - } } if (security_list != NULL) - free_security_list(security_list); + free_security_list(security_list); if (dup != NULL) - free(dup); + free(dup); return (ret); } @@ -693,17 +724,17 @@ int hex = 0; if (strncmp(number, "0x", 2) == 0) { - number += 2; - hex = 1; - } else if (*number == '-') - number++; /* skip the minus */ - + number += 2; + hex = 1; + } else if (*number == '-') { + number++; /* skip the minus */ + } while (ret == 1 && *number != '\0') { - if (hex) { - ret = isxdigit(*number++); - } else { - ret = isdigit(*number++); - } + if (hex) { + ret = isxdigit(*number++); + } else { + ret = isdigit(*number++); + } } return (ret); } @@ -730,9 +761,8 @@ error = nfsl_getconfig_list(&configlist); if (error) { (void) fprintf(stderr, - dgettext(TEXT_DOMAIN, - "Cannot get log configuration: %s\n"), - strerror(error)); + dgettext(TEXT_DOMAIN, "Cannot get log configuration: %s\n"), + strerror(error)); } if (tag == NULL) @@ -740,8 +770,7 @@ if ((configp = nfsl_findconfig(configlist, tag, &error)) == NULL) { nfsl_freeconfig_list(&configlist); (void) fprintf(stderr, - dgettext(TEXT_DOMAIN, - "No tags matching \"%s\"\n"), tag); + dgettext(TEXT_DOMAIN, "No tags matching \"%s\"\n"), tag); /* bad configuration */ error = ENOENT; goto err; @@ -760,7 +789,7 @@ exp->ex_flags |= EX_LOG_ALLOPS; out: if (configlist != NULL) - nfsl_freeconfig_list(&configlist); + nfsl_freeconfig_list(&configlist); err: if (error != 0) { @@ -769,9 +798,8 @@ if (exp->ex_log_buffer != NULL) free(exp->ex_log_buffer); (void) fprintf(stderr, - dgettext(TEXT_DOMAIN, - "Cannot set log configuration: %s\n"), - strerror(error)); + dgettext(TEXT_DOMAIN, "Cannot set log configuration: %s\n"), + strerror(error)); } } @@ -791,111 +819,109 @@ int ret = SA_OK; for (option = sa_get_property(optionset, NULL); - option != NULL; option = sa_get_next_property(option)) { - char *name; - char *value; - uint32_t val; + option != NULL; option = sa_get_next_property(option)) { + char *name; + char *value; + uint32_t val; - /* - * since options may be set/reset multiple times, always do an - * explicit set or clear of the option. This allows defaults - * to be set and then the protocol specifici to override. - */ + /* + * since options may be set/reset multiple times, always do an + * explicit set or clear of the option. This allows defaults + * to be set and then the protocol specifici to override. + */ - name = sa_get_property_attr(option, "type"); - value = sa_get_property_attr(option, "value"); - switch (findopt(name)) { - case OPT_ANON: - if (value != NULL && is_a_number(value)) { - val = strtoul(value, NULL, 0); - } else { - struct passwd *pw; - pw = getpwnam(value != NULL ? value : "nobody"); - if (pw != NULL) { - val = pw->pw_uid; - } else { - val = UID_NOBODY; - } - endpwent(); + name = sa_get_property_attr(option, "type"); + value = sa_get_property_attr(option, "value"); + switch (findopt(name)) { + case OPT_ANON: + if (value != NULL && is_a_number(value)) { + val = strtoul(value, NULL, 0); + } else { + struct passwd *pw; + pw = getpwnam(value != NULL ? value : "nobody"); + if (pw != NULL) { + val = pw->pw_uid; + } else { + val = UID_NOBODY; + } + endpwent(); + } + export->ex_anon = val; + break; + case OPT_NOSUID: + if (value != NULL && (strcasecmp(value, "true") == 0 || + strcmp(value, "1") == 0)) + export->ex_flags |= EX_NOSUID; + else + export->ex_flags &= ~EX_NOSUID; + break; + case OPT_ACLOK: + if (value != NULL && (strcasecmp(value, "true") == 0 || + strcmp(value, "1") == 0)) + export->ex_flags |= EX_ACLOK; + else + export->ex_flags &= ~EX_ACLOK; + break; + case OPT_NOSUB: + if (value != NULL && (strcasecmp(value, "true") == 0 || + strcmp(value, "1") == 0)) + export->ex_flags |= EX_NOSUB; + else + export->ex_flags &= ~EX_NOSUB; + break; + case OPT_PUBLIC: + if (value != NULL && (strcasecmp(value, "true") == 0 || + strcmp(value, "1") == 0)) + export->ex_flags |= EX_PUBLIC; + else + export->ex_flags &= ~EX_PUBLIC; + break; + case OPT_INDEX: + if (value != NULL && (strcmp(value, "..") == 0 || + strchr(value, '/') != NULL)) { + /* this is an error */ + (void) printf(dgettext(TEXT_DOMAIN, + "NFS: index=\"%s\" not valid;" + "must be a filename.\n"), + value); + break; + } + if (value != NULL && *value != '\0' && + strcmp(value, ".") != 0) { + /* valid index file string */ + if (export->ex_index != NULL) { + /* left over from "default" */ + free(export->ex_index); + } + /* remember to free */ + export->ex_index = strdup(value); + if (export->ex_index == NULL) { + (void) printf(dgettext(TEXT_DOMAIN, + "NFS: out of memory setting " + "index property\n")); + break; + } + export->ex_flags |= EX_INDEX; + } + break; + case OPT_LOG: + if (value == NULL) + value = strdup("global"); + if (value != NULL) + configlog(export, + strlen(value) ? value : "global"); + break; + default: + /* have a syntactic error */ + (void) printf(dgettext(TEXT_DOMAIN, + "NFS: unrecognized option %s=%s\n"), + name, value != NULL ? value : ""); + break; } - export->ex_anon = val; - break; - case OPT_NOSUID: - if (value != NULL && - (strcasecmp(value, "true") == 0 || strcmp(value, "1") == 0)) - export->ex_flags |= EX_NOSUID; - else - export->ex_flags &= ~EX_NOSUID; - break; - case OPT_ACLOK: - if (value != NULL && - (strcasecmp(value, "true") == 0 || - strcmp(value, "1") == 0)) - export->ex_flags |= EX_ACLOK; - else - export->ex_flags &= ~EX_ACLOK; - break; - case OPT_NOSUB: - if (value != NULL && - (strcasecmp(value, "true") == 0 || strcmp(value, "1") == 0)) - export->ex_flags |= EX_NOSUB; - else - export->ex_flags &= ~EX_NOSUB; - break; - case OPT_PUBLIC: - if (value != NULL && - (strcasecmp(value, "true") == 0 || strcmp(value, "1") == 0)) - export->ex_flags |= EX_PUBLIC; - else - export->ex_flags &= ~EX_PUBLIC; - break; - case OPT_INDEX: - if (value != NULL && - (strcmp(value, "..") == 0 || strchr(value, '/') != NULL)) { - /* this is an error */ - (void) printf(dgettext(TEXT_DOMAIN, - "NFS: index=\"%s\" not valid;" - "must be a filename.\n"), - value); - break; - } - if (value != NULL && *value != '\0' && - strcmp(value, ".") != 0) { - /* valid index file string */ - if (export->ex_index != NULL) { - /* left over from "default" */ - free(export->ex_index); - } - export->ex_index = strdup(value); /* remember to free */ - if (export->ex_index == NULL) { - (void) printf(dgettext(TEXT_DOMAIN, - "NFS: out of memory setting " - "index property\n")); - break; - } - export->ex_flags |= EX_INDEX; - } - break; - case OPT_LOG: - if (value == NULL) - value = strdup("global"); + if (name != NULL) + sa_free_attr_string(name); if (value != NULL) - configlog(export, strlen(value) ? value : "global"); - break; - case OPT_CKSUM: - /* TBD: not ready yet */ - break; - default: - /* have a syntactic error */ - (void) printf(dgettext(TEXT_DOMAIN, - "NFS: unrecognized option %s=%s\n"), - name, value != NULL ? value : ""); - break; - } - if (name != NULL) - sa_free_attr_string(name); - if (value != NULL) - sa_free_attr_string(value); + sa_free_attr_string(value); } return (ret); } @@ -912,13 +938,12 @@ int i; if (export->ex_index != NULL) - free(export->ex_index); + free(export->ex_index); if (export->ex_secinfo != NULL) { - for (i = 0; i < export->ex_seccnt; i++) - if (export->ex_secinfo[i].s_rootnames != NULL) { - free(export->ex_secinfo[i].s_rootnames); - } - free(export->ex_secinfo); + for (i = 0; i < export->ex_seccnt; i++) + if (export->ex_secinfo[i].s_rootnames != NULL) + free(export->ex_secinfo[i].s_rootnames); + free(export->ex_secinfo); } } @@ -950,17 +975,17 @@ a = (caddr_t *)malloc(c * sizeof (char *)); if (a == NULL) { (void) printf(dgettext(TEXT_DOMAIN, - "get_rootnames: no memory\n")); + "get_rootnames: no memory\n")); } else { - for (i = 0; i < c; i++) { - host = strtok(list, ":"); - if (!nfs_get_root_principal(sec, host, &a[i])) { - free(a); - a = NULL; - break; + for (i = 0; i < c; i++) { + host = strtok(list, ":"); + if (!nfs_get_root_principal(sec, host, &a[i])) { + free(a); + a = NULL; + break; + } + list = NULL; } - list = NULL; - } } return (a); @@ -982,74 +1007,76 @@ type = sa_get_security_attr(secopts, "sectype"); if (type != NULL) { - /* named security type needs secinfo to be filled in */ - err = nfs_getseconfig_byname(type, &sp->s_secinfo); - sa_free_attr_string(type); - if (err != SC_NOERROR) - return (err); + /* named security type needs secinfo to be filled in */ + err = nfs_getseconfig_byname(type, &sp->s_secinfo); + sa_free_attr_string(type); + if (err != SC_NOERROR) + return (err); } else { - /* default case */ - err = nfs_getseconfig_default(&sp->s_secinfo); - if (err != SC_NOERROR) - return (err); + /* default case */ + err = nfs_getseconfig_default(&sp->s_secinfo); + if (err != SC_NOERROR) + return (err); } err = SA_OK; for (prop = sa_get_property(secopts, NULL); - prop != NULL && err == SA_OK; - prop = sa_get_next_property(prop)) { - char *name; - char *value; + prop != NULL && err == SA_OK; + prop = sa_get_next_property(prop)) { + char *name; + char *value; - name = sa_get_property_attr(prop, "type"); - value = sa_get_property_attr(prop, "value"); + name = sa_get_property_attr(prop, "type"); + value = sa_get_property_attr(prop, "value"); - longform = value != NULL && strcmp(value, "*") != 0; + longform = value != NULL && strcmp(value, "*") != 0; - switch (findopt(name)) { - case OPT_RO: - sp->s_flags |= longform ? M_ROL : M_RO; - break; - case OPT_RW: - sp->s_flags |= longform ? M_RWL : M_RW; - break; - case OPT_ROOT: - sp->s_flags |= M_ROOT; - /* - * if we are using AUTH_UNIX, handle like other things - * such as RO/RW - */ - if (sp->s_secinfo.sc_rpcnum == AUTH_UNIX) - continue; - /* not AUTH_UNIX */ - if (value != NULL) { - sp->s_rootnames = get_rootnames(&sp->s_secinfo, value, - &sp->s_rootcnt); - if (sp->s_rootnames == NULL) { - err = SA_BAD_VALUE; - (void) fprintf(stderr, dgettext(TEXT_DOMAIN, - "Bad root list\n")); - } + switch (findopt(name)) { + case OPT_RO: + sp->s_flags |= longform ? M_ROL : M_RO; + break; + case OPT_RW: + sp->s_flags |= longform ? M_RWL : M_RW; + break; + case OPT_ROOT: + sp->s_flags |= M_ROOT; + /* + * if we are using AUTH_UNIX, handle like other things + * such as RO/RW + */ + if (sp->s_secinfo.sc_rpcnum == AUTH_UNIX) + continue; + /* not AUTH_UNIX */ + if (value != NULL) { + sp->s_rootnames = get_rootnames(&sp->s_secinfo, + value, &sp->s_rootcnt); + if (sp->s_rootnames == NULL) { + err = SA_BAD_VALUE; + (void) fprintf(stderr, + dgettext(TEXT_DOMAIN, + "Bad root list\n")); + } + } + break; + case OPT_WINDOW: + if (value != NULL) { + sp->s_window = atoi(value); + /* just in case */ + if (sp->s_window < 0) + sp->s_window = DEF_WIN; + } + break; + default: + break; } - break; - case OPT_WINDOW: - if (value != NULL) { - sp->s_window = atoi(value); - if (sp->s_window < 0) - sp->s_window = DEF_WIN; /* just in case */ - } - break; - default: - break; - } - if (name != NULL) - sa_free_attr_string(name); - if (value != NULL) - sa_free_attr_string(value); + if (name != NULL) + sa_free_attr_string(name); + if (value != NULL) + sa_free_attr_string(value); } /* if rw/ro options not set, use default of RW */ if ((sp->s_flags & NFS_RWMODES) == 0) - sp->s_flags |= M_RW; + sp->s_flags |= M_RW; return (err); } @@ -1065,7 +1092,7 @@ struct secinfo *sp; if (debug == 0) - return; + return; (void) printf("%s:\n", path); (void) printf("\tex_version = %d\n", ep->ex_version); @@ -1089,9 +1116,9 @@ (void) printf("\n"); if (ep->ex_flags & EX_LOG) { (void) printf("\tex_log_buffer = %s\n", - (ep->ex_log_buffer ? ep->ex_log_buffer : "(NULL)")); + (ep->ex_log_buffer ? ep->ex_log_buffer : "(NULL)")); (void) printf("\tex_tag = %s\n", - (ep->ex_tag ? ep->ex_tag : "(NULL)")); + (ep->ex_tag ? ep->ex_tag : "(NULL)")); } (void) printf("\tex_anon = %d\n", ep->ex_anon); (void) printf("\tex_seccnt = %d\n", ep->ex_seccnt); @@ -1112,7 +1139,7 @@ (void) fflush(stdout); for (j = 0; j < sp->s_rootcnt; j++) (void) printf("%s ", sp->s_rootnames[j] ? - sp->s_rootnames[j] : "<null>"); + sp->s_rootnames[j] : "<null>"); (void) printf("\n\n"); } } @@ -1131,10 +1158,10 @@ int count = 0; sa_property_t prop; if (opts != NULL) { - for (prop = sa_get_property(opts, NULL); prop != NULL; - prop = sa_get_next_property(prop)) { - count++; - } + for (prop = sa_get_property(opts, NULL); prop != NULL; + prop = sa_get_next_property(prop)) { + count++; + } } return (count); } @@ -1162,79 +1189,79 @@ name = sa_get_property_attr(prop, "type"); value = sa_get_property_attr(prop, "value"); if (buff != NULL) - curlen = strlen(buff); + curlen = strlen(buff); else - curlen = 0; + curlen = 0; if (name != NULL) { - int len; - len = strlen(name) + sep; + int len; + len = strlen(name) + sep; /* * A future RFE would be to replace this with more * generic code and to possibly handle more types. */ - switch (gettype(name)) { - case OPT_TYPE_BOOLEAN: - if (value != NULL && strcasecmp(value, "false") == 0) { - *name = '\0'; - } - if (value != NULL) - sa_free_attr_string(value); - value = NULL; - break; - case OPT_TYPE_ACCLIST: - if (value != NULL && strcmp(value, "*") == 0) { - sa_free_attr_string(value); - value = NULL; - } else { - if (value != NULL) - len += 1 + strlen(value); - } - break; - case OPT_TYPE_LOGTAG: - if (value != NULL && strlen(value) == 0) { - sa_free_attr_string(value); - value = NULL; - } else { - if (value != NULL) - len += 1 + strlen(value); + switch (gettype(name)) { + case OPT_TYPE_BOOLEAN: + if (value != NULL && strcasecmp(value, "false") == 0) + *name = '\0'; + if (value != NULL) + sa_free_attr_string(value); + value = NULL; + break; + case OPT_TYPE_ACCLIST: + if (value != NULL && strcmp(value, "*") == 0) { + sa_free_attr_string(value); + value = NULL; + } else { + if (value != NULL) + len += 1 + strlen(value); + } + break; + case OPT_TYPE_LOGTAG: + if (value != NULL && strlen(value) == 0) { + sa_free_attr_string(value); + value = NULL; + } else { + if (value != NULL) + len += 1 + strlen(value); + } + break; + default: + if (value != NULL) + len += 1 + strlen(value); + break; } - break; - default: - if (value != NULL) - len += 1 + strlen(value); - break; - } - while (buffsize <= (curlen + len)) { - /* need more room */ - buffsize += incr; - buff = realloc(buff, buffsize); - if (buff == NULL) { - /* realloc failed so free everything */ - if (*rbuff != NULL) - free(*rbuff); + while (buffsize <= (curlen + len)) { + /* need more room */ + buffsize += incr; + buff = realloc(buff, buffsize); + if (buff == NULL) { + /* realloc failed so free everything */ + if (*rbuff != NULL) + free(*rbuff); + } + *rbuff = buff; + *rbuffsize = buffsize; + if (buff == NULL) { + return; + } } - *rbuff = buff; - *rbuffsize = buffsize; - if (buff == NULL) { - return; + if (buff == NULL) + return; + if (value == NULL) { + (void) snprintf(buff + curlen, buffsize - curlen, + "%s%s", sep ? "," : "", + name, value != NULL ? value : ""); + } else { + (void) snprintf(buff + curlen, buffsize - curlen, + "%s%s=%s", sep ? "," : "", + name, value != NULL ? value : ""); } - } - if (buff == NULL) - return; - if (value == NULL) - (void) snprintf(buff + curlen, buffsize - curlen, - "%s%s", sep ? "," : "", - name, value != NULL ? value : ""); - else - (void) snprintf(buff + curlen, buffsize - curlen, - "%s%s=%s", sep ? "," : "", - name, value != NULL ? value : ""); } if (name != NULL) - sa_free_attr_string(name); + sa_free_attr_string(name); if (value != NULL) - sa_free_attr_string(value); + sa_free_attr_string(value); } /* @@ -1249,99 +1276,121 @@ nfs_format_options(sa_group_t group, int hier) { sa_optionset_t options = NULL; - sa_optionset_t secoptions; + sa_optionset_t secoptions = NULL; sa_property_t prop, secprop; - sa_security_t security; + sa_security_t security = NULL; char *buff; size_t buffsize; + char *sectype = NULL; + int sep = 0; + + + buff = malloc(OPT_CHUNK); + if (buff == NULL) { + return (NULL); + } + + buff[0] = '\0'; + buffsize = OPT_CHUNK; + + /* + * We may have a an optionset relative to this item. format + * these if we find them and then add any security definitions. + */ options = sa_get_derived_optionset(group, "nfs", hier); /* - * have a an optionset relative to this item, if any. format - * these then add any security definitions. + * do the default set first but skip any option that is also + * in the protocol specific optionset. */ - buff = malloc(OPT_CHUNK); - if (buff != NULL) { - int sep = 0; - buff[0] = '\0'; - buffsize = OPT_CHUNK; - /* - * do the default set first but skip any option that is also - * in the protocol specific optionset. - */ - if (options != NULL) { - for (prop = sa_get_property(options, NULL); prop != NULL; - prop = sa_get_next_property(prop)) { + if (options != NULL) { + for (prop = sa_get_property(options, NULL); + prop != NULL; prop = sa_get_next_property(prop)) { /* - * use this one since we skipped any of these that - * were also in optdefault + * use this one since we skipped any + * of these that were also in + * optdefault */ - nfs_sprint_option(&buff, &buffsize, OPT_CHUNK, prop, sep); - if (buff == NULL) { - /* - * buff could become NULL if there isn't - * enough memory for nfs_sprint_option to - * realloc() as necessary. We can't really do - * anything about it at this point so we - * return NULL. The caller should handle the - * failure. Note that this - */ - return (buff); - } - sep = 1; + nfs_sprint_option(&buff, &buffsize, OPT_CHUNK, + prop, sep); + if (buff == NULL) { + /* + * buff could become NULL if there + * isn't enough memory for + * nfs_sprint_option to realloc() + * as necessary. We can't really + * do anything about it at this + * point so we return NULL. The + * caller should handle the + * failure. + */ + if (options != NULL) + sa_free_derived_optionset( + options); + return (buff); + } + sep = 1; } - } - secoptions = (sa_optionset_t)sa_get_all_security_types(group, - "nfs", hier); - if (secoptions != NULL) { + } + secoptions = (sa_optionset_t)sa_get_all_security_types(group, + "nfs", hier); + if (secoptions != NULL) { for (secprop = sa_get_property(secoptions, NULL); - secprop != NULL; secprop = sa_get_next_property(secprop)) { - char *sectype; - - sectype = sa_get_property_attr(secprop, "type"); - security = (sa_security_t)sa_get_derived_security(group, - sectype, - "nfs", hier); - if (security != NULL) { - if (sectype != NULL) { - prop = sa_create_property("sec", sectype); - nfs_sprint_option(&buff, &buffsize, OPT_CHUNK, - prop, sep); - (void) sa_remove_property(prop); - sep = 1; + secprop != NULL; + secprop = sa_get_next_property(secprop)) { + sectype = sa_get_property_attr(secprop, "type"); + security = + (sa_security_t)sa_get_derived_security( + group, sectype, "nfs", hier); + if (security != NULL) { + if (sectype != NULL) { + prop = sa_create_property( + "sec", sectype); + nfs_sprint_option(&buff, + &buffsize, OPT_CHUNK, + prop, sep); + (void) sa_remove_property(prop); + sep = 1; + } + for (prop = sa_get_property(security, + NULL); prop != NULL; + prop = sa_get_next_property(prop)) { + nfs_sprint_option(&buff, + &buffsize, OPT_CHUNK, prop, + sep); + if (buff == NULL) + goto err; + sep = 1; + } + sa_free_derived_optionset(security); } - for (prop = sa_get_property(security, NULL); - prop != NULL; - prop = sa_get_next_property(prop)) { - - nfs_sprint_option(&buff, &buffsize, OPT_CHUNK, - prop, sep); - if (buff == NULL) { - /* catastrophic memory failure */ - sa_free_derived_optionset(secoptions); - if (security != NULL) - sa_free_derived_optionset(security); - if (sectype != NULL) - sa_free_attr_string(sectype); - if (options != NULL) - sa_free_derived_optionset(options); - return (buff); - } - sep = 1; - } - sa_free_derived_optionset(security); - } - if (sectype != NULL) - sa_free_attr_string(sectype); + if (sectype != NULL) + sa_free_attr_string(sectype); } sa_free_derived_optionset(secoptions); - } } + if (options != NULL) - sa_free_derived_optionset(options); + sa_free_derived_optionset(options); + return (buff); + +err: + /* + * If we couldn't allocate memory for option printing, we need + * to break out of the nested loops, cleanup and return NULL. + */ + if (secoptions != NULL) + sa_free_derived_optionset(secoptions); + if (security != NULL) + sa_free_derived_optionset(security); + if (sectype != NULL) + sa_free_attr_string(sectype); + if (options != NULL) + sa_free_derived_optionset(options); return (buff); } + /* * Append an entry to the nfslogtab file */ @@ -1367,16 +1416,16 @@ if (lockf(fileno(f), F_LOCK, 0L) < 0) { (void) fprintf(stderr, dgettext(TEXT_DOMAIN, - "share complete, however failed to lock %s " - "for update: %s\n"), NFSLOGTAB, strerror(errno)); + "share complete, however failed to lock %s " + "for update: %s\n"), NFSLOGTAB, strerror(errno)); error = -1; goto out; } if (logtab_deactivate_after_boot(f) == -1) { (void) fprintf(stderr, dgettext(TEXT_DOMAIN, - "share complete, however could not deactivate " - "entries in %s\n"), NFSLOGTAB); + "share complete, however could not deactivate " + "entries in %s\n"), NFSLOGTAB); error = -1; goto out; } @@ -1387,8 +1436,8 @@ */ if (logtab_rement(f, buffer, dir, NULL, -1)) { (void) fprintf(stderr, dgettext(TEXT_DOMAIN, - "share complete, however could not remove matching " - "entries in %s\n"), NFSLOGTAB); + "share complete, however could not remove matching " + "entries in %s\n"), NFSLOGTAB); error = -1; goto out; } @@ -1398,8 +1447,8 @@ */ if (logtab_deactivate(f, NULL, dir, NULL)) { (void) fprintf(stderr, dgettext(TEXT_DOMAIN, - "share complete, however could not deactivate matching " - "entries in %s\n"), NFSLOGTAB); + "share complete, however could not deactivate matching " + "entries in %s\n"), NFSLOGTAB); error = -1; goto out; } @@ -1414,8 +1463,8 @@ */ if (logtab_putent(f, &lep) < 0) { (void) fprintf(stderr, dgettext(TEXT_DOMAIN, - "share complete, however could not add %s to %s\n"), - dir, NFSLOGTAB); + "share complete, however could not add %s to %s\n"), + dir, NFSLOGTAB); error = -1; } @@ -1443,16 +1492,16 @@ if (lockf(fileno(f), F_LOCK, 0L) < 0) { error = errno; (void) fprintf(stderr, dgettext(TEXT_DOMAIN, - "share complete, however could not lock %s for " - "update: %s\n"), NFSLOGTAB, strerror(error)); + "share complete, however could not lock %s for " + "update: %s\n"), NFSLOGTAB, strerror(error)); goto out; } if (logtab_deactivate(f, NULL, path, NULL) == -1) { error = -1; (void) fprintf(stderr, - dgettext(TEXT_DOMAIN, - "share complete, however could not " - "deactivate %s in %s\n"), path, NFSLOGTAB); + dgettext(TEXT_DOMAIN, + "share complete, however could not " + "deactivate %s in %s\n"), path, NFSLOGTAB); goto out; } @@ -1480,32 +1529,34 @@ group = sa_get_parent_group(skipshare); if (group == NULL) - return (SA_NO_SUCH_GROUP); + return (SA_NO_SUCH_GROUP); handle = sa_find_group_handle(group); if (handle == NULL) - return (SA_SYSTEM_ERR); + return (SA_SYSTEM_ERR); for (group = sa_get_group(handle, NULL); group != NULL; group = sa_get_next_group(group)) { - for (share = sa_get_share(group, NULL); share != NULL; - share = sa_get_next_share(share)) { - if (share == skipshare) - continue; - opt = sa_get_optionset(share, "nfs"); - if (opt != NULL) { - prop = sa_get_property(opt, "public"); - if (prop != NULL) { - char *shared; - shared = sa_get_share_attr(share, "shared"); - if (shared != NULL) { - exists = strcmp(shared, "true") == 0; - sa_free_attr_string(shared); - goto out; + for (share = sa_get_share(group, NULL); share != NULL; + share = sa_get_next_share(share)) { + if (share == skipshare) + continue; + opt = sa_get_optionset(share, "nfs"); + if (opt != NULL) { + prop = sa_get_property(opt, "public"); + if (prop != NULL) { + char *shared; + shared = sa_get_share_attr(share, + "shared"); + if (shared != NULL) { + exists = strcmp(shared, + "true") == 0; + sa_free_attr_string(shared); + goto out; + } + } } - } } - } } out: return (exists); @@ -1537,7 +1588,7 @@ /* get the path since it is important in several places */ path = sa_get_share_attr(share, "path"); if (path == NULL) - return (SA_NO_SUCH_PATH); + return (SA_NO_SUCH_PATH); /* * find the optionsets and security sets. There may not be @@ -1548,9 +1599,9 @@ opt = sa_get_derived_optionset(share, "nfs", 1); secoptlist = (sa_optionset_t)sa_get_all_security_types(share, "nfs", 1); if (secoptlist != NULL) - num_secinfo = MAX(1, count_security(secoptlist)); + num_secinfo = MAX(1, count_security(secoptlist)); else - num_secinfo = 1; + num_secinfo = 1; /* * walk through the options and fill in the structure @@ -1572,7 +1623,7 @@ sp = calloc(num_secinfo, sizeof (struct secinfo)); if (opt != NULL) - err = fill_export_from_optionset(&export, opt); + err = fill_export_from_optionset(&export, opt); /* * check to see if "public" is set. If it is, then make sure @@ -1580,22 +1631,22 @@ */ if (export.ex_flags & EX_PUBLIC && public_exists(share)) { - (void) printf(dgettext(TEXT_DOMAIN, - "NFS: Cannot share more than one file " - "system with 'public' property\n")); - err = SA_NOT_ALLOWED; - goto out; + (void) printf(dgettext(TEXT_DOMAIN, + "NFS: Cannot share more than one file " + "system with 'public' property\n")); + err = SA_NOT_ALLOWED; + goto out; } if (sp == NULL) { /* failed to alloc memory */ - (void) printf("NFS: no memory for security\n"); - err = SA_NO_MEMORY; + (void) printf("NFS: no memory for security\n"); + err = SA_NO_MEMORY; } else { - int i; - export.ex_secinfo = sp; - /* get default secinfo */ - export.ex_seccnt = num_secinfo; + int i; + export.ex_secinfo = sp; + /* get default secinfo */ + export.ex_seccnt = num_secinfo; /* * since we must have one security option defined, we * init to the default and then override as we find @@ -1603,39 +1654,49 @@ * where we have no defined options but we need to set * up one. */ - sp[0].s_window = DEF_WIN; - sp[0].s_rootnames = NULL; - /* setup a default in case no properties defined */ - if (nfs_getseconfig_default(&sp[0].s_secinfo)) { - (void) printf(dgettext(TEXT_DOMAIN, - "NFS: nfs_getseconfig_default: failed to " - "get default security mode\n")); - err = SA_CONFIG_ERR; - } - if (secoptlist != NULL) { - for (i = 0, prop = sa_get_property(secoptlist, NULL); - prop != NULL && i < num_secinfo; - prop = sa_get_next_property(prop), i++) { - char *sectype; + sp[0].s_window = DEF_WIN; + sp[0].s_rootnames = NULL; + /* setup a default in case no properties defined */ + if (nfs_getseconfig_default(&sp[0].s_secinfo)) { + (void) printf(dgettext(TEXT_DOMAIN, + "NFS: nfs_getseconfig_default: failed to " + "get default security mode\n")); + err = SA_CONFIG_ERR; + } + if (secoptlist != NULL) { + for (i = 0, prop = sa_get_property(secoptlist, NULL); + prop != NULL && i < num_secinfo; + prop = sa_get_next_property(prop), i++) { + char *sectype; - sectype = sa_get_property_attr(prop, "type"); - /* if sectype is NULL, we can't do anything so skip */ - if (sectype == NULL) - continue; - sec = (sa_security_t)sa_get_derived_security(share, - sectype, - "nfs", 1); - sp[i].s_window = DEF_WIN; - sp[i].s_rootcnt = 0; - sp[i].s_rootnames = NULL; + sectype = sa_get_property_attr(prop, "type"); + /* + * if sectype is NULL, we probably + * have a memory problem and can't get + * the correct values. Rather than + * exporting with incorrect security, + * don't share it. + */ + if (sectype == NULL) { + err = SA_NO_MEMORY; + (void) printf(dgettext(TEXT_DOMAIN, + "NFS: Cannot share %s: " + "no memory\n"), path); + goto out; + } + sec = (sa_security_t)sa_get_derived_security( + share, sectype, "nfs", 1); + sp[i].s_window = DEF_WIN; + sp[i].s_rootcnt = 0; + sp[i].s_rootnames = NULL; - (void) fill_security_from_secopts(&sp[i], sec); - if (sec != NULL) - sa_free_derived_security(sec); - if (sectype != NULL) - sa_free_attr_string(sectype); + (void) fill_security_from_secopts(&sp[i], sec); + if (sec != NULL) + sa_free_derived_security(sec); + if (sectype != NULL) + sa_free_attr_string(sectype); + } } - } /* * when we get here, we can do the exportfs system call and * initiate thinsg. We probably want to enable the nfs.server @@ -1644,37 +1705,36 @@ /* check nfs.server status and start if needed */ /* now add the share to the internal tables */ - printarg(path, &export); + printarg(path, &export); /* * call the exportfs system call which is implemented * via the nfssys() call as the EXPORTFS subfunction. */ - if ((err = exportfs(path, &export)) < 0) { - err = SA_SYSTEM_ERR; - switch (errno) { - case EREMOTE: - (void) printf(dgettext(TEXT_DOMAIN, - "NFS: Cannot share remote file" - "system: %s\n"), - path); - break; - case EPERM: - if (getzoneid() != GLOBAL_ZONEID) { - (void) printf(dgettext(TEXT_DOMAIN, - "NFS: Cannot share file systems " - "in non-global zones: %s\n"), path); - err = SA_NOT_SUPPORTED; - break; - } - err = SA_NO_PERMISSION; - /* FALLTHROUGH */ - default: - break; + if ((err = exportfs(path, &export)) < 0) { + err = SA_SYSTEM_ERR; + switch (errno) { + case EREMOTE: + (void) printf(dgettext(TEXT_DOMAIN, + "NFS: Cannot share remote " + "filesystem: %s\n"), path); + break; + case EPERM: + if (getzoneid() != GLOBAL_ZONEID) { + (void) printf(dgettext(TEXT_DOMAIN, + "NFS: Cannot share filesystems " + "in non-global zones: %s\n"), path); + err = SA_NOT_SUPPORTED; + break; + } + err = SA_NO_PERMISSION; + /* FALLTHROUGH */ + default: + break; + } + } else { + /* update sharetab with an add/modify */ + (void) sa_update_sharetab(share, "nfs"); } - } else { - /* update sharetab with an add/modify */ - (void) sa_update_sharetab(share, "nfs"); - } } if (err == SA_OK) { @@ -1689,35 +1749,34 @@ * error. This is probably where sharetab should be * updated with the NFS specific entry. */ - if (export.ex_flags & EX_LOG) { - /* enable logging */ - if (nfslogtab_add(path, export.ex_log_buffer, - export.ex_tag) != 0) { - (void) fprintf(stderr, - dgettext(TEXT_DOMAIN, - "Could not enable logging for %s\n"), - path); + if (export.ex_flags & EX_LOG) { + /* enable logging */ + if (nfslogtab_add(path, export.ex_log_buffer, + export.ex_tag) != 0) { + (void) fprintf(stderr, dgettext(TEXT_DOMAIN, + "Could not enable logging for %s\n"), + path); + } + _check_services(service_list_logging); + } else { + /* + * don't have logging so remove it from file. It might + * not be thre, but that doesn't matter. + */ + (void) nfslogtab_deactivate(path); + _check_services(service_list_default); } - _check_services(service_list_logging); - } else { - /* - * don't have logging so remove it from file. It might - * not be thre, but that doesn't matter. - */ - (void) nfslogtab_deactivate(path); - _check_services(service_list_default); - } } out: if (path != NULL) - free(path); + free(path); cleanup_export(&export); if (opt != NULL) - sa_free_derived_optionset(opt); + sa_free_derived_optionset(opt); if (secoptlist != NULL) - (void) sa_destroy_optionset(secoptlist); + (void) sa_destroy_optionset(secoptlist); return (err); } @@ -1734,31 +1793,33 @@ int ret = SA_OK; if (share != NULL) { - err = exportfs(share, NULL); - if (err < 0) { - /* TBD: only an error in some cases - need better analysis */ - switch (errno) { - case EPERM: - case EACCES: - ret = SA_NO_PERMISSION; - if (getzoneid() != GLOBAL_ZONEID) { - ret = SA_NOT_SUPPORTED; - } - break; - case EINVAL: - case ENOENT: - ret = SA_NO_SUCH_PATH; - break; - default: - ret = SA_SYSTEM_ERR; - break; + err = exportfs(share, NULL); + if (err < 0) { + /* + * TBD: only an error in some cases - need + * better analysis + */ + switch (errno) { + case EPERM: + case EACCES: + ret = SA_NO_PERMISSION; + if (getzoneid() != GLOBAL_ZONEID) + ret = SA_NOT_SUPPORTED; + break; + case EINVAL: + case ENOENT: + ret = SA_NO_SUCH_PATH; + break; + default: + ret = SA_SYSTEM_ERR; + break; + } } - } - if (ret == SA_OK || ret == SA_NO_SUCH_PATH) { - (void) sa_delete_sharetab(share, "nfs"); - /* just in case it was logged */ - (void) nfslogtab_deactivate(share); - } + if (ret == SA_OK || ret == SA_NO_SUCH_PATH) { + (void) sa_delete_sharetab(share, "nfs"); + /* just in case it was logged */ + (void) nfslogtab_deactivate(share); + } } return (ret); } @@ -1773,7 +1834,7 @@ { int ret = SA_OK; if (strcmp(v1, v2) == 0) - ret = SA_VALUE_CONFLICT; + ret = SA_VALUE_CONFLICT; return (ret); } @@ -1797,126 +1858,143 @@ propname = sa_get_property_attr(property, "type"); if ((optindex = findopt(propname)) < 0) - ret = SA_NO_SUCH_PROP; + ret = SA_NO_SUCH_PROP; /* need to validate value range here as well */ if (ret == SA_OK) { - parent_group = sa_get_parent_group((sa_share_t)parent); - if (optdefs[optindex].share && !sa_is_share(parent_group)) { - ret = SA_PROP_SHARE_ONLY; - } + parent_group = sa_get_parent_group((sa_share_t)parent); + if (optdefs[optindex].share && !sa_is_share(parent_group)) + ret = SA_PROP_SHARE_ONLY; } if (ret == SA_OK) { - value = sa_get_property_attr(property, "value"); - if (value != NULL) { - /* first basic type checking */ - switch (optdefs[optindex].type) { - case OPT_TYPE_NUMBER: - /* check that the value is all digits */ - if (!is_a_number(value)) - ret = SA_BAD_VALUE; - break; - case OPT_TYPE_BOOLEAN: - if (strlen(value) == 0 || - strcasecmp(value, "true") == 0 || - strcmp(value, "1") == 0 || - strcasecmp(value, "false") == 0 || - strcmp(value, "0") == 0) { - ret = SA_OK; - } else { - ret = SA_BAD_VALUE; - } - break; - case OPT_TYPE_USER: - if (!is_a_number(value)) { - struct passwd *pw; - /* in this case it would have to be a user name */ - pw = getpwnam(value); - if (pw == NULL) - ret = SA_BAD_VALUE; - endpwent(); - } else { - uint64_t intval; - intval = strtoull(value, NULL, 0); - if (intval > UID_MAX && intval != ~0) - ret = SA_BAD_VALUE; - } - break; - case OPT_TYPE_FILE: - if (strcmp(value, "..") == 0 || - strchr(value, '/') != NULL) { - ret = SA_BAD_VALUE; - } - break; - case OPT_TYPE_ACCLIST: - /* - * access list handling. Should eventually - * validate that all the values make sense. - * Also, ro and rw may have cross value - * conflicts. - */ - if (strcmp(propname, SHOPT_RO) == 0) - other = SHOPT_RW; - else if (strcmp(propname, SHOPT_RW) == 0) - other = SHOPT_RO; - else - other = NULL; - if (other != NULL && parent != NULL) { - /* compare rw(ro) with ro(rw) */ - sa_property_t oprop; - oprop = sa_get_property(parent, other); - if (oprop != NULL) { - /* only potential confusion if other exists */ - char *ovalue; - ovalue = sa_get_property_attr(oprop, "value"); - if (ovalue != NULL) { - ret = check_rorw(value, ovalue); - sa_free_attr_string(ovalue); - } + value = sa_get_property_attr(property, "value"); + if (value != NULL) { + /* first basic type checking */ + switch (optdefs[optindex].type) { + case OPT_TYPE_NUMBER: + /* check that the value is all digits */ + if (!is_a_number(value)) + ret = SA_BAD_VALUE; + break; + case OPT_TYPE_BOOLEAN: + if (strlen(value) == 0 || + strcasecmp(value, "true") == 0 || + strcmp(value, "1") == 0 || + strcasecmp(value, "false") == 0 || + strcmp(value, "0") == 0) { + ret = SA_OK; + } else { + ret = SA_BAD_VALUE; + } + break; + case OPT_TYPE_USER: + if (!is_a_number(value)) { + struct passwd *pw; + /* + * in this case it would have to be a + * user name + */ + pw = getpwnam(value); + if (pw == NULL) + ret = SA_BAD_VALUE; + endpwent(); + } else { + uint64_t intval; + intval = strtoull(value, NULL, 0); + if (intval > UID_MAX && intval != ~0) + ret = SA_BAD_VALUE; + } + break; + case OPT_TYPE_FILE: + if (strcmp(value, "..") == 0 || + strchr(value, '/') != NULL) { + ret = SA_BAD_VALUE; + } + break; + case OPT_TYPE_ACCLIST: + /* + * access list handling. Should eventually + * validate that all the values make sense. + * Also, ro and rw may have cross value + * conflicts. + */ + if (strcmp(propname, SHOPT_RO) == 0) + other = SHOPT_RW; + else if (strcmp(propname, SHOPT_RW) == 0) + other = SHOPT_RO; + else + other = NULL; + + if (other != NULL && parent != NULL) { + /* compare rw(ro) with ro(rw) */ + sa_property_t oprop; + oprop = sa_get_property(parent, other); + if (oprop != NULL) { + /* + * only potential + * confusion if other + * exists + */ + char *ovalue; + ovalue = sa_get_property_attr( + oprop, "value"); + if (ovalue != NULL) { + ret = check_rorw(value, + ovalue); + sa_free_attr_string( + ovalue); + } + } + } + break; + case OPT_TYPE_LOGTAG: + if (nfsl_getconfig_list(&configlist) == 0) { + int error; + if (value == NULL || + strlen(value) == 0) { + if (value != NULL) + sa_free_attr_string( + value); + value = strdup("global"); + } + if (value != NULL && + nfsl_findconfig(configlist, value, + &error) == NULL) { + ret = SA_BAD_VALUE; + } else { + nfsl_freeconfig_list( + &configlist); + } + } else { + ret = SA_CONFIG_ERR; + } + break; + case OPT_TYPE_STRING: + /* whatever is here should be ok */ + break; + case OPT_TYPE_SECURITY: + /* + * The "sec" property isn't used in the + * non-legacy parts of sharemgr. We need to + * reject it here. For legacy, it is pulled + * out well before we get here. + */ + ret = SA_NO_SUCH_PROP; + break; + default: + break; } - } - break; - case OPT_TYPE_LOGTAG: - if (nfsl_getconfig_list(&configlist) == 0) { - int error; - if (value == NULL || strlen(value) == 0) { - if (value != NULL) - sa_free_attr_string(value); - value = strdup("global"); + sa_free_attr_string(value); + if (ret == SA_OK && optdefs[optindex].check != NULL) { + /* do the property specific check */ + ret = optdefs[optindex].check(property); } - if (nfsl_findconfig(configlist, value, &error) == NULL) - ret = SA_BAD_VALUE; - nfsl_freeconfig_list(&configlist); - } else { - ret = SA_CONFIG_ERR; - } - break; - case OPT_TYPE_STRING: - /* whatever is here should be ok */ - break; - case OPT_TYPE_SECURITY: - /* - * The "sec" property isn't used in the - * non-legacy parts of sharemgr. We need to - * reject it here. For legacy, it is pulled - * out well before we get here. - */ - ret = SA_NO_SUCH_PROP; - break; - default: - break; } - sa_free_attr_string(value); - if (ret == SA_OK && optdefs[optindex].check != NULL) { - /* do the property specific check */ - ret = optdefs[optindex].check(property); - } - } } if (propname != NULL) - sa_free_attr_string(propname); + sa_free_attr_string(propname); return (ret); } @@ -2027,13 +2105,13 @@ { int i; for (i = 0; proto_options[i].tag != NULL; i++) { - if (whichname == 1) { - if (strcasecmp(proto_options[i].name, name) == 0) + if (whichname == 1) { + if (strcasecmp(proto_options[i].name, name) == 0) return (i); - } else { - if (strcasecmp(proto_options[i].tag, name) == 0) - return (i); - } + } else { + if (strcasecmp(proto_options[i].tag, name) == 0) + return (i); + } } return (-1); } @@ -2048,8 +2126,8 @@ fixcaselower(char *str) { while (*str) { - *str = tolower(*str); - str++; + *str = tolower(*str); + str++; } } @@ -2063,8 +2141,8 @@ fixcaseupper(char *str) { while (*str) { - *str = toupper(*str); - str++; + *str = toupper(*str); + str++; } } @@ -2085,6 +2163,32 @@ } /* + * extractprop() + * + * Extract the property and value out of the line and create the + * property in the optionset. + */ +static void +extractprop(char *name, char *value) +{ + sa_property_t prop; + int index; + /* + * Remove any leading + * white space. + */ + name = skipwhitespace(name); + + index = findprotoopt(name, 0); + if (index >= 0) { + fixcaselower(name); + prop = sa_create_property(proto_options[index].name, value); + if (prop != NULL) + (void) sa_add_protocol_property(protoset, prop); + } +} + +/* * initprotofromdefault() * * read the default file(s) and add the defined values to the @@ -2099,50 +2203,39 @@ char buff[BUFSIZ]; char *name; char *value; - sa_property_t prop; - int index; protoset = sa_create_protocol_properties("nfs"); if (protoset != NULL) { - nfs = fopen(NFSADMIN, "r"); - if (nfs != NULL) { - while (fgets(buff, sizeof (buff), nfs) != NULL) { - switch (buff[0]) { - case '\n': - case '#': - /* skip */ - break; - default: - name = buff; - buff[strlen(buff) - 1] = '\0'; - value = strchr(name, '='); - if (value != NULL) { - *value++ = '\0'; - /* Remove any leading white space. */ - name = skipwhitespace(name); - - if ((index = findprotoopt(name, 0)) >= 0) { - fixcaselower(name); - prop = sa_create_property( - proto_options[index].name, - value); - (void) sa_add_protocol_property(protoset, prop); - } + nfs = fopen(NFSADMIN, "r"); + if (nfs != NULL) { + while (fgets(buff, sizeof (buff), nfs) != NULL) { + switch (buff[0]) { + case '\n': + case '#': + /* skip */ + break; + default: + name = buff; + buff[strlen(buff) - 1] = '\0'; + value = strchr(name, '='); + if (value != NULL) { + *value++ = '\0'; + extractprop(name, value); + } + } } - } + if (nfs != NULL) + (void) fclose(nfs); } - if (nfs != NULL) - (void) fclose(nfs); - } } if (protoset == NULL) - return (SA_NO_MEMORY); + return (SA_NO_MEMORY); return (SA_OK); } /* - * add_default() + * add_defaults() * * Add the default values for any property not defined in the parsing * of the default files. Values are set according to their defined @@ -2156,37 +2249,40 @@ char number[MAXDIGITS]; for (i = 0; proto_options[i].tag != NULL; i++) { - sa_property_t prop; - prop = sa_get_protocol_property(protoset, proto_options[i].name); - if (prop == NULL) { - /* add the default value */ - switch (proto_options[i].type) { - case OPT_TYPE_NUMBER: - (void) snprintf(number, sizeof (number), "%d", - proto_options[i].defvalue.intval); - prop = sa_create_property(proto_options[i].name, number); - break; + sa_property_t prop; + prop = sa_get_protocol_property(protoset, + proto_options[i].name); + if (prop == NULL) { + /* add the default value */ + switch (proto_options[i].type) { + case OPT_TYPE_NUMBER: + (void) snprintf(number, sizeof (number), "%d", + proto_options[i].defvalue.intval); + prop = sa_create_property(proto_options[i].name, + number); + break; - case OPT_TYPE_BOOLEAN: - prop = sa_create_property(proto_options[i].name, - proto_options[i].defvalue.intval ? - "true" : "false"); - break; + case OPT_TYPE_BOOLEAN: + prop = sa_create_property(proto_options[i].name, + proto_options[i].defvalue.intval ? + "true" : "false"); + break; - case OPT_TYPE_ONOFF: - prop = sa_create_property(proto_options[i].name, - proto_options[i].defvalue.intval ? - "on" : "off"); - break; + case OPT_TYPE_ONOFF: + prop = sa_create_property(proto_options[i].name, + proto_options[i].defvalue.intval ? + "on" : "off"); + break; - default: - /* treat as strings of zero length */ - prop = sa_create_property(proto_options[i].name, ""); - break; + default: + /* treat as strings of zero length */ + prop = sa_create_property(proto_options[i].name, + ""); + break; + } + if (prop != NULL) + (void) sa_add_protocol_property(protoset, prop); } - if (prop != NULL) - (void) sa_add_protocol_property(protoset, prop); - } } } @@ -2208,11 +2304,12 @@ int ret = SA_OK; if (sa_plugin_ops.sa_init != nfs_init) - (void) printf(dgettext(TEXT_DOMAIN, - "NFS plugin not properly initialized\n")); + (void) printf(dgettext(TEXT_DOMAIN, + "NFS plugin not properly initialized\n")); ret = initprotofromdefault(); - add_defaults(); + if (ret == SA_OK) + add_defaults(); return (ret); } @@ -2265,19 +2362,20 @@ file = fopen(fname, "r"); if (file != NULL) { - while (fgets(buff, sizeof (buff), file) != NULL) { - newdef = (struct deffile *)calloc(1, sizeof (struct deffile)); - if (newdef != NULL) { - /* Make sure we skip any leading whitespace. */ - newdef->line = strdup(skipwhitespace(buff)); - if (defs == NULL) { - prevdef = defs = newdef; - } else { - prevdef->next = newdef; - prevdef = newdef; - } + while (fgets(buff, sizeof (buff), file) != NULL) { + newdef = (struct deffile *)calloc(1, + sizeof (struct deffile)); + if (newdef != NULL) { + /* Make sure we skip any leading whitespace. */ + newdef->line = strdup(skipwhitespace(buff)); + if (defs == NULL) { + prevdef = defs = newdef; + } else { + prevdef->next = newdef; + prevdef = newdef; + } + } } - } } (void) fclose(file); return (defs); @@ -2289,11 +2387,11 @@ struct deffile *curdefs = NULL; while (defs != NULL) { - curdefs = defs; - defs = defs->next; - if (curdefs->line != NULL) - free(curdefs->line); - free(curdefs); + curdefs = defs; + defs = defs->next; + if (curdefs->line != NULL) + free(curdefs->line); + free(curdefs); } } @@ -2312,28 +2410,28 @@ file = fopen(fname, "w+"); if (file != NULL) { - (void) sigprocmask(SIG_BLOCK, NULL, &new); - (void) sigaddset(&new, SIGHUP); - (void) sigaddset(&new, SIGINT); - (void) sigaddset(&new, SIGQUIT); - (void) sigaddset(&new, SIGTSTP); - (void) sigprocmask(SIG_SETMASK, &new, &old); - while (defs != NULL) { - (void) fputs(defs->line, file); - defs = defs->next; - } - (void) fsync(fileno(file)); - (void) sigprocmask(SIG_SETMASK, &old, NULL); - (void) fclose(file); + (void) sigprocmask(SIG_BLOCK, NULL, &new); + (void) sigaddset(&new, SIGHUP); + (void) sigaddset(&new, SIGINT); + (void) sigaddset(&new, SIGQUIT); + (void) sigaddset(&new, SIGTSTP); + (void) sigprocmask(SIG_SETMASK, &new, &old); + while (defs != NULL) { + (void) fputs(defs->line, file); + defs = defs->next; + } + (void) fsync(fileno(file)); + (void) sigprocmask(SIG_SETMASK, &old, NULL); + (void) fclose(file); } else { - switch (errno) { - case EPERM: - case EACCES: - ret = SA_NO_PERMISSION; - break; - default: - ret = SA_SYSTEM_ERR; - } + switch (errno) { + case EPERM: + case EACCES: + ret = SA_NO_PERMISSION; + break; + default: + ret = SA_SYSTEM_ERR; + } } return (ret); } @@ -2363,64 +2461,64 @@ root = defs = read_default_file(NFSADMIN); if (root == NULL) { - if (errno == EPERM || errno == EACCES) - ret = SA_NO_PERMISSION; - else - ret = SA_SYSTEM_ERR; + if (errno == EPERM || errno == EACCES) + ret = SA_NO_PERMISSION; + else + ret = SA_SYSTEM_ERR; } else { - while (defs != NULL) { - if (defs->line != NULL && - strncasecmp(defs->line, string, len) == 0) { - /* replace with the new value */ - free(defs->line); - fixcaseupper(tag); - (void) snprintf(string, sizeof (string), "%s=%s\n", - tag, value); - string[MAX_STRING_LENGTH - 1] = '\0'; - defs->line = strdup(string); - update = 1; - break; - } - defs = defs->next; - } - if (!update) { - defs = root; - /* didn't find, so see if it is a comment */ - (void) snprintf(string, MAX_STRING_LENGTH, "#%s=", tag); - len = strlen(string); while (defs != NULL) { - if (strncasecmp(defs->line, string, len) == 0) { - /* replace with the new value */ - free(defs->line); - fixcaseupper(tag); - (void) snprintf(string, sizeof (string), + if (defs->line != NULL && + strncasecmp(defs->line, string, len) == 0) { + /* replace with the new value */ + free(defs->line); + fixcaseupper(tag); + (void) snprintf(string, sizeof (string), "%s=%s\n", tag, value); - string[MAX_STRING_LENGTH - 1] = '\0'; - defs->line = strdup(string); - update = 1; - break; - } - defs = defs->next; + string[MAX_STRING_LENGTH - 1] = '\0'; + defs->line = strdup(string); + update = 1; + break; + } + defs = defs->next; } - } - if (!update) { - fixcaseupper(tag); - (void) snprintf(string, sizeof (string), "%s=%s\n", - tag, value); - prev = root; - while (prev->next != NULL) - prev = prev->next; - defs = malloc(sizeof (struct deffile)); - prev->next = defs; - if (defs != NULL) { - defs->next = NULL; - defs->line = strdup(string); + if (!update) { + defs = root; + /* didn't find, so see if it is a comment */ + (void) snprintf(string, MAX_STRING_LENGTH, "#%s=", tag); + len = strlen(string); + while (defs != NULL) { + if (strncasecmp(defs->line, string, len) == 0) { + /* replace with the new value */ + free(defs->line); + fixcaseupper(tag); + (void) snprintf(string, sizeof (string), + "%s=%s\n", tag, value); + string[MAX_STRING_LENGTH - 1] = '\0'; + defs->line = strdup(string); + update = 1; + break; + } + defs = defs->next; + } } - } - if (update) { - ret = write_default_file(NFSADMIN, root); - } - free_default_file(root); + if (!update) { + fixcaseupper(tag); + (void) snprintf(string, sizeof (string), "%s=%s\n", + tag, value); + prev = root; + while (prev->next != NULL) + prev = prev->next; + defs = malloc(sizeof (struct deffile)); + prev->next = defs; + if (defs != NULL) { + defs->next = NULL; + defs->line = strdup(string); + } + } + if (update) { + ret = write_default_file(NFSADMIN, root); + } + free_default_file(root); } return (ret); } @@ -2440,9 +2538,9 @@ state = smf_get_state(service); if (state != NULL) { - /* got the state so get the equality for the return value */ - ret = strcmp(state, chkstate) == 0 ? B_TRUE : B_FALSE; - free(state); + /* got the state so get the equality for the return value */ + ret = strcmp(state, chkstate) == 0 ? B_TRUE : B_FALSE; + free(state); } return (ret); } @@ -2464,34 +2562,34 @@ char *service; for (mask = 1; svcs != 0; mask <<= 1) { - switch (svcs & mask) { - case SVC_LOCKD: - service = LOCKD; - break; - case SVC_STATD: - service = STATD; - break; - case SVC_NFSD: - service = NFSD; - break; - case SVC_MOUNTD: - service = MOUNTD; - break; - case SVC_NFS4CBD: - service = NFS4CBD; - break; - case SVC_NFSMAPID: - service = NFSMAPID; - break; - case SVC_RQUOTAD: - service = RQUOTAD; - break; - case SVC_NFSLOGD: - service = NFSLOGD; - break; - default: - continue; - } + switch (svcs & mask) { + case SVC_LOCKD: + service = LOCKD; + break; + case SVC_STATD: + service = STATD; + break; + case SVC_NFSD: + service = NFSD; + break; + case SVC_MOUNTD: + service = MOUNTD; + break; + case SVC_NFS4CBD: + service = NFS4CBD; + break; + case SVC_NFSMAPID: + service = NFSMAPID; + break; + case SVC_RQUOTAD: + service = RQUOTAD; + break; + case SVC_NFSLOGD: + service = NFSLOGD; + break; + default: + continue; + } /* * Only attempt to restart the service if it is @@ -2499,34 +2597,35 @@ * desirable to use smf_refresh_instance if the NFS * services ever implement the refresh method. */ - if (service_in_state(service, SCF_STATE_STRING_ONLINE)) { - ret = smf_restart_instance(service); - /* - * There are only a few SMF errors at this point, but - * it is also possible that a bad value may have put - * the service into maintenance if there wasn't an - * SMF level error. - */ - if (ret != 0) { - (void) fprintf(stderr, - dgettext(TEXT_DOMAIN, - "%s failed to restart: %s\n"), - scf_strerror(scf_error())); - } else { + if (service_in_state(service, SCF_STATE_STRING_ONLINE)) { + ret = smf_restart_instance(service); /* - * Check whether it has gone to "maintenance" - * mode or not. Maintenance implies something - * went wrong. + * There are only a few SMF errors at this point, but + * it is also possible that a bad value may have put + * the service into maintenance if there wasn't an + * SMF level error. */ - if (service_in_state(service, SCF_STATE_STRING_MAINT)) { - (void) fprintf(stderr, - dgettext(TEXT_DOMAIN, - "%s failed to restart\n"), - service); - } + if (ret != 0) { + (void) fprintf(stderr, + dgettext(TEXT_DOMAIN, + "%s failed to restart: %s\n"), + scf_strerror(scf_error())); + } else { + /* + * Check whether it has gone to "maintenance" + * mode or not. Maintenance implies something + * went wrong. + */ + if (service_in_state(service, + SCF_STATE_STRING_MAINT)) { + (void) fprintf(stderr, + dgettext(TEXT_DOMAIN, + "%s failed to restart\n"), + service); + } + } } - } - svcs &= ~mask; + svcs &= ~mask; } } @@ -2549,25 +2648,27 @@ int ret = B_TRUE; if (proto_options[index].other != NULL) { - /* have a property to compare against */ - opts = nfs_get_proto_set(); - prop = sa_get_property(opts, proto_options[index].other); + /* have a property to compare against */ + opts = nfs_get_proto_set(); + prop = sa_get_property(opts, proto_options[index].other); /* * If we don't find the property, assume default * values which will work since the max will be at the * max and the min at the min. */ - if (prop != NULL) { - pval = sa_get_property_attr(prop, "value"); - if (pval != NULL) { - val = strtoul(pval, NULL, 0); - if (proto_options[index].compare == OPT_CMP_LE) { - ret = value <= val ? B_TRUE : B_FALSE; - } else if (proto_options[index].compare == OPT_CMP_GE) { - ret = value >= val ? B_TRUE : B_FALSE; - } + if (prop != NULL) { + pval = sa_get_property_attr(prop, "value"); + if (pval != NULL) { + val = strtoul(pval, NULL, 0); + if (proto_options[index].compare == + OPT_CMP_LE) { + ret = value <= val ? B_TRUE : B_FALSE; + } else if (proto_options[index].compare == + OPT_CMP_GE) { + ret = value >= val ? B_TRUE : B_FALSE; + } + } } - } } return (ret); } @@ -2598,25 +2699,25 @@ switch (proto_options[index].type) { case OPT_TYPE_NUMBER: - if (!is_a_number(value)) - ret = SA_BAD_VALUE; - else { - int val; - val = strtoul(value, NULL, 0); - if (val < proto_options[index].minval || - val > proto_options[index].maxval) - ret = SA_BAD_VALUE; - /* - * For server_versmin/server_versmax and - * client_versmin/client_versmax, the value of the - * min(max) should be checked to be correct relative - * to the current max(min). - */ - if (!nfs_minmax_check(index, val)) { - ret = SA_BAD_VALUE; + if (!is_a_number(value)) + ret = SA_BAD_VALUE; + else { + int val; + val = strtoul(value, NULL, 0); + if (val < proto_options[index].minval || + val > proto_options[index].maxval) + ret = SA_BAD_VALUE; + /* + * For server_versmin/server_versmax and + * client_versmin/client_versmax, the value of the + * min(max) should be checked to be correct relative + * to the current max(min). + */ + if (!nfs_minmax_check(index, val)) { + ret = SA_BAD_VALUE; + } } - } - break; + break; case OPT_TYPE_DOMAIN: /* @@ -2625,42 +2726,42 @@ * side of it. A zero length string is also allowed * and is the way to turn off the override. */ - if (strlen(value) == 0) + if (strlen(value) == 0) + break; + cp = strchr(value, '.'); + if (cp == NULL || cp == value || strchr(value, '@') != NULL) + ret = SA_BAD_VALUE; break; - cp = strchr(value, '.'); - if (cp == NULL || cp == value || strchr(value, '@') != NULL) - ret = SA_BAD_VALUE; - break; case OPT_TYPE_BOOLEAN: - if (strlen(value) == 0 || - strcasecmp(value, "true") == 0 || - strcmp(value, "1") == 0 || - strcasecmp(value, "false") == 0 || - strcmp(value, "0") == 0) { - ret = SA_OK; - } else { - ret = SA_BAD_VALUE; - } - break; + if (strlen(value) == 0 || + strcasecmp(value, "true") == 0 || + strcmp(value, "1") == 0 || + strcasecmp(value, "false") == 0 || + strcmp(value, "0") == 0) { + ret = SA_OK; + } else { + ret = SA_BAD_VALUE; + } + break; case OPT_TYPE_ONOFF: - if (strcasecmp(value, "on") != 0 && - strcasecmp(value, "off") != 0) { - ret = SA_BAD_VALUE; - } - break; + if (strcasecmp(value, "on") != 0 && + strcasecmp(value, "off") != 0) { + ret = SA_BAD_VALUE; + } + break; case OPT_TYPE_PROTOCOL: - if (strcasecmp(value, "all") != 0 && - strcasecmp(value, "tcp") != 0 && - strcasecmp(value, "udp") != 0) - ret = SA_BAD_VALUE; - break; + if (strcasecmp(value, "all") != 0 && + strcasecmp(value, "tcp") != 0 && + strcasecmp(value, "udp") != 0) + ret = SA_BAD_VALUE; + break; default: - /* treat as a string */ - break; + /* treat as a string */ + break; } return (ret); } @@ -2681,21 +2782,21 @@ name = sa_get_property_attr(prop, "type"); value = sa_get_property_attr(prop, "value"); if (name != NULL && value != NULL) { - int index = findprotoopt(name, 1); - if (index >= 0) { - /* should test for valid value */ - ret = nfs_validate_proto_prop(index, name, value); - if (ret == SA_OK) - ret = set_default_file_value(proto_options[index].tag, - value); - if (ret == SA_OK) - restart_service(proto_options[index].svcs); - } + int index = findprotoopt(name, 1); + if (index >= 0) { + /* should test for valid value */ + ret = nfs_validate_proto_prop(index, name, value); + if (ret == SA_OK) + ret = set_default_file_value( + proto_options[index].tag, value); + if (ret == SA_OK) + restart_service(proto_options[index].svcs); + } } if (name != NULL) - sa_free_attr_string(name); + sa_free_attr_string(name); if (value != NULL) - sa_free_attr_string(value); + sa_free_attr_string(value); return (ret); } @@ -2735,8 +2836,8 @@ */ if (strcmp(space, "default") == 0 && nfs_getseconfig_default(&secconf) == 0) { - if (nfs_getseconfig_bynumber(secconf.sc_nfsnum, &secconf) == 0) - name = secconf.sc_name; + if (nfs_getseconfig_bynumber(secconf.sc_nfsnum, &secconf) == 0) + name = secconf.sc_name; } return (strdup(name)); }