From 98cfc1aab07d311b53b0171fad62a4031c96fcfd Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Mon, 18 Jul 2016 14:23:36 -0400 Subject: Add uid/gid config parameters to shared-vm database map operator So vpp_get_metrics and similar will not need to run as root Change-Id: I635e830834c82990ad84ddaae06f2e50e55fd616 Signed-off-by: Dave Barach --- gmod/gmod/mod_vpp.c | 6 +- svm/svmdb.c | 36 +++-------- svm/svmdb.h | 16 ++--- svm/svmdbtool.c | 142 ++++++++++++++++++++++++++++++++++++++---- vpp-api-test/vat/restart.c | 8 ++- vpp/vpp-api/gmon.c | 9 ++- vpp/vpp-api/vpp_get_metrics.c | 65 ++++++++++++++++++- 7 files changed, 226 insertions(+), 56 deletions(-) diff --git a/gmod/gmod/mod_vpp.c b/gmod/gmod/mod_vpp.c index 4a82ca70..4a1da83c 100644 --- a/gmod/gmod/mod_vpp.c +++ b/gmod/gmod/mod_vpp.c @@ -33,6 +33,7 @@ static int vpp_metric_init (apr_pool_t *p) apr_array_header_t *list_params = vpp_module.module_params_list; mmparam *params; char *chroot_path = 0; + svmdb_map_args_t _ma, *ma= &_ma; int i; if (str_params) { @@ -47,7 +48,10 @@ static int vpp_metric_init (apr_pool_t *p) } } - svmdb_client = svmdb_map_chroot (chroot_path); + memset (ma, 0, sizeof (*ma)); + ma->root_path = (char *)chroot_path; + + svmdb_client = svmdb_map (ma); /* Initialize the metadata storage for each of the metrics and then diff --git a/svm/svmdb.c b/svm/svmdb.c index b22d2fab..c0680bc3 100644 --- a/svm/svmdb.c +++ b/svm/svmdb.c @@ -66,8 +66,8 @@ region_unlock (svm_region_t * rp) pthread_mutex_unlock (&rp->mutex); } -static svmdb_client_t * -svmdb_map_internal (char *root_path, uword size) +svmdb_client_t * +svmdb_map (svmdb_map_args_t * dba) { svmdb_client_t *client = 0; svm_map_region_args_t *a = 0; @@ -78,12 +78,14 @@ svmdb_map_internal (char *root_path, uword size) vec_validate (client, 0); vec_validate (a, 0); - svm_region_init_chroot (root_path); + svm_region_init_chroot_uid_gid (dba->root_path, dba->uid, dba->gid); - a->root_path = root_path; + a->root_path = dba->root_path; a->name = "/db"; - a->size = size ? size : SVMDB_DEFAULT_SIZE; + a->size = dba->size ? dba->size : SVMDB_DEFAULT_SIZE; a->flags = SVM_FLAGS_MHEAP; + a->uid = dba->uid; + a->gid = dba->gid; db_rp = client->db_rp = svm_region_find_or_create (a); @@ -127,30 +129,6 @@ svmdb_map_internal (char *root_path, uword size) return (client); } -svmdb_client_t * -svmdb_map (void) -{ - return svmdb_map_internal (0, 0); -} - -svmdb_client_t * -svmdb_map_size (uword size) -{ - return svmdb_map_internal (0, size); -} - -svmdb_client_t * -svmdb_map_chroot (char *root_path) -{ - return svmdb_map_internal (root_path, 0); -} - -svmdb_client_t * -svmdb_map_chroot_size (char *root_path, uword size) -{ - return svmdb_map_internal (root_path, size); -} - void svmdb_unmap (svmdb_client_t * client) { diff --git a/svm/svmdb.h b/svm/svmdb.h index 5f44b332..a113c22d 100644 --- a/svm/svmdb.h +++ b/svm/svmdb.h @@ -81,19 +81,21 @@ typedef struct u32 opaque:28; } svmdb_notification_args_t; +typedef struct +{ + char *root_path; + uword size; + u32 uid; + u32 gid; +} svmdb_map_args_t; + /* * Must be a reasonable number, several mb smaller than * SVM_GLOBAL_REGION_SIZE, or no donut for you... */ #define SVMDB_DEFAULT_SIZE (4<<20) -svmdb_client_t *svmdb_map (void); - -svmdb_client_t *svmdb_map_size (uword size); - -svmdb_client_t *svmdb_map_chroot (char *root_path); - -svmdb_client_t *svmdb_map_chroot_size (char *root_path, uword size); +svmdb_client_t *svmdb_map (svmdb_map_args_t *); void svmdb_unmap (svmdb_client_t * client); void svmdb_local_unset_string_variable (svmdb_client_t * client, char *var); diff --git a/svm/svmdbtool.c b/svm/svmdbtool.c index cf475c4d..829df4e9 100644 --- a/svm/svmdbtool.c +++ b/svm/svmdbtool.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -38,13 +40,39 @@ #include #include "svmdb.h" +typedef struct +{ + svmdb_map_args_t map_args; + int uid, gid; + uword size; +} svmdbtool_main_t; + +svmdbtool_main_t svmdbtool_main; + +static inline +svmdb_map_args_t * map_arg_setup (char *chroot_path) +{ + svmdbtool_main_t *sm = &svmdbtool_main; + svmdb_map_args_t *ma = &sm->map_args; + + memset (ma, 0, sizeof (*ma)); + ma->root_path = chroot_path; + ma->size = sm->size; + ma->uid = sm->uid; + ma->gid = sm->gid; + return ma; +} + static void get_string (char *chroot_path, u8 * vbl) { svmdb_client_t *c; char *rv; + svmdb_map_args_t *ma; - c = svmdb_map_chroot (chroot_path); + ma = map_arg_setup (chroot_path); + + c = svmdb_map (ma); rv = svmdb_local_get_string_variable (c, (char *) vbl); @@ -57,8 +85,11 @@ static void set_string (char *chroot_path, u8 * vbl, u8 * value) { svmdb_client_t *c; + svmdb_map_args_t *ma; + + ma = map_arg_setup (chroot_path); - c = svmdb_map_chroot (chroot_path); + c = svmdb_map (ma); svmdb_local_set_string_variable (c, (char *) vbl, (char *) value); svmdb_unmap (c); } @@ -67,8 +98,11 @@ static void unset_string (char *chroot_path, u8 * vbl) { svmdb_client_t *c; + svmdb_map_args_t *ma; - c = svmdb_map_chroot (chroot_path); + ma = map_arg_setup (chroot_path); + + c = svmdb_map (ma); svmdb_local_unset_string_variable (c, (char *) vbl); svmdb_unmap (c); } @@ -77,8 +111,11 @@ static void dump_strings (char *chroot_path) { svmdb_client_t *c; + svmdb_map_args_t *ma; + + ma = map_arg_setup (chroot_path); - c = svmdb_map_chroot (chroot_path); + c = svmdb_map (ma); svmdb_local_dump_strings (c); svmdb_unmap (c); } @@ -88,10 +125,13 @@ test_vlib_vec_rate (char *chroot_path, f64 vr) { svmdb_client_t *c; f64 *tv = 0; + svmdb_map_args_t *ma; - vec_add1 (tv, vr); + ma = map_arg_setup (chroot_path); + + c = svmdb_map (ma); - c = svmdb_map_chroot (chroot_path); + vec_add1 (tv, vr); svmdb_local_set_vec_variable (c, "vlib_vector_rate", (char *) tv, sizeof (*tv)); @@ -108,6 +148,11 @@ test_vec (char *chroot_path, u8 * vbl) svmdb_client_t *c; u64 *tv = 0; int i; + svmdb_map_args_t *ma; + + ma = map_arg_setup (chroot_path); + + c = svmdb_map (ma); /* my amp goes to 11 */ for (i = 0; i < 11; i++) @@ -115,7 +160,6 @@ test_vec (char *chroot_path, u8 * vbl) vec_add1 (tv, i); } - c = svmdb_map_chroot (chroot_path); svmdb_local_set_vec_variable (c, (char *) vbl, (char *) tv, sizeof (tv[0])); svmdb_unmap (c); @@ -132,8 +176,11 @@ fake_install (char *chroot_path, u8 * add_value) u8 *value; int nitems = 0, i; serialize_main_t m; + svmdb_map_args_t *ma; - c = svmdb_map_chroot (chroot_path); + ma = map_arg_setup (chroot_path); + + c = svmdb_map (ma); oldvalue = svmdb_local_get_vec_variable (c, "installed_sw", 1); if (oldvalue) @@ -192,6 +239,9 @@ test_reg (char *chroot_path, u8 * vbl) svmdb_notification_args_t args; svmdb_notification_args_t *a = &args; struct sigaction sa; + svmdb_map_args_t *ma; + + ma = map_arg_setup (chroot_path); memset (&sa, 0, sizeof (sa)); sa.sa_sigaction = sigaction_handler; @@ -204,7 +254,7 @@ test_reg (char *chroot_path, u8 * vbl) memset (a, 0, sizeof (*a)); - c = svmdb_map_chroot (chroot_path); + c = svmdb_map (ma); a->add_del = 1 /* add */ ; a->nspace = SVMDB_NAMESPACE_STRING; @@ -230,8 +280,12 @@ static void unset_vec (char *chroot_path, u8 * vbl) { svmdb_client_t *c; + svmdb_map_args_t *ma; + + ma = map_arg_setup (chroot_path); + + c = svmdb_map (ma); - c = svmdb_map_chroot (chroot_path); svmdb_local_unset_vec_variable (c, (char *) vbl); svmdb_unmap (c); } @@ -240,8 +294,12 @@ static void dump_vecs (char *chroot_path) { svmdb_client_t *c; + svmdb_map_args_t *ma; + + ma = map_arg_setup (chroot_path); + + c = svmdb_map (ma); - c = svmdb_map_chroot (chroot_path); svmdb_local_dump_vecs (c); svmdb_unmap (c); } @@ -250,8 +308,11 @@ static void crash_test (char *chroot_path) { svmdb_client_t *c; + svmdb_map_args_t *ma; + + ma = map_arg_setup (chroot_path); - c = svmdb_map_chroot (chroot_path); + c = svmdb_map (ma); clib_warning ("Grab region mutex and crash deliberately!"); c->db_rp->mutex_owner_pid = getpid (); @@ -265,7 +326,13 @@ static void map_with_size (char *chroot_path, uword size) { svmdb_client_t *c; - c = svmdb_map_chroot_size (chroot_path, size); + svmdb_map_args_t *ma; + + svmdbtool_main.size = size; + ma = map_arg_setup (chroot_path); + + c = svmdb_map (ma); + svmdb_unmap (c); } @@ -279,6 +346,13 @@ main (int argc, char **argv) u8 *chroot_path_u8; uword size; f64 vr; + int uid, gid, rv; + struct passwd _pw, *pw; + struct group _grp, *grp; + char *s, buf[128]; + + svmdbtool_main.uid = geteuid(); + svmdbtool_main.gid = getegid(); unformat_init_command_line (&input, argv); @@ -353,6 +427,46 @@ main (int argc, char **argv) map_with_size (chroot_path, size); parsed++; } + else if (unformat (&input, "uid %d", &uid)) + svmdbtool_main.uid = uid; + else if (unformat (&input, "gid %d", &gid)) + svmdbtool_main.gid = gid; + else if (unformat (&input, "uid %s", &s)) + { + /* lookup the username */ + pw = NULL; + rv = getpwnam_r(s, &_pw, buf, sizeof(buf), &pw); + if (rv < 0) + { + fformat (stderr, "cannot fetch username %s", s); + exit (1); + } + if (pw == NULL) + { + fformat (stderr, "username %s does not exist", s); + exit (1); + } + vec_free (s); + svmdbtool_main.uid = pw->pw_uid; + } + else if (unformat (&input, "gid %s", &s)) + { + /* lookup the group name */ + grp = NULL; + rv = getgrnam_r(s, &_grp, buf, sizeof(buf), &grp); + if (rv != 0) + { + fformat (stderr, "cannot fetch group %s", s); + exit (1); + } + if (grp == NULL) + { + fformat (stderr, "group %s does not exist", s); + exit (1); + } + vec_free (s); + svmdbtool_main.gid = grp->gr_gid; + } else { break; @@ -368,6 +482,8 @@ main (int argc, char **argv) fformat (stdout, " unset-string | dump-strings\n"); fformat (stdout, " test-vec |\n"); fformat (stdout, " unset-vec | dump-vecs\n"); + fformat (stdout, " chroot [uid ]\n"); + fformat (stdout, " [gid ]\n"); } exit (0); diff --git a/vpp-api-test/vat/restart.c b/vpp-api-test/vat/restart.c index d94ddf89..2bbaa516 100644 --- a/vpp-api-test/vat/restart.c +++ b/vpp-api-test/vat/restart.c @@ -40,6 +40,7 @@ int restart_main_fn (unformat_input_t * i) struct stat statb; ino_t old_inode; int sleeps; + svmdb_map_args_t _ma, *ma= &_ma; struct timespec _req, *req = &_req; struct timespec _rem, *rem = &_rem; @@ -63,7 +64,10 @@ int restart_main_fn (unformat_input_t * i) /* * Step 1: look up the current VPP pid in the shared-memory database */ - svmdb_client = svmdb_map_chroot ((char *) chroot_path); + memset (ma, 0, sizeof (*ma)); + ma->root_path = (char *)chroot_path; + + svmdb_client = svmdb_map (ma); pidp = svmdb_local_get_variable_reference (svmdb_client, SVMDB_NAMESPACE_VEC, @@ -173,7 +177,7 @@ int restart_main_fn (unformat_input_t * i) /* * Step 6: remap the SVM database */ - svmdb_client = svmdb_map_chroot ((char *) chroot_path); + svmdb_client = svmdb_map (ma); pidp = svmdb_local_get_variable_reference (svmdb_client, SVMDB_NAMESPACE_VEC, diff --git a/vpp/vpp-api/gmon.c b/vpp/vpp-api/gmon.c index 6ab71096..05d6a117 100644 --- a/vpp/vpp-api/gmon.c +++ b/vpp/vpp-api/gmon.c @@ -166,6 +166,7 @@ gmon_init (vlib_main_t *vm) pid_t *swp = 0; f64 *v = 0; clib_error_t * error; + svmdb_map_args_t _ma, *ma= &_ma; if ((error = vlib_call_init_function(vm, vpe_api_init))) return(error); @@ -174,7 +175,13 @@ gmon_init (vlib_main_t *vm) svm_region_init_chroot_uid_gid (am->root_path, am->api_uid, am->api_gid); gm->vlib_main = vm; - gm->svmdb_client = svmdb_map_chroot(am->root_path); + + memset (ma, 0, sizeof (*ma)); + ma->root_path = am->root_path; + ma->uid = am->api_uid; + ma->gid = am->api_gid; + + gm->svmdb_client = svmdb_map (ma); /* Find or create, set to zero */ vec_add1 (v, 0.0); diff --git a/vpp/vpp-api/vpp_get_metrics.c b/vpp/vpp-api/vpp_get_metrics.c index e963bc6d..ea4af01d 100644 --- a/vpp/vpp-api/vpp_get_metrics.c +++ b/vpp/vpp-api/vpp_get_metrics.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -106,9 +108,17 @@ main (int argc, char **argv) int interval = 0; f64 *vector_ratep, *rx_ratep, *sig_error_ratep; pid_t *vpp_pidp; + svmdb_map_args_t _ma, *ma= &_ma; + int uid, gid, rv; + struct passwd _pw, *pw; + struct group _grp, *grp; + char *s, buf[128]; unformat_init_command_line (&input, argv); + uid = geteuid(); + gid = getegid(); + while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT) { if (unformat (&input, "chroot %s", &chroot_path_u8)) @@ -117,6 +127,46 @@ main (int argc, char **argv) } else if (unformat (&input, "interval %d", &interval)) ; + else if (unformat (&input, "uid %d", &uid)) + ; + else if (unformat (&input, "gid %d", &gid)) + ; + else if (unformat (&input, "uid %s", &s)) + { + /* lookup the username */ + pw = NULL; + rv = getpwnam_r(s, &_pw, buf, sizeof(buf), &pw); + if (rv < 0) + { + fformat (stderr, "cannot fetch username %s", s); + exit (1); + } + if (pw == NULL) + { + fformat (stderr, "username %s does not exist", s); + exit (1); + } + vec_free (s); + uid = pw->pw_uid; + } + else if (unformat (&input, "gid %s", &s)) + { + /* lookup the group name */ + grp = NULL; + rv = getgrnam_r(s, &_grp, buf, sizeof(buf), &grp); + if (rv != 0) + { + fformat (stderr, "cannot fetch group %s", s); + exit (1); + } + if (grp == NULL) + { + fformat (stderr, "group %s does not exist", s); + exit (1); + } + vec_free (s); + gid = grp->gr_gid; + } else { fformat (stderr, @@ -127,7 +177,12 @@ main (int argc, char **argv) setup_signal_handlers (); - c = svmdb_map_chroot (chroot_path); + memset (ma, 0, sizeof (*ma)); + ma->root_path = chroot_path; + ma->uid = uid; + ma->gid = gid; + + c = svmdb_map (ma); vpp_pidp = svmdb_local_get_variable_reference (c, SVMDB_NAMESPACE_VEC, "vpp_pid"); @@ -156,8 +211,12 @@ main (int argc, char **argv) do { - /* Once vpp exits, the svm db region will be recreated... */ - if (*vpp_pidp == 0 || kill (*vpp_pidp, 0) < 0) + /* + * Once vpp exits, the svm db region will be recreated... + * Can't use kill (*vpp_pidp, 0) if running as non-root / + * accessing the shared-VM database via group perms. + */ + if (*vpp_pidp == 0) { fformat (stdout, "vpp not running\n"); exit (1); -- cgit 1.2.3-korg