1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 #include <liblustre.h>
34 #include <linux/lustre_idl.h>
35 #include <linux/obd.h>
36 #include <linux/lustre_mds.h>
38 #include <portals/types.h>
39 #include <portals/ptlctl.h>
43 * 0: fail to insert (found identical)
46 int insert_sort(gid_t *groups, int size, gid_t grp)
51 for (i = 0; i < size; i++) {
58 for (; i <= size; i++) {
66 int get_groups_local(uid_t uid, gid_t *gid, int *ngroups, gid_t **groups)
75 maxgroups = sysconf(_SC_NGROUPS_MAX);
76 *groups = malloc(maxgroups * sizeof(gid_t));
86 while ((gr = getgrent())) {
89 for (i = 0; gr->gr_mem[i]; i++) {
90 if (strcmp(gr->gr_mem[i], pw->pw_name))
92 size += insert_sort(*groups, size, gr->gr_gid);
95 if (size == maxgroups)
103 #define LINEBUF_SIZE (1024)
104 static char linebuf[LINEBUF_SIZE];
106 int readline(FILE *fp, char *buf, int bufsize)
111 if (fgets(buf, bufsize, fp) == NULL)
130 #define IS_SPACE(c) ((c) == ' ' || (c) == '\t')
132 void remove_space_head(char **buf)
142 void remove_space_tail(char **buf)
159 int get_next_uid_range(char **buf, uid_t *uid_range)
164 remove_space_head(&p);
168 comma = strchr(p, ',');
173 *buf = p + strlen(p);
175 sub = strchr(p, '-');
177 uid_range[0] = uid_range[1] = atoi(p);
180 uid_range[0] = atoi(p);
181 uid_range[1] = atoi(sub);
190 int remove_bracket(char **buf)
204 if (*p2 != ' ' && *p2 != '\t')
209 remove_space_tail(&p);
214 /* return 0: found a match */
215 int search_uid(FILE *fp, uid_t uid)
222 rc = readline(fp, linebuf, LINEBUF_SIZE);
229 if (remove_bracket(&p))
232 while (get_next_uid_range(&p, uid_range) == 0) {
233 if (uid >= uid_range[0] && uid <= uid_range[1]) {
245 {"setuid", LSD_PERM_SETUID},
246 {"setgid", LSD_PERM_SETGID},
247 {"setgrp", LSD_PERM_SETGRP},
249 #define N_PERM_TYPES (3)
251 int parse_perm(__u32 *perm, char *str)
261 comma = strchr(str, ',');
267 for (i = 0; i < N_PERM_TYPES; i++) {
268 if (!strcasecmp(p, perm_types[i].name)) {
269 *perm |= perm_types[i].bit;
274 if (i >= N_PERM_TYPES) {
275 printf("unkown perm type: %s\n", p);
285 int parse_nid(ptl_nid_t *nidp, char *nid_str)
287 if (!strcmp(nid_str, "*")) {
292 return ptl_parse_nid(nidp, nid_str);
295 int get_one_perm(FILE *fp, struct lsd_permission *perm)
297 char nid_str[256], perm_str[256];
301 rc = readline(fp, linebuf, LINEBUF_SIZE);
307 rc = sscanf(linebuf, "%s %s", nid_str, perm_str);
311 if (parse_nid(&perm->nid, nid_str))
314 if (parse_perm(&perm->perm, perm_str))
321 #define MAX_PERMS (50)
323 int get_perms(FILE *fp, uid_t uid, int *nperms, struct lsd_permission **perms)
325 static struct lsd_permission _perms[MAX_PERMS];
327 if (search_uid(fp, uid))
331 while (*nperms < MAX_PERMS) {
332 if (get_one_perm(fp, &_perms[*nperms]))
340 void show_result(struct lsd_downcall_args *dc)
344 printf("err: %d, uid %u, gid %d\n"
346 dc->err, dc->uid, dc->gid, dc->ngroups);
347 for (i = 0; i < dc->ngroups; i++)
348 printf("\t%d\n", dc->groups[i]);
350 printf("nperms: %d\n", dc->nperms);
351 for (i = 0; i < dc->nperms; i++)
352 printf("\t: netid %u, nid "LPX64", bits %x\n", i,
353 dc->perms[i].nid, dc->perms[i].perm);
356 void usage(char *prog)
358 printf("Usage: %s [-t] uid\n", prog);
362 int main (int argc, char **argv)
364 char *dc_name = "/proc/fs/lustre/mds/lsd_downcall";
366 char *conf_name = "/etc/lustre/lsd.conf";
368 struct lsd_downcall_args ioc_data;
370 int opt, testing = 0, rc;
372 while ((opt = getopt(argc, argv, "t")) != -1) {
385 memset(&ioc_data, 0, sizeof(ioc_data));
386 ioc_data.uid = atoi(argv[optind]);
388 /* read user/group database */
389 ioc_data.err = get_groups_local(ioc_data.uid, &ioc_data.gid,
390 (int *)&ioc_data.ngroups,
395 /* read lsd config database */
396 conf_fp = fopen(conf_name, "r");
398 get_perms(conf_fp, ioc_data.uid,
399 (int *)&ioc_data.nperms,
407 show_result(&ioc_data);
410 dc_fd = open(dc_name, O_WRONLY);
412 printf("can't open device %s\n", dc_name);
416 rc = write(dc_fd, &ioc_data, sizeof(ioc_data));
417 return (rc != sizeof(ioc_data));