Branko Čibej wrote:
>
> Try getopt_tests.py.
Thanks, I'll take a look at it (probably not `til Wednesday).
>>+#if !( HAVE_UMASK && HAVE_SETUID && HAVE_SETGID )
>>
>>
>
> Urgh. We don't use spaces after open parens or before close parens.
Sorry! I come from the "whitespace is free" school, so I have to rigorously
supress my desire to lather everything in extra spaces... ;~)
>
>>+ printf ("WARNING: --owner and --group unavailable under Win32");
>
> 1. This warning isn't restricted to Win32 any more
Good point. How does "...unavailable on this platform" sound?
> 2. Use svn_handle_warning instead of printf
I see lots of examples using "printf()" and "fprintf(stderr," in the commandline
tools, and very few examples of using svn_handle_warning(). Since the error is
not being thrown by one of the svn_* functions, it didn't seem appropriate to
use that wrapper. There is always a point where encapsulation becomes needless
obfuscation; I'm not comfortable enough with svn code to know where that point is.
Thanks for taking the time to look over my code. I learn, but slowly. Having
good clean code makes it easier, I must say. New patch attached.
John
--
John Peacock
Director of Information Research and Technology
Rowman & Littlefield Publishing Group
4501 Forbes Boulevard
Suite H
Lanham, MD 20706
301-459-3366 x.5010
fax 301-429-5748
------------
LOG MESSAGE
------------
Implement two new options to the 'svnadmin create' command to explicitely
create a new repository with rights appropriate for either
1) exclusive access by a single user/process
2) shared access by all members of an existing system group
This is likely to only be relevant to Unix-like operating systems,
where chmod(), setgid(), and setuid() are meaningful.
* configure.in
Add tests to check for existance of chmod, setgid, and setuid
* subversion/svnadmin/main.c
(#include) - need svn_private_config.h in order to get autoconf #define's
(enum),(options_table),(cmd_table): add owner_id, group_id to option tables
(subcommand_create): Add logic to get system UID and GID and switch
current process to those values before calling svn_repos_create()
* doc/book/book/ch05.xml
(svn-ch-5-sect-2): Add paragraph and link to discussion of --owner and
--group options in svn-ch-5-sect-5.
(svn-ch-5-sect-5): Document the use of --owner and --group to create
the repository with specific rights for limited repository access.
Index: configure.in
===================================================================
--- configure.in (revision 6915)
+++ configure.in (working copy)
@@ -518,6 +518,12 @@
esac
AC_SUBST(INCLUDE_OUTPUTS)
+dnl
+dnl Check for support for umask, setuid, and setgid (needed by svnadmin)
+dnl
+
+AC_CHECK_FUNCS(umask setuid setgid)
+
dnl Final step: create the Makefile ----------------------------
AC_CONFIG_FILES([Makefile])
Index: subversion/svnadmin/main.c
===================================================================
--- subversion/svnadmin/main.c (revision 6915)
+++ subversion/svnadmin/main.c (working copy)
@@ -25,7 +25,7 @@
#include "svn_subst.h"
#include "svn_path.h"
#include "svn_config.h"
-
+#include "svn_private_config.h"
#include "svnadmin.h"
@@ -79,7 +79,9 @@
svnadmin__force_uuid,
svnadmin__parent_dir,
svnadmin__bdb_txn_nosync,
- svnadmin__config_dir
+ svnadmin__config_dir,
+ svnadmin__owner_id,
+ svnadmin__group_id
};
/* Option codes and descriptions.
@@ -133,6 +135,12 @@
{"config-dir", svnadmin__config_dir, 1,
"read user configuration files from directory ARG"},
+ {"owner", svnadmin__owner_id, 1,
+ "create repository owned and usable by user ARG"},
+
+ {"group", svnadmin__group_id, 1,
+ "create repository owned and usable by group ARG"},
+
{NULL}
};
@@ -144,9 +152,13 @@
{
{"create", subcommand_create, {0},
"usage: svnadmin create REPOS_PATH\n\n"
- "Create a new, empty repository at REPOS_PATH.\n",
+ "Create a new, empty repository at REPOS_PATH. The --owner and --group\n"
+ "options will create the repository with appropriate ownership and\n"
+ "permissions under most Unix-like O/S's (and do nothing on Win32), but\n"
+ "require that svnadmin be run as root.\n",
{svnadmin__on_disk_template, svnadmin__in_repos_template,
- svnadmin__bdb_txn_nosync, svnadmin__config_dir} },
+ svnadmin__bdb_txn_nosync, svnadmin__config_dir,
+ svnadmin__owner_id, svnadmin__group_id} },
{"createtxn", subcommand_createtxn, {0},
"usage: svnadmin createtxn REPOS_PATH -r REVISION\n\n"
@@ -246,6 +258,8 @@
const char *parent_dir;
const char *config_dir; /* Overriding Configuration Directory */
+ const char *owner_id;
+ const char *group_id;
};
/* This implements `svn_opt_subcommand_t'. */
@@ -264,6 +278,58 @@
APR_HASH_KEY_STRING, "1");
}
+ /* If the user requested the repository be created as a specific
+ * owner and/or group, we need to lookup the system UID/GID and
+ * switch the current process to that user and group before
+ * creating the repository. In this case, svnadmin must be run
+ * as root, in order to be able to switch to an arbitrary user
+ * and group. This feature does not work (currently) under Win32.
+ */
+ if (opt_state->owner_id)
+ {
+#if !(HAVE_UMASK && HAVE_SETUID && HAVE_SETGID)
+ svn_handle_warning (stderr, svn_error_create
+ (SVN_ERR_INCORRECT_PARAMS, NULL,
+ "--owner and --group unavailable on this platform"));
+#else
+ apr_uid_t retrieved_uid;
+ apr_gid_t retrieved_gid;
+ apr_status_t apr_err;
+
+ apr_err = apr_uid_get(&retrieved_uid, &retrieved_gid,
+ opt_state->owner_id, pool);
+
+ if (apr_err)
+ {
+ return svn_error_create
+ (apr_err, NULL, "failed to get owner's UID");
+ }
+
+ if (opt_state->group_id)
+ {
+ (void)umask(0007); /* permit group access */
+ apr_err = apr_gid_get(&retrieved_gid,
+ opt_state->group_id, pool);
+ if (apr_err)
+ {
+ return svn_error_create
+ (apr_err, NULL, "failed to get group's GID");
+ }
+ }
+ else
+ {
+ (void)umask(0077); /* no group access */
+ }
+
+ if ( setgid(retrieved_gid) != 0 )
+ return svn_error_create (SVN_ERR_INCORRECT_PARAMS, NULL,
+ "problem setting gid (must be root)");
+ if ( setuid(retrieved_uid) != 0 )
+ return svn_error_createf (SVN_ERR_INCORRECT_PARAMS, NULL,
+ "problem setting uid (must be root)");
+#endif
+ }
+
SVN_ERR (svn_config_get_config (&config, opt_state->config_dir, pool));
SVN_ERR (svn_repos_create (&repos, opt_state->repository_path,
opt_state->on_disk, opt_state->in_repos,
@@ -796,6 +862,12 @@
opt_state.config_dir = apr_pstrdup (pool, svn_path_canonicalize(opt_arg,
pool));
break;
+ case svnadmin__group_id:
+ opt_state.group_id = apr_pstrdup (pool, opt_arg);
+ break;
+ case svnadmin__owner_id:
+ opt_state.owner_id = apr_pstrdup (pool, opt_arg);
+ break;
default:
{
subcommand_help (NULL, NULL, pool);
Index: doc/book/book/ch05.xml
===================================================================
--- doc/book/book/ch05.xml (revision 6915)
+++ doc/book/book/ch05.xml (working copy)
@@ -170,6 +170,12 @@
directory. Initially, revision 0 also has a single revision
property, <literal>svn:date</literal>, set to the time at which
the repository was created.</para>
+
+ <para>If you need to limit the local file:// access to the repository
+ to a specific user or share it with a specific group, please see
+ <xref linkend="svn-ch-5-sect-5"/>. You should also consult that
+ section for one way to set the repository permissions for access
+ via Apache or svnserver.</para>
<para>You may have noticed that the path argument to
<command>svnadmin</command> was just a regular filesystem path
@@ -2610,11 +2616,43 @@
files? Assuming you have a Unix-like operating system, a
straightforward approach might be to place every potential
repository user into a new <literal>svn</literal> group, and
- make the repository wholly owned by that group. But even that's
- not enough, because a process may write to the database files
- using an unfriendly umask—one which prevents access by
- other users.</para>
+ make the repository wholly owned by that group. Fortunately,
+ <command>svnadmin create</command> has several options that
+ make this trivial under Unix-like operating systems.</para>
+ <para>If you want to initially create the repository so that it is
+ exclusively accessible by a single user (either because it is a
+ private repository accessed via file:// or because you will only
+ access the repository via a specific non-priveledged account under
+ Apache or svnserver), you can use the following commands:</para>
+
+ <screen>
+$ su [enter root password]
+# svnadmin create --owner nobody /path/to/repository
+</screen>
+
+ <para>which will create a repository owned by the 'nobody' user,
+ with exclusive (i.e. no group or other) rights.</para>
+
+ <para>On the other hand, if you want a group of local users to have
+ local file:// access (as well as possibly an Apache or svnserver
+ server), you can use something like the following commands:</para>
+
+ <screen>
+$ su [enter root password]
+# svnadmin create --group svn --owner admuser /path/to/repository
+</screen>
+
+ <para>which will create a repository owned by 'admuser' (typically
+ the user who will be managing the database, running recovery, etc).
+ The files will also have the group 'svn' (which needs to be created
+ and populated first), so that all users in that group will be able
+ to use file:// access.</para>
+
+ <para>But even that's not enough, because a process may write to the
+ database files using an unfriendly umask—one which prevents
+ access by other users.</para>
+
<para>So the next step beyond setting up a common group for
repository users is to force every repository-accessing process
to use a sane umask. For users accessing the repository
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Sep 22 16:17:10 2003