debug_winbindd.sh: add "n" to ps options to avoid name translation
[slow/toolbox.git] / gpfsacl.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdarg.h>
5 #include <stdbool.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <dirent.h>
10 #include <sys/types.h>
11
12 #include <gpfs.h>
13
14 #define ERR_USAGE       1
15 #define ERR_SYSCALL     2
16 #define ERR_CALL        3
17 #define ERR_FATAL       4
18
19 #define ERROR(err, fmt, ...)                                            \
20         do {                                                            \
21                 do_log(__FILE__, __LINE__, __FUNCTION__, (fmt), __VA_ARGS__); \
22                 exit(err);                                              \
23         } while (0)
24
25 #define LOG(fmt, ...)                                                   \
26         do {                                                            \
27                 do_log(__FILE__, __LINE__, __FUNCTION__, (fmt), __VA_ARGS__); \
28         } while (0)
29
30 #define FREE(p)                         \
31         do {                            \
32                 free(p);                \
33                 p = 0;                  \
34         } while (0)
35
36 static void do_log(const char *file, int line, const char *func, const char *fmt, ...)
37 {
38         char *message;
39         va_list args;
40         int len;
41
42         va_start(args, fmt);
43         len = vasprintf(&message, fmt, args);
44         va_end(args);
45         if (len == -1) {
46                 exit(ERR_FATAL);
47         }
48
49         printf("%s:%d(%s): %s\n", file, line, func, message);
50         free(message);
51 }
52
53 static void print_acl(gpfs_acl_t *acl)
54 {
55         bool have_v4_flags = acl->acl_level == GPFS_ACL_LEVEL_V4FLAGS ? true : false;
56         int aces_offset = have_v4_flags ? sizeof(unsigned int) : 0;
57         int v4_flags = have_v4_flags ? acl->v4Level1.acl_flags : 0;
58         gpfs_ace_v4_t *ace = NULL;
59         int i;
60
61         printf("ACL: acl_level [%d] acl_version [%d] acl_type [%d] flags [%08x]\n",
62                acl->acl_level, acl->acl_version, acl->acl_type, v4_flags);
63
64         if (!have_v4_flags) {
65                 ace = acl->ace_v4;
66         } else {
67                 ace = acl->v4Level1.ace_v4;
68         }
69
70         for (i = 0; i < acl->acl_nace; i++, ace++) {
71                 printf("%d: aceType [%d] aceFlags [%08x] aceIFlags [%08x] aceMask [%08x] aceWho [%u]\n",
72                        i, ace->aceType, ace->aceFlags, ace->aceIFlags, ace->aceMask, ace->aceWho);
73         }
74 }
75
76 static void set_dacl_prot_fn(const char *path, gpfs_acl_t *acl, bool set)
77 {
78         int result;
79
80         if (acl->acl_level != GPFS_ACL_LEVEL_V4FLAGS) {
81                 ERROR(ERR_CALL, "acl_level != GPFS_ACL_LEVEL_V4FLAGS [%d]\n", acl->acl_level);
82         }
83
84         if (set) {
85                 acl->v4Level1.acl_flags |= ACL4_FLAG_DACL_PROTECTED;
86         } else {
87                 acl->v4Level1.acl_flags &= ~ACL4_FLAG_DACL_PROTECTED;
88         }
89
90         result = gpfs_putacl(path, GPFS_PUTACL_STRUCT, acl);
91         if (result != 0) {
92                 ERROR(ERR_SYSCALL, "gpfs_getacl: %s\n", strerror(errno));
93         }
94 }
95
96 static void show_usage(const char *path)
97 {
98         printf("usage: %s [-dD4] PATH\n\n"
99                "       -p set ACL4_FLAG_DACL_PROTECTED\n"
100                "       -P remove ACL4_FLAG_DACL_PROTECTED\n"
101                "       -4 don't request GPFS_ACL_LEVEL_V4FLAGS\n",
102                path);
103         exit(1);
104 }
105
106 int main(int argc, char **argv)
107 {
108         const char *path = NULL;
109         gpfs_acl_t *acl = NULL;
110         int result;
111         int opt;
112         bool set_dacl_prot = false;
113         bool remove_dacl_prot = false;
114         bool set_level_v4flags = true;
115
116         while ((opt = getopt(argc, argv, "pP4")) != -1) {
117                 switch(opt) {
118                 case 'p':
119                         set_dacl_prot = true;
120                         break;
121                 case 'P':
122                         remove_dacl_prot = true;
123                         break;
124                 case '4':
125                         set_level_v4flags = false;
126                         break;
127                 default:
128                         show_usage(argv[0]);
129                 }
130         }
131
132         if ((optind + 1) != argc) {
133                 show_usage(argv[0]);
134         }
135
136         path = argv[optind];
137
138         acl = malloc(1024);
139
140         acl->acl_len = 1024;
141         acl->acl_level = set_level_v4flags ? GPFS_ACL_LEVEL_V4FLAGS : GPFS_ACL_LEVEL_BASE;
142         acl->acl_version = 0;
143         acl->acl_type = 0;
144
145         result = gpfs_getacl(path, GPFS_GETACL_STRUCT, acl);
146         if (result != 0) {
147                 ERROR(ERR_SYSCALL, "gpfs_getacl: %s\n", strerror(errno));
148         }
149
150         if (acl->acl_type != GPFS_ACL_TYPE_NFS4) {
151                 ERROR(ERR_CALL, "expected GPFS_ACL_TYPE_NFS4 got [%d]\n",
152                         acl->acl_type);
153         }
154
155         print_acl(acl);
156
157         if (set_dacl_prot) {
158                 printf("Setting ACL4_FLAG_DACL_PROTECTED\n");
159                 set_dacl_prot_fn(path, acl, true);
160         }
161
162         if (remove_dacl_prot) {
163                 printf("Removing ACL4_FLAG_DACL_PROTECTED\n");
164                 set_dacl_prot_fn(path, acl, false);
165         }
166
167         return 0;
168 }