summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/libshare/common/libshare.c69
-rw-r--r--usr/src/lib/libshare/common/libshare.h14
-rw-r--r--usr/src/lib/libshare/common/libsharecore.c19
-rw-r--r--usr/src/lib/libshare/common/scfutil.c41
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);
}
}