diff options
Diffstat (limited to 'usr/src/lib')
-rw-r--r-- | usr/src/lib/libshare/common/libshare.c | 69 | ||||
-rw-r--r-- | usr/src/lib/libshare/common/libshare.h | 14 | ||||
-rw-r--r-- | usr/src/lib/libshare/common/libsharecore.c | 19 | ||||
-rw-r--r-- | usr/src/lib/libshare/common/scfutil.c | 41 |
4 files changed, 109 insertions, 34 deletions
diff --git a/usr/src/lib/libshare/common/libshare.c b/usr/src/lib/libshare/common/libshare.c index c5e94f8113..54d8be6602 100644 --- a/usr/src/lib/libshare/common/libshare.c +++ b/usr/src/lib/libshare/common/libshare.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -282,12 +282,19 @@ is_shared(sa_share_t share) } /* - * checksubdir determines if the specified path is a subdirectory of - * another share. It calls issubdir() from the old share - * implementation to do the complicated work. + * checksubdir(newpath, strictness) + * + * checksubdir determines if the specified path (newpath) is a + * subdirectory of another share. It calls issubdir() from the old + * share implementation to do the complicated work. The strictness + * parameter determines how strict a check to make against the + * path. The strictness values mean: + * SA_CHECK_NORMAL == only check newpath against shares that are active + * SA_CHECK_STRICT == check newpath against both active shares and those + * stored in the repository */ static int -checksubdir(char *newpath) +checksubdir(char *newpath, int strictness) { sa_group_t group; sa_share_t share; @@ -307,10 +314,17 @@ checksubdir(char *newpath) * could be considered incorrect. We may tighten this * up in the future. */ - if (!is_shared(share)) + if (strictness == SA_CHECK_NORMAL && !is_shared(share)) continue; path = sa_get_share_attr(share, "path"); + /* + * If path is NULL, then a share is in the process of + * construction or someone has modified the property + * group inappropriately. It should be ignored. + */ + if (path == NULL) + continue; if (newpath != NULL && (strcmp(path, newpath) == 0 || issubdir(newpath, path) || issubdir(path, newpath))) { @@ -329,13 +343,13 @@ checksubdir(char *newpath) } /* - * validpath(path) + * validpath(path, strictness) * determine if the provided path is valid for a share. It shouldn't * be a sub-dir of an already shared path or the parent directory of a * share path. */ static int -validpath(char *path) +validpath(char *path, int strictness) { int error = SA_OK; struct stat st; @@ -370,7 +384,7 @@ validpath(char *path) sa_free_fstype(fstype); } if (error == SA_OK) { - error = checksubdir(path); + error = checksubdir(path, strictness); } } return (error); @@ -514,7 +528,7 @@ sa_security_name(sa_security_t security, char *oname, size_t len, char *id) } /* - * sa_init() + * sa_init(init_service) * Initialize the API * find all the shared objects * init the tables with all objects @@ -875,21 +889,24 @@ sa_find_share(char *sharepath) } /* - * sa_check_path(group, path) + * sa_check_path(group, path, strictness) * * check that path is a valid path relative to the group. Currently, * we are ignoring the group and checking only the NFS rules. Later, * we may want to use the group to then check against the protocols - * enabled on the group. + * enabled on the group. The strictness values mean: + * SA_CHECK_NORMAL == only check newpath against shares that are active + * SA_CHECK_STRICT == check newpath against both active shares and those + * stored in the repository */ int -sa_check_path(sa_group_t group, char *path) +sa_check_path(sa_group_t group, char *path, int strictness) { #ifdef lint group = group; #endif - return (validpath(path)); + return (validpath(path, strictness)); } /* @@ -964,9 +981,24 @@ sa_add_share(sa_group_t group, char *sharepath, int persist, int *error) { xmlNodePtr node = NULL; sa_share_t dup; + int strictness = SA_CHECK_NORMAL; + + /* + * If the share is to be permanent, use strict checking so a + * bad config doesn't get created. Transient shares only need + * to check against the currently active + * shares. SA_SHARE_PARSER is a modifier used internally to + * indicate that we are being called by the dfstab parser and + * that we need strict checking in all cases. Normally persist + * is in integer value but SA_SHARE_PARSER may be or'd into + * it as an override. + */ + if (persist & SA_SHARE_PARSER || persist == SA_SHARE_PERMANENT) + strictness = SA_CHECK_STRICT; if ((dup = sa_find_share(sharepath)) == NULL && - (*error = sa_check_path(group, sharepath)) == SA_OK) { + (*error = sa_check_path(group, sharepath, strictness)) == + SA_OK) { node = _sa_add_share(group, sharepath, persist, error); } if (dup != NULL) @@ -1326,19 +1358,12 @@ sa_remove_group(sa_group_t group) int sa_update_config() { - struct stat st; - /* * do legacy files first so we can tell when they change. * This will go away when we start updating individual records * rather than the whole file. */ update_legacy_config(); - /* update legacy timestamp */ - if (stat(SA_LEGACY_DFSTAB, &st) >= 0) { - set_legacy_timestamp(sa_config_tree, SA_LEGACY_DFSTAB, - TSTAMP(st.st_ctim)); - } return (SA_OK); } diff --git a/usr/src/lib/libshare/common/libshare.h b/usr/src/lib/libshare/common/libshare.h index 1c172f6f2a..822442dfae 100644 --- a/usr/src/lib/libshare/common/libshare.h +++ b/usr/src/lib/libshare/common/libshare.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -90,9 +90,15 @@ typedef void *sa_handle_t; /* opaque handle to access core functions */ */ #define SA_MAX_NAME_LEN 100 /* must fit service instance name */ -#define SA_SHARE_PERMANENT 2 /* share goes to repository */ -#define SA_SHARE_LEGACY 1 /* share is in dfstab only */ + +/* Used in calls to sa_add_share() */ #define SA_SHARE_TRANSIENT 0 /* shared but not across reboot */ +#define SA_SHARE_LEGACY 1 /* share is in dfstab only */ +#define SA_SHARE_PERMANENT 2 /* share goes to repository */ + +/* sa_check_path() related */ +#define SA_CHECK_NORMAL 0 /* only check against active shares */ +#define SA_CHECK_STRICT 1 /* check against all shares */ /* RBAC related */ #define SA_RBAC_MANAGE "solaris.smf.manage.shares" @@ -133,7 +139,7 @@ extern int sa_valid_group_name(char *); /* share control */ extern sa_share_t sa_add_share(sa_group_t, char *, int, int *); -extern int sa_check_path(sa_group_t, char *); +extern int sa_check_path(sa_group_t, char *, int); extern int sa_move_share(sa_group_t, sa_share_t); extern int sa_remove_share(sa_share_t); extern sa_share_t sa_get_share(sa_group_t, char *); diff --git a/usr/src/lib/libshare/common/libsharecore.c b/usr/src/lib/libshare/common/libsharecore.c index 766afd4197..4ea50f5303 100644 --- a/usr/src/lib/libshare/common/libsharecore.c +++ b/usr/src/lib/libshare/common/libsharecore.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -514,7 +514,11 @@ sa_comment_line(char *line, char *err) (void) lockf(fileno(dfstab), F_LOCK, 0); list = getdfstab(dfstab); rewind(dfstab); - (void) remdfsline(list, line); + /* + * don't ignore the return since the list could have + * gone to NULL if the file only had one line in it. + */ + list = remdfsline(list, line); outdfstab(dfstab, list); (void) fprintf(dfstab, "# Error: %s: %s", err, line); (void) fsync(fileno(dfstab)); @@ -1079,19 +1083,21 @@ legacy_removes(sa_group_t group, char *file) if (dfstab != NULL) { list = getdfstab(dfstab); (void) fclose(dfstab); +retry: for (share = sa_get_share(group, NULL); share != NULL; share = sa_get_next_share(share)) { /* now see if the share is in the dfstab file */ path = sa_get_share_attr(share, "path"); if (path != NULL) { item = finddfsentry(list, path); + sa_free_attr_string(path); if (item == NULL) { /* the share was removed this way */ (void) sa_remove_share(share); + /* start over since the list was broken */ - share = sa_get_share(group, NULL); + goto retry; } - sa_free_attr_string(path); } } if (list != NULL) @@ -1316,9 +1322,12 @@ parse_sharetab(void) } else { /* * if this is a legacy share, mark as shared so we - * only update sharetab appropriately. + * only update sharetab appropriately. We also keep + * the sharetab options in order to display for legacy + * share with no arguments. */ set_node_attr(share, "shared", "true"); + set_node_attr(share, "shareopts", tmplist->options); } } dfs_free_list(list); diff --git a/usr/src/lib/libshare/common/scfutil.c b/usr/src/lib/libshare/common/scfutil.c index 88447471a6..f80ac111d0 100644 --- a/usr/src/lib/libshare/common/scfutil.c +++ b/usr/src/lib/libshare/common/scfutil.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,6 +38,7 @@ #include <errno.h> #include <uuid/uuid.h> #include <sys/param.h> +#include <signal.h> ssize_t scf_max_name_len; extern struct sa_proto_plugin *sap_proto_list; @@ -418,6 +419,7 @@ sa_share_from_pgroup(xmlNodePtr root, scfutilhandle_t *handle, ssize_t vallen; char *valuestr; int ret = SA_OK; + int have_path = 0; /* * While preliminary check (starts with 'S') passed before @@ -475,6 +477,14 @@ sa_share_from_pgroup(xmlNodePtr root, scfutilhandle_t *handle, } } if (ret == SA_OK) { + /* + * check that we have the "path" property in + * name. The string in name will always be nul + * terminated if scf_property_get_name() + * succeeded. + */ + if (strcmp(name, "path") == 0) + have_path = 1; if (is_share_attr(name)) { /* * if a share attr, then simple - @@ -498,6 +508,17 @@ sa_share_from_pgroup(xmlNodePtr root, scfutilhandle_t *handle, } } } + /* + * a share without a path is broken so we want to not include + * these. They shouldn't happen but if you kill a sharemgr in + * the process of creating a share, it could happen. They + * should be harmless. It is also possible that another + * sharemgr is running and in the process of creating a share. + */ + if (have_path == 0 && node != NULL) { + xmlUnlinkNode(node); + xmlFreeNode(node); + } if (name != NULL) free(name); if (valuestr != NULL) @@ -1301,10 +1322,21 @@ sa_commit_share(scfutilhandle_t *handle, sa_group_t group, sa_share_t share) sharename = strdup(shname); } if (sharename != NULL) { + sigset_t old, new; /* - * have a share name allocated so create a pgroup - * for it. It may already exist, but that is OK. + * have a share name allocated so create a pgroup for + * it. It may already exist, but that is OK. In order + * to avoid creating a share pgroup that doesn't have + * a path property, block signals around the critical + * region of creating the share pgroup and props. */ + (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); + ret = sa_create_pgroup(handle, sharename); if (ret == SA_OK) { /* @@ -1345,6 +1377,9 @@ sa_commit_share(scfutilhandle_t *handle, sa_group_t group, sa_share_t share) } else { sa_abort_transaction(handle); } + + (void) sigprocmask(SIG_SETMASK, &old, NULL); + free(sharename); } } |