[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] svnadmin create --owner --group patch (new feature)

From: John Peacock <jpeacock_at_rowman.com>
Date: 2003-09-09 17:24:35 CEST

Here is my suggestion for automatically creating a new subversion repository
with appropriate rights, based on exclusive access by a specific user or group.
  I'm away from work today, so I have not tested this on Win32. I am also
submitting it as an attachment (not trusting my mail client to play nice with
whitespace and/or possible wrapping). The log message is also prepended on the
patch.

I am not a Python programmer [yet???] so I did not include a testcase either,
but if need be, I will learn enough Python to submit one. I did include a patch
to the docs, though...

John

------------
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,
basically where setgid() and setuid() are meaningful.

* subversion/svnadmin/main.c
     (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.

-- 
John Peacock
Director of Information Research and Technology
Rowman & Littlefield Publishing Group
4720 Boston Way
Lanham, MD 20706
301-459-3366 x.5010
fax 301-429-5747

------------
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,
basically where setgid() and setuid() are meaningful.

* subversion/svnadmin/main.c
    (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: subversion/svnadmin/main.c
===================================================================
--- subversion/svnadmin/main.c (revision 6915)
+++ subversion/svnadmin/main.c (working copy)
@@ -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}
   };
 
@@ -146,7 +154,8 @@
      "usage: svnadmin create REPOS_PATH\n\n"
      "Create a new, empty repository at REPOS_PATH.\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 +255,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 +275,52 @@
                     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
+ */
+ if (opt_state->owner_id)
+ {
+ 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 (apr_err, NULL,
+ "must be root to set the gid");
+ if ( setuid(retrieved_uid) != 0 )
+ return svn_error_createf (apr_err, NULL,
+ "must be root to set the uid");
+ }
+
   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 +853,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&mdash;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&mdash;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 Tue Sep 9 17:25:21 2003

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.