~serge-hallyn/ubuntu/quantal/lxc/lxc-user-ns

« back to all changes in this revision

Viewing changes to src/lxc/conf.c

  • Committer: Serge Hallyn
  • Date: 2012-10-29 16:51:57 UTC
  • Revision ID: serge.hallyn@ubuntu.com-20121029165157-xw2nxym7eo0ocxu4
Add user namespaces patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1079
1079
        return 0;
1080
1080
}
1081
1081
 
1082
 
static int setup_cgroup(const char *name, struct lxc_list *cgroups)
 
1082
int setup_cgroup(const char *name, struct lxc_list *cgroups)
1083
1083
{
1084
1084
        struct lxc_list *iterator;
1085
1085
        struct lxc_cgroup *cg;
1738
1738
        lxc_list_init(&new->network);
1739
1739
        lxc_list_init(&new->mount_list);
1740
1740
        lxc_list_init(&new->caps);
 
1741
        lxc_list_init(&new->id_map);
1741
1742
        new->aa_profile = NULL;
1742
1743
        for (i=0; i<NUM_LXC_HOOKS; i++)
1743
1744
                lxc_list_init(&new->hooks[i]);
2037
2038
        return 0;
2038
2039
}
2039
2040
 
 
2041
int add_id_mapping(enum idtype idtype, pid_t pid, uid_t host_start, uid_t ns_start, int range)
 
2042
{
 
2043
        char path[PATH_MAX];
 
2044
        int ret;
 
2045
        FILE *f;
 
2046
 
 
2047
        ret = snprintf(path, PATH_MAX, "/proc/%d/%cid_map", pid, idtype == ID_TYPE_UID ? 'u' : 'g');
 
2048
        if (ret < 0 || ret >= PATH_MAX) {
 
2049
                fprintf(stderr, "%s: path name too long", __func__);
 
2050
                return -E2BIG;
 
2051
        }
 
2052
        f = fopen(path, "w");
 
2053
        if (!f) {
 
2054
                perror("open");
 
2055
                return -EINVAL;
 
2056
        }
 
2057
        ret = fprintf(f, "%d %d %d", ns_start, host_start, range);
 
2058
        if (ret < 0)
 
2059
                perror("write");
 
2060
        fclose(f);
 
2061
        return ret < 0 ? ret : 0;
 
2062
}
 
2063
 
 
2064
int lxc_map_ids(struct lxc_list *idmap, pid_t pid)
 
2065
{
 
2066
        struct lxc_list *iterator;
 
2067
        struct id_map *map;
 
2068
        int ret;
 
2069
 
 
2070
        lxc_list_for_each(iterator, idmap) {
 
2071
                map = iterator->elem;
 
2072
                ret = add_id_mapping(map->idtype, pid, map->hostid, map->nsid, map->range);
 
2073
                if (ret)
 
2074
                        break;
 
2075
        }
 
2076
        return ret;
 
2077
}
 
2078
 
2040
2079
int lxc_find_gateway_addresses(struct lxc_handler *handler)
2041
2080
{
2042
2081
        struct lxc_list *network = &handler->conf->network;
2218
2257
                return -1;
2219
2258
        }
2220
2259
 
2221
 
        if (setup_cgroup(name, &lxc_conf->cgroup)) {
2222
 
                ERROR("failed to setup the cgroups for '%s'", name);
2223
 
                return -1;
2224
 
        }
2225
2260
        if (run_lxc_hooks(name, "mount", lxc_conf)) {
2226
2261
                ERROR("failed to run mount hooks for container '%s'.", name);
2227
2262
                return -1;
2274
2309
                return -1;
2275
2310
        }
2276
2311
 
2277
 
        if (setup_caps(&lxc_conf->caps)) {
2278
 
                ERROR("failed to drop capabilities");
2279
 
                return -1;
 
2312
        if (lxc_list_empty(&lxc_conf->id_map)) {
 
2313
                if (setup_caps(&lxc_conf->caps)) {
 
2314
                        ERROR("failed to drop capabilities");
 
2315
                        return -1;
 
2316
                }
2280
2317
        }
2281
2318
 
2282
2319
        NOTICE("'%s' is setup.", name);
2533
2570
        lxc_clear_mount_entries(conf);
2534
2571
        free(conf);
2535
2572
}
 
2573
 
 
2574
/*
 
2575
 * given a host uid, return the ns uid if it is mapped.
 
2576
 * if it is not mapped, return the original host id.
 
2577
 */
 
2578
static int shiftid(struct lxc_conf *c, int uid, enum idtype w)
 
2579
{
 
2580
        struct lxc_list *iterator;
 
2581
        struct id_map *map;
 
2582
        int low, high;
 
2583
 
 
2584
        lxc_list_for_each(iterator, &c->id_map) {
 
2585
                map = iterator->elem;
 
2586
                if (map->idtype != w)
 
2587
                        continue;
 
2588
 
 
2589
                low = map->hostid;
 
2590
                high = map->hostid + map->range;
 
2591
                if (uid < low || uid >= high)
 
2592
                        continue;
 
2593
 
 
2594
                return uid - low + map->nsid;
 
2595
        }
 
2596
 
 
2597
        return uid;
 
2598
}
 
2599
 
 
2600
/*
 
2601
 * Take a pathname for a file created on the host, and map the uid and gid
 
2602
 * into the container if needed.  (Used for ttys)
 
2603
 */
 
2604
int uid_shift_file(char *path, struct lxc_conf *c)
 
2605
{
 
2606
        struct stat statbuf;
 
2607
        int newuid, newgid;
 
2608
 
 
2609
        if (stat(path, &statbuf)) {
 
2610
                SYSERROR("stat(%s)", path);
 
2611
                return -1;
 
2612
        }
 
2613
 
 
2614
        newuid = shiftid(c, statbuf.st_uid, ID_TYPE_UID);
 
2615
        newgid = shiftid(c, statbuf.st_gid, ID_TYPE_GID);
 
2616
        if (newuid != statbuf.st_uid || newgid != statbuf.st_gid) {
 
2617
                if (chown(path, newuid, newgid)) {
 
2618
                        SYSERROR("chown(%s)", path);
 
2619
                        return -1;
 
2620
                }
 
2621
        }
 
2622
        return 0;
 
2623
}