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.
34 #include <liblustre.h>
35 #include <linux/lustre_idl.h>
36 #include <linux/obd.h>
37 #include <linux/lustre_mds.h>
39 #include <portals/types.h>
40 #include <portals/ptlctl.h>
44 * 0: fail to insert (found identical)
47 int insert_sort(gid_t *groups, int size, gid_t grp)
52 for (i = 0; i < size; i++) {
59 for (; i <= size; i++) {
67 int get_groups_local(uid_t uid, gid_t *gid, int *ngroups, gid_t **groups)
76 maxgroups = sysconf(_SC_NGROUPS_MAX);
77 *groups = malloc(maxgroups * sizeof(gid_t));
87 while ((gr = getgrent())) {
90 for (i = 0; gr->gr_mem[i]; i++) {
91 if (strcmp(gr->gr_mem[i], pw->pw_name))
93 size += insert_sort(*groups, size, gr->gr_gid);
96 if (size == maxgroups)
104 #define LINEBUF_SIZE (1024)
105 static char linebuf[LINEBUF_SIZE];
107 int readline(FILE *fp, char *buf, int bufsize)
112 if (fgets(buf, bufsize, fp) == NULL)
131 #define IS_SPACE(c) ((c) == ' ' || (c) == '\t')
133 void remove_space_head(char **buf)
143 void remove_space_tail(char **buf)
160 int get_next_uid_range(char **buf, uid_t *uid_range)
165 remove_space_head(&p);
169 comma = strchr(p, ',');
174 *buf = p + strlen(p);
176 sub = strchr(p, '-');
178 uid_range[0] = uid_range[1] = atoi(p);
181 uid_range[0] = atoi(p);
182 uid_range[1] = atoi(sub);
191 int remove_bracket(char **buf)
205 if (*p2 != ' ' && *p2 != '\t')
210 remove_space_tail(&p);
215 /* return 0: found a match */
216 int search_uid(FILE *fp, uid_t uid)
223 rc = readline(fp, linebuf, LINEBUF_SIZE);
230 if (remove_bracket(&p))
233 while (get_next_uid_range(&p, uid_range) == 0) {
234 if (uid >= uid_range[0] && uid <= uid_range[1]) {
246 {"setuid", LSD_PERM_SETUID},
247 {"setgid", LSD_PERM_SETGID},
248 {"setgrp", LSD_PERM_SETGRP},
250 #define N_PERM_TYPES (3)
252 int parse_perm(__u32 *perm, char *str)
262 comma = strchr(str, ',');
268 for (i = 0; i < N_PERM_TYPES; i++) {
269 if (!strcasecmp(p, perm_types[i].name)) {
270 *perm |= perm_types[i].bit;
275 if (i >= N_PERM_TYPES) {
276 printf("unkown perm type: %s\n", p);
286 int parse_nid(ptl_nid_t *nidp, char *nid_str)
288 if (!strcmp(nid_str, "*")) {
293 return ptl_parse_nid(nidp, nid_str);
296 int get_one_perm(FILE *fp, struct lsd_permission *perm)
298 char nid_str[256], perm_str[256];
302 rc = readline(fp, linebuf, LINEBUF_SIZE);
308 rc = sscanf(linebuf, "%s %s", nid_str, perm_str);
312 if (parse_nid(&perm->nid, nid_str))
315 if (parse_perm(&perm->perm, perm_str))
322 #define MAX_PERMS (50)
324 int get_perms(FILE *fp, uid_t uid, int *nperms, struct lsd_permission **perms)
326 static struct lsd_permission _perms[MAX_PERMS];
328 if (search_uid(fp, uid))
332 while (*nperms < MAX_PERMS) {
333 if (get_one_perm(fp, &_perms[*nperms]))
341 void show_result(struct lsd_downcall_args *dc)
345 printf("err: %d, uid %u, gid %d\n"
347 dc->err, dc->uid, dc->gid, dc->ngroups);
348 for (i = 0; i < dc->ngroups; i++)
349 printf("\t%d\n", dc->groups[i]);
351 printf("nperms: %d\n", dc->nperms);
352 for (i = 0; i < dc->nperms; i++)
353 printf("\t: netid %u, nid "LPX64", bits %x\n", i,
354 dc->perms[i].nid, dc->perms[i].perm);
357 #define log_msg(testing, fmt, args...) \
360 printf(fmt, ## args); \
362 syslog(LOG_ERR, fmt, ## args); \
365 void usage(char *prog)
367 printf("Usage: %s [-t] uid\n", prog);
371 int main (int argc, char **argv)
373 char *dc_name = "/proc/fs/lustre/mds/lsd_downcall";
375 char *conf_name = "/etc/lustre/lsd.conf";
377 struct lsd_downcall_args ioc_data;
379 int opt, testing = 0, rc;
381 while ((opt = getopt(argc, argv, "t")) != -1) {
394 memset(&ioc_data, 0, sizeof(ioc_data));
395 ioc_data.uid = atoi(argv[optind]);
397 /* read user/group database */
398 ioc_data.err = get_groups_local(ioc_data.uid, &ioc_data.gid,
399 (int *)&ioc_data.ngroups,
404 /* read lsd config database */
405 conf_fp = fopen(conf_name, "r");
407 get_perms(conf_fp, ioc_data.uid,
408 (int *)&ioc_data.nperms,
415 show_result(&ioc_data);
418 dc_fd = open(dc_name, O_WRONLY);
420 log_msg(testing, "can't open device %s: %s\n",
421 dc_name, strerror(errno));
426 rc = write(dc_fd, &ioc_data, sizeof(ioc_data));
427 if (rc != sizeof(ioc_data)) {
428 log_msg(testing, "partial write ret %d: %s\n",
429 rc, strerror(errno));