source: main/trunk/package-kits/scripts/gs-mkdir/gs-mkdir.c@ 29703

Last change on this file since 29703 was 29703, checked in by Jeremy Symon, 9 years ago

Fixed error message for invalid username

File size: 6.4 KB
RevLine 
[29701]1#include <stdlib.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <pwd.h>
5#include <string.h>
6#include <errno.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <sys/acl.h>
10#include <acl/libacl.h>
11
12#define GREENSTONE_DIR "/Greenstone"
13// #define DEBUG
14
15static acl_entry_t
16find_entry(
17 acl_t acl,
18 acl_tag_t type,
19 id_t id)
20{
21 acl_entry_t ent;
22 acl_tag_t e_type;
23 id_t *e_id_p;
24
25 if (acl_get_entry(acl, ACL_FIRST_ENTRY, &ent) != 1)
26 return NULL;
27
28 for(;;) {
29 acl_get_tag_type(ent, &e_type);
30 if (type == e_type) {
31 if (id != ACL_UNDEFINED_ID) {
32 e_id_p = acl_get_qualifier(ent);
33 if (e_id_p == NULL)
34 return NULL;
35 if (*e_id_p == id) {
36 acl_free(e_id_p);
37 return ent;
38 }
39 acl_free(e_id_p);
40 } else {
41 return ent;
42 }
43 }
44 if (acl_get_entry(acl, ACL_NEXT_ENTRY, &ent) != 1)
45 return NULL;
46 }
47}
48
49static int
50clone_entry(
51 acl_t from_acl,
52 acl_tag_t from_type,
53 acl_t *to_acl,
54 acl_tag_t to_type)
55{
56 acl_entry_t from_entry, to_entry;
57 from_entry = find_entry(from_acl, from_type, ACL_UNDEFINED_ID);
58 if (from_entry) {
59 if (acl_create_entry(to_acl, &to_entry) != 0)
60 return -1;
61 acl_copy_entry(to_entry, from_entry);
62 acl_set_tag_type(to_entry, to_type);
63 return 0;
64 } else {
65 return 1;
66 }
67}
68
69static int set_perms (acl_t *acl, int type, int uid, int perms) {
70 acl_entry_t entry = find_entry (*acl, type, uid);
71 if (!entry) {
72 if (acl_create_entry(acl, &entry)) {
73 perror ("acl_create_entry");
74 return 1;
75 }
76 acl_set_tag_type(entry, type);
77 acl_set_qualifier(entry, &uid);
78 }
79 acl_permset_t set;
80 acl_get_permset(entry, &set);
81
82 if (perms & 4) {
83 acl_add_perm(set, ACL_READ);
84 } else {
85 acl_delete_perm(set, ACL_READ);
86 }
87 if (perms & 2) {
88 acl_add_perm(set, ACL_WRITE);
89 } else {
90 acl_delete_perm(set, ACL_WRITE);
91 }
92 if (perms & 1) {
93 acl_add_perm(set, ACL_EXECUTE);
94 } else {
95 acl_delete_perm(set, ACL_EXECUTE);
96 }
97 return 0;
98}
99
100static int check_acl (acl_t *acl) {
101#ifdef DEBUG
102 int which_entry;
103 int error;
104 if ((error = acl_check(*acl, &which_entry))) {
105 if (error > 0) {
106 fprintf (stderr,
107 "Malformed ACL '%s': %s at entry %d\n",
108 acl_to_any_text(*acl, NULL, ',', 0),
109 acl_error(error), which_entry + 1
110 );
111 }
112#else
113 if (acl_check(*acl, NULL)) {
114 perror ("acl_check");
115#endif
116 return 1;
117 }
118 return 0;
119}
120
121static int set_acl (char *fpath, int user_uid, int greenstone_gid) {
122 acl_t default_acl = acl_get_file (fpath, ACL_TYPE_DEFAULT);
123 acl_t acl = acl_get_file (fpath, ACL_TYPE_ACCESS);
124 if (!default_acl || !acl) {
125 perror (fpath);
126 return 1;
127 }
128 int error = 0;
129
130 set_perms (&default_acl, ACL_USER, user_uid, 07);
131 set_perms (&acl, ACL_USER, user_uid, 07);
132 set_perms (&default_acl, ACL_GROUP, greenstone_gid, 07);
133 set_perms (&acl, ACL_GROUP, greenstone_gid, 07);
134
135 /* Try to fill in missing entries */
136 if (!find_entry(default_acl, ACL_USER_OBJ, ACL_UNDEFINED_ID)) {
137 clone_entry(acl, ACL_USER_OBJ, &default_acl, ACL_USER_OBJ);
138 }
139 if (!find_entry(default_acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) {
140 clone_entry(acl, ACL_GROUP_OBJ, &default_acl, ACL_GROUP_OBJ);
141 }
142 if (!find_entry(default_acl, ACL_OTHER, ACL_UNDEFINED_ID)) {
143 clone_entry(acl, ACL_OTHER, &default_acl, ACL_OTHER);
144 }
145
146 if (acl_equiv_mode (acl, NULL) != 0) {
147 if (!find_entry (acl, ACL_MASK, ACL_UNDEFINED_ID)) {
148 clone_entry (acl, ACL_GROUP_OBJ, &acl, ACL_MASK);
149 }
150 acl_calc_mask(&acl);
151 }
152 if (acl_equiv_mode (default_acl, NULL) != 0) {
153 if (!find_entry (default_acl, ACL_MASK, ACL_UNDEFINED_ID)) {
154 clone_entry (default_acl, ACL_GROUP_OBJ, &default_acl, ACL_MASK);
155 }
156 acl_calc_mask(&default_acl);
157 }
158
159 if (check_acl (&acl) || check_acl (&default_acl)) {
160 goto acl_error;
161 }
162
163 if (acl_set_file (fpath, ACL_TYPE_DEFAULT, default_acl) ||
164 acl_set_file (fpath, ACL_TYPE_ACCESS, acl)) {
165 perror ("acl_set_file");
166 goto acl_error;
167 }
168
169acl_cleanup:
170 if (acl_free (acl) || acl_free (default_acl)) {
171 perror ("acl_free");
172 }
173 return error;
174acl_error:
175 error = 1;
176 goto acl_cleanup;
177}
178
179
180int main(int argc, char **argv) {
181 if (argc < 2) {
182 fprintf (stderr, "Usage: gs-mkdir <username> [...]\n");
183 return 1;
184 }
185 int greenstone_gid;
186 {
187 struct stat greenstone_user;
188 if (stat (argv[0], &greenstone_user)) {
189 perror (argv[0]);
190 return 1;
191 }
192 greenstone_gid = greenstone_user.st_gid;
193 }
194
195 int i;
196 for (i = 1; i < argc; i++) {
197 /* Ensure the user exists */
198 struct passwd *user = getpwnam(argv[i]);
199 if (!user) {
[29703]200 fprintf (stderr, "User '%s' does not exist\n", argv[i]);
[29701]201 return 1;
202 }
203
204 char *path = user->pw_dir;
205 struct stat st;
206 /* Ensure the user home folder exists */
207 if (stat (path, &st)) {
208 perror (path);
209 return 1;
210 }
211 int path_len = strlen (path);
212 char *full_path = malloc (path_len + strlen (GREENSTONE_DIR) + 1);
213 memcpy (full_path, path, path_len);
214 memcpy (full_path + path_len, GREENSTONE_DIR, strlen (GREENSTONE_DIR));
215 full_path[path_len + strlen (GREENSTONE_DIR)] = 0;
216
217 /* Check if the user's greenstone folder exists */
218 if (stat (full_path, &st)) {
219 if (errno == ENOENT) {
220 /* Create the folder as it doesn't exist */
221 if (mkdir (full_path, 0770)) {
222 perror (full_path);
223 return 1;
224 }
225 chown (full_path, user->pw_uid, user->pw_gid);
226
227 if (set_acl (full_path, user->pw_uid, greenstone_gid)) {
228 return 1;
229 }
230 } else {
231 /* Something went wrong */
232 perror (full_path);
233 return 1;
234 }
235 }
236
237 puts (full_path);
238 free (full_path);
239 }
240 return 0;
241}
Note: See TracBrowser for help on using the repository browser.