readgroup: Make sure user supplies a groupfile
[openafs.git] / src / ptserver / readgroup.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14 #include <afs/opr.h>
15
16 #ifdef AFS_NT40_ENV
17 #include <WINNT/afsevent.h>
18 #endif
19 #include <ctype.h>
20
21 #include <rx/rx.h>
22 #include <rx/xdr.h>
23 #include <afs/cellconfig.h>
24 #include <afs/afsutil.h>
25 #include <afs/com_err.h>
26
27 #include "ptclient.h"
28 #include "ptuser.h"
29 #include "pterror.h"
30 #include "ptprototypes.h"
31
32 int verbose = 0;
33 static void skip(char **);
34
35 void
36 report_error(afs_int32 code, char *name, char *gname)
37 {
38     if (code == 0) {
39         if (verbose)
40             printf("  added %s to %s.\n", name, gname);
41     } else if (code == PRIDEXIST) {
42         if (verbose)
43             printf("  user %s already on group %s\n", name, gname);
44     } else {
45         fprintf(stderr, "Couldn't add %s to %s!\n", name, gname);
46         fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code), code);
47     }
48 }
49
50 int
51 osi_audit(void)
52 {
53 /* OK, this REALLY sucks bigtime, but I can't tell who is calling
54  * afsconf_CheckAuth easily, and only *SERVERS* should be calling osi_audit
55  * anyway.  It's gonna give somebody fits to debug, I know, I know.
56  */
57     return 0;
58 }
59
60 #include "AFS_component_version_number.c"
61
62 int
63 main(int argc, char **argv)
64 {
65     afs_int32 code;
66     char name[PR_MAXNAMELEN];
67     char gname[PR_MAXNAMELEN];
68     char owner[PR_MAXNAMELEN];
69     afs_int32 id;
70     char buf[3000];
71     FILE *fp;
72     char *ptr;
73     char *tmp;
74     char *cellname;
75     namelist lnames;
76     afs_int32 i;
77     afs_int32 fail = 0;
78
79     buf[0] = '\0';
80
81     if (argc < 2) {
82         fprintf(stderr, "Usage: readgroup [-v] [-c cellname] groupfile.\n");
83         exit(0);
84     }
85     cellname = 0;
86     for (i = 1; i < argc; i++) {
87         if (!strcmp(argv[i], "-v"))
88             verbose = 1;
89         else {
90             if (!strcmp(argv[i], "-c")) {
91                 cellname = malloc(100);
92                 strncpy(cellname, argv[++i], 100);
93             } else
94                 strncpy(buf, argv[i], 150);
95         }
96     }
97
98     /* Catch missing filename */
99     if (buf[0] == '\0') {
100         fprintf(stderr, "Usage: readgroup [-v] [-c cellname] groupfile.\n");
101         exit(0);
102     }
103
104     code = pr_Initialize(2, AFSDIR_CLIENT_ETC_DIRPATH, cellname);
105     free(cellname);
106     if (code) {
107         fprintf(stderr, "pr_Initialize failed .. exiting.\n");
108         fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code), code);
109         exit(1);
110     }
111
112     if ((fp = fopen(buf, "r")) == NULL) {
113         fprintf(stderr, "Couldn't open %s.\n", argv[1]);
114         exit(1);
115     }
116
117     while ((tmp = fgets(buf, 3000, fp)) != NULL) {
118         /* group file lines must either have the name of a group or a tab or blank space at beginning */
119         if (buf[0] == '\n')
120             break;
121         if (buf[0] != ' ' && buf[0] != '\t') {
122             /* grab the group name */
123             memset(gname, 0, PR_MAXNAMELEN);
124             memset(owner, 0, PR_MAXNAMELEN);
125             sscanf(buf, "%s %d", gname, &id);
126             tmp = buf;
127             skip(&tmp);
128             skip(&tmp);
129             stolower(gname);
130             ptr = strchr(gname, ':');
131             strncpy(owner, gname, ptr - gname);
132             if (strcmp(owner, "system") == 0)
133                 strncpy(owner, "system:administrators", PR_MAXNAMELEN);
134             fail = 0;
135             if (verbose)
136                 printf("Group is %s, owner is %s, id is %d.\n", gname, owner,
137                        id);
138             code = pr_CreateGroup(gname, owner, &id);
139             if (code != 0) {
140                 if (code != PRIDEXIST) {        /* already exists */
141                     fprintf(stderr, "Failed to create group %s with id %d!\n",
142                             gname, id);
143                     fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code), code);
144                 }
145                 if (code != PREXIST && code != PRIDEXIST) {     /* we won't add users if it's not there */
146                     fail = 1;
147                 }
148             }
149             if (!fail) {
150                 /* read members out of buf and add to the group */
151                 memset(name, 0, PR_MAXNAMELEN);
152                 while (sscanf(tmp, "%s", name) != EOF) {
153                     if (strchr(name, ':') == NULL) {
154                         /* then it's not a group */
155                         code = pr_AddToGroup(name, gname);
156                         report_error(code, name, gname);
157                     } else {
158                         /* add the members of a group to the group */
159                         if (verbose)
160                             printf("Adding %s to %s.\n", name, gname);
161                         code = pr_ListMembers(name, &lnames);
162                         if (code) {
163                             fprintf(stderr,
164                                     "Couldn't get the members for %s to add to %s.\n",
165                                     name, gname);
166                             fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code),
167                                     code);
168                         } else {
169                             for (i = 0; i < lnames.namelist_len; i++) {
170                                 code =
171                                     pr_AddToGroup(lnames.namelist_val[i], gname);
172                                 report_error(code, lnames.namelist_val[i], gname);
173                             }
174                             if (lnames.namelist_val)
175                                 free(lnames.namelist_val);
176                         }
177                     }
178                     memset(name, 0, PR_MAXNAMELEN);
179                     skip(&tmp);
180                 }
181             }
182         } else {                /* must have more names to add */
183             /* if we couldn't create the group, and it wasn't already there, don't try to add more users */
184             if (fail)
185                 continue;
186             /* read members out of buf and add to the group */
187             memset(name, 0, PR_MAXNAMELEN);
188             tmp = buf;
189             tmp++;
190             while (sscanf(tmp, "%s", name) != EOF) {
191                 if (strchr(name, ':') == NULL) {
192                     /* then it's not a group */
193                     code = pr_AddToGroup(name, gname);
194                     report_error(code, name, gname);
195                 } else {
196                     /* add the members of a group to the group */
197                     code = pr_ListMembers(name, &lnames);
198                     if (code) {
199                         fprintf(stderr,
200                                 "Couldn't get the members for %s to add to %s.\n",
201                                 name, gname);
202                         fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code),
203                                 code);
204                     } else {
205                         for (i = 0; i < lnames.namelist_len; i++) {
206                             if (verbose)
207                                 printf("Adding %s to %s.\n",
208                                        lnames.namelist_val[i], gname);
209                             code = pr_AddToGroup(lnames.namelist_val[i], gname);
210                             report_error(code, lnames.namelist_val[i], gname);
211                         }
212                         if (lnames.namelist_val)
213                             free(lnames.namelist_val);
214                     }
215                 }
216                 memset(name, 0, PR_MAXNAMELEN);
217                 skip(&tmp);
218             }
219         }
220     }
221     return 0;
222 }
223
224 static void
225 skip(char **s)
226 {
227     while (**s != ' ' && **s != '\t' && **s != '\0')
228         (*s)++;
229     while (**s == ' ' || **s == '\t')
230         (*s)++;
231 }