ptserver-warning-cleanup-20011005
[openafs.git] / src / ptserver / ptuser.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 #if defined(UKERNEL)
12 #include "../afs/param.h"
13 #else
14 #include <afs/param.h>
15 #endif
16
17 RCSID("$Header$");
18
19 #if defined(UKERNEL)
20 #include "../afs/sysincludes.h"
21 #include "../afs/afs_usrops.h"
22 #include "../afs/afsincludes.h"
23 #include "../afs/stds.h"
24 #include "../rx/rx.h"
25 #include "../rx/xdr.h"
26 #include "../rx/rxkad.h"
27 #include "../afs/auth.h"
28 #include "../afs/cellconfig.h"
29 #include "../afs/afsutil.h"
30 #include "../afs/ptclient.h"
31 #include "../afs/pterror.h"
32 #else /* defined(UKERNEL) */
33 #include <afs/stds.h>
34 #include <ctype.h>
35 #include <sys/types.h>
36 #ifdef AFS_NT40_ENV 
37 #include <winsock2.h>
38 #else
39 #include <netinet/in.h>
40 #endif
41 #include <stdio.h>
42 #ifdef HAVE_STRING_H
43 #include <string.h>
44 #else
45 #ifdef HAVE_STRINGS_H
46 #include <strings.h>
47 #endif
48 #endif
49 #include <rx/rx.h>
50 #include <rx/xdr.h>
51 #include <rx/rxkad.h>
52 #include <afs/auth.h>
53 #include <afs/cellconfig.h>
54 #include <afs/afsutil.h>
55 #include "ptclient.h"
56 #include "pterror.h"
57 #endif /* defined(UKERNEL) */
58
59
60 struct ubik_client *pruclient = 0;
61 static afs_int32 lastLevel;                     /* security level pruclient, if any */
62
63 static char *whoami = "libprot";
64
65 afs_int32 pr_Initialize (secLevel, confDir, cell)
66   IN afs_int32 secLevel;
67   IN char *confDir;
68   IN char *cell;
69 {
70     afs_int32 code;
71     struct rx_connection *serverconns[MAXSERVERS];
72     struct rx_securityClass *sc[3];
73     static struct afsconf_dir *tdir = 0; /* only do this once */
74     static char tconfDir[100];
75     struct ktc_token ttoken;
76     afs_int32 scIndex;
77     static struct afsconf_cell info;
78     afs_int32 i;
79     char cellstr[64];
80
81     initialize_PT_error_table();
82     initialize_RXK_error_table();
83     initialize_ACFG_error_table();
84     initialize_KTC_error_table();
85
86     if (strcmp(confDir, tconfDir)) {
87         /*
88          * Different conf dir; force re-evaluation.
89          */
90         tdir = (struct afsconf_dir *)0;
91         pruclient = (struct ubik_client *)0;
92     }
93     if (tdir == 0) {
94         strncpy(tconfDir, confDir, sizeof(tconfDir));
95 #if defined(UKERNEL)
96         tdir = afs_cdir;
97         if (!cell) {
98             cell = afs_LclCellName;
99         }
100 #else /* defined(UKERNEL) */  
101         tdir = afsconf_Open(confDir);
102         if (!tdir) {
103             fprintf(stderr,
104                     "libprot: Could not open configuration directory: %s.\n",
105                     confDir);
106             return -1;
107         }
108
109         if (!cell) {
110            code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
111            if (code) {
112               fprintf(stderr,
113                       "vos: can't get local cell name - check %s/%s\n",
114                       confDir, AFSDIR_THISCELL_FILE);
115               exit(1);
116            }
117            cell = cellstr;
118         }
119 #endif /* defined(UKERNEL) */  
120
121         code = afsconf_GetCellInfo(tdir,cell,"afsprot",&info);
122         if (code) {
123             fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n",
124                     cell, confDir, AFSDIR_CELLSERVDB_FILE);
125             return code;
126         }
127     }
128
129     /* If we already have a client and it is at the security level we
130      * want, don't get a new one. Unless the security level is 2 in
131      * which case we will get one (and re-read the key file).
132      */
133     if (pruclient && (lastLevel == secLevel) && (secLevel != 2))
134        return 0;
135     
136     code = rx_Init(0);
137     if (code) {
138         fprintf(stderr,"libprot:  Could not initialize rx.\n");
139         return code;
140     }
141
142     scIndex = secLevel;
143     sc[0] = 0;
144     sc[1] = 0;
145     sc[2] = 0;
146     /* Most callers use secLevel==1, however, the fileserver uses secLevel==2
147      * to force use of the KeyFile.  secLevel == 0 implies -noauth was
148      * specified. */
149     if ((secLevel == 2) && (afsconf_GetLatestKey (tdir, 0,0) == 0)) {
150         /* If secLevel is two assume we're on a file server and use
151          * ClientAuthSecure if possible. */
152         code = afsconf_ClientAuthSecure (tdir, &sc[2], &scIndex);
153         if (code) scIndex = 0;          /* use noauth */
154         if (scIndex != 2)
155             /* if there was a problem, an unauthenticated conn is returned */
156             sc[scIndex] = sc[2];
157     }
158     else if (secLevel > 0) {
159         struct ktc_principal sname;
160         strcpy(sname.cell,info.name);
161         sname.instance[0] = 0;
162         strcpy(sname.name, "afs");
163         code = ktc_GetToken(&sname,&ttoken, sizeof(ttoken), (char *)0);
164         if (code) scIndex = 0;
165         else {
166             if (ttoken.kvno >= 0 && ttoken.kvno <= 255)
167                 /* this is a kerberos ticket, set scIndex accordingly */
168                 scIndex = 2;
169             else {
170                 fprintf (stderr,
171                          "libprot: funny kvno (%d) in ticket, proceeding\n",
172                          ttoken.kvno);
173                 scIndex = 2;
174             }
175             sc[2] = (struct rx_securityClass *) rxkad_NewClientSecurityObject
176                 (rxkad_clear, &ttoken.sessionKey, ttoken.kvno,
177                  ttoken.ticketLen, ttoken.ticket);
178         }
179     }
180     if (scIndex == 1) return PRBADARG;
181     if ((scIndex == 0) && (sc[0] == 0))
182         sc[0] = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
183     if ((scIndex == 0) && (secLevel != 0))
184         com_err (whoami, code,
185                  "Could not get afs tokens, running unauthenticated.");
186
187     memset(serverconns, 0, sizeof(serverconns)); /* terminate list!!! */
188     for (i = 0;i<info.numServers;i++) 
189         serverconns[i] = rx_NewConnection
190             (info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
191              PRSRV, sc[scIndex], scIndex);
192
193     code = ubik_ClientInit(serverconns, &pruclient);
194     if (code) {
195         com_err (whoami, code, "ubik client init failed.");
196         return code;
197     }
198     lastLevel = scIndex;
199
200     code = rxs_Release (sc[scIndex]);
201     return code;
202 }
203
204
205 pr_End()
206 {
207    int code = 0;
208
209     if (pruclient) {
210         code = ubik_ClientDestroy (pruclient);
211         pruclient = 0;
212     }
213    return code;
214 }
215
216
217
218 pr_CreateUser(name,id)
219 char name[PR_MAXNAMELEN];
220 afs_int32 *id;
221 {
222     register afs_int32 code;
223
224     stolower(name);
225     if (*id) {
226         code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,0);
227         return code;
228     }
229     else {
230         code = ubik_Call(PR_NewEntry, pruclient, 0, name,0,0,id);
231         return code;
232     }
233     
234 }
235
236 pr_CreateGroup(name,owner, id)
237 char name[PR_MAXNAMELEN];
238 char owner[PR_MAXNAMELEN];
239 afs_int32 *id;
240 {
241     register afs_int32 code;
242     afs_int32 oid = 0;
243     afs_int32 flags = 0;
244     
245     stolower(name);
246     if (owner) {
247         code = pr_SNameToId(owner,&oid);
248         if (code) return code;
249         if (oid == ANONYMOUSID) return PRNOENT;
250     }
251     flags |= PRGRP;
252     if (*id) {
253         code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,oid);
254         return code;
255     }
256     else {
257         code = ubik_Call(PR_NewEntry,pruclient, 0, name,flags,oid,id);
258         return code;
259     }
260 }
261
262 pr_Delete(name)
263 char *name;
264 {
265     register afs_int32 code;
266     afs_int32 id;
267     
268     stolower(name);
269     code = pr_SNameToId(name,&id);
270     if (code) return code;
271     if (id == ANONYMOUSID) return PRNOENT;
272     code = ubik_Call(PR_Delete,pruclient,0,id);
273     return code;
274 }
275
276 pr_DeleteByID(id)
277 afs_int32 id;
278 {
279     register afs_int32 code;
280
281     code = ubik_Call(PR_Delete,pruclient,0,id);
282     return code;
283 }
284
285 pr_AddToGroup(user,group)
286 char *user;
287 char *group;
288 {
289     register afs_int32 code;
290     namelist lnames;
291     idlist lids;
292
293     lnames.namelist_len = 2;
294     lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
295     strncpy(lnames.namelist_val[0],user,PR_MAXNAMELEN);
296     strncpy(lnames.namelist_val[1],group,PR_MAXNAMELEN);
297     lids.idlist_val = 0;
298     lids.idlist_len = 0;
299     code = pr_NameToId(&lnames,&lids);
300     if (code) goto done;
301     /* if here, still could be missing an entry */
302     if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
303         code = PRNOENT;
304         goto done;
305     }
306     code = ubik_Call(PR_AddToGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
307   done:
308     if (lnames.namelist_val) free(lnames.namelist_val);
309     if (lids.idlist_val) free(lids.idlist_val);
310     return code;
311 }
312
313 pr_RemoveUserFromGroup(user,group)
314 char *user;
315 char *group;
316 {
317     register afs_int32 code;
318     namelist lnames;
319     idlist lids;
320
321     lnames.namelist_len = 2;
322     lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
323     strncpy(lnames.namelist_val[0],user,PR_MAXNAMELEN);
324     strncpy(lnames.namelist_val[1],group,PR_MAXNAMELEN);
325     lids.idlist_val = 0;
326     lids.idlist_len = 0;
327     code = pr_NameToId(&lnames,&lids);
328     if (code) goto done;
329
330     if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
331         code = PRNOENT;
332         goto done;
333     }
334     code = ubik_Call(PR_RemoveFromGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
335 done:
336     if (lnames.namelist_val) free(lnames.namelist_val);
337     if (lids.idlist_val) free(lids.idlist_val);
338     return code;
339
340 }
341
342 pr_NameToId(names, ids)
343 namelist *names;
344 idlist *ids;
345 {
346     register afs_int32 code;
347     register afs_int32 i;
348
349     for (i=0;i<names->namelist_len;i++)
350         stolower(names->namelist_val[i]);
351     code = ubik_Call(PR_NameToID,pruclient,0,names,ids);
352     return code;
353 }
354
355 pr_SNameToId(name,id)
356 char name[PR_MAXNAMELEN];
357 afs_int32 *id;
358 {
359     namelist lnames;
360     idlist lids;
361     register afs_int32 code;
362
363     lids.idlist_len = 0;
364     lids.idlist_val = 0;
365     lnames.namelist_len = 1;
366     lnames.namelist_val = (prname *)malloc(PR_MAXNAMELEN);
367     stolower(name);
368     strncpy(lnames.namelist_val[0],name,PR_MAXNAMELEN);
369     code = ubik_Call(PR_NameToID,pruclient,0,&lnames,&lids);
370     if (lids.idlist_val) {
371         *id = *lids.idlist_val;
372         free(lids.idlist_val);
373     }
374     if (lnames.namelist_val) free(lnames.namelist_val);
375     return code;
376 }
377     
378
379
380 pr_IdToName(ids,names)
381 idlist *ids;
382 namelist *names;
383 {
384     register afs_int32 code;
385
386     code = ubik_Call(PR_IDToName,pruclient,0,ids,names);
387     return code;
388 }
389
390 pr_SIdToName(id,name)
391 afs_int32 id;
392 char name[PR_MAXNAMELEN];
393 {
394     namelist lnames;
395     idlist lids;
396     register afs_int32 code;
397
398     lids.idlist_len = 1;
399     lids.idlist_val = (afs_int32 *)malloc(sizeof(afs_int32));
400     *lids.idlist_val = id;
401     lnames.namelist_len = 0;
402     lnames.namelist_val = 0;
403     code = ubik_Call(PR_IDToName,pruclient,0,&lids,&lnames);
404     if (lnames.namelist_val) {
405         strncpy(name,lnames.namelist_val[0],PR_MAXNAMELEN);
406         free(lnames.namelist_val);
407     }
408     if (lids.idlist_val) free(lids.idlist_val);
409     return code;
410 }
411     
412         
413
414 pr_GetCPS(id, CPS)
415 afs_int32 id;
416 prlist *CPS;
417 {
418     register afs_int32 code;
419     afs_int32 over;
420
421     over = 0;
422     code = ubik_Call(PR_GetCPS,pruclient,0,id,CPS,&over);
423     if (code != PRSUCCESS) return code;
424     if (over) {
425         /* do something about this, probably make a new call */
426         /* don't forget there's a hard limit in the interface */
427         fprintf (stderr, "membership list for id %d exceeds display limit\n", id);
428     }
429     return 0;
430 }
431
432
433 pr_GetCPS2(id, host, CPS)
434     afs_int32 id;
435     afs_int32 host;
436     prlist *CPS;
437 {
438     register afs_int32 code;
439     afs_int32 over;
440
441     over = 0;
442     code = ubik_Call(PR_GetCPS2,pruclient,0,id,host,CPS,&over);
443     if (code != PRSUCCESS) return code;
444     if (over) {
445         /* do something about this, probably make a new call */
446         /* don't forget there's a hard limit in the interface */
447         fprintf (stderr, "membership list for id %d exceeds display limit\n", id);
448     }
449     return 0;
450 }
451
452 pr_GetHostCPS(host, CPS)
453     afs_int32 host;
454     prlist *CPS;
455 {
456     register afs_int32 code;
457     afs_int32 over;
458
459     over = 0;
460     code = ubik_Call(PR_GetHostCPS,pruclient,0,host,CPS,&over);
461     if (code != PRSUCCESS) return code;
462     if (over) {
463         /* do something about this, probably make a new call */
464         /* don't forget there's a hard limit in the interface */
465         fprintf (stderr, "membership list for host id %d exceeds display limit\n", host);
466     }
467     return 0;
468 }
469
470
471 pr_ListMembers(group,lnames)
472 char *group;
473 namelist *lnames;
474 {
475     register afs_int32 code;
476     afs_int32 gid;
477
478     code = pr_SNameToId(group,&gid);
479     if (code) return code;
480     if (gid == ANONYMOUSID) return PRNOENT;
481     code = pr_IDListMembers(gid, lnames);
482     return code;
483 }
484
485 pr_ListOwned (oid,lnames,moreP)
486   afs_int32 oid;
487   namelist *lnames;
488   afs_int32 *moreP;
489 {
490     register afs_int32 code;
491     prlist alist;
492     idlist *lids;
493
494     alist.prlist_len = 0;
495     alist.prlist_val = 0;
496     code = ubik_Call(PR_ListOwned,pruclient,0,oid,&alist,moreP);
497     if (code) return code;
498     if (*moreP == 1) {
499       /* Remain backwards compatible when moreP was a T/F bit */
500       fprintf (stderr, "membership list for id %d exceeds display limit\n",
501                oid);
502       *moreP = 0;
503     }
504     lids = (idlist *)&alist;
505     code = pr_IdToName(lids,lnames);
506     if (code) return code;
507     if (alist.prlist_val) free(alist.prlist_val);
508     return PRSUCCESS;
509 }
510
511 pr_IDListMembers(gid,lnames)
512 afs_int32 gid;
513 namelist *lnames;
514 {
515     register afs_int32 code;
516     prlist alist;
517     idlist *lids;
518     afs_int32 over;
519
520     alist.prlist_len = 0;
521     alist.prlist_val = 0;
522     code = ubik_Call(PR_ListElements,pruclient,0,gid,&alist,&over);
523     if (code) return code;
524     if (over) {
525        fprintf (stderr, "membership list for id %d exceeds display limit\n", gid);
526     }
527     lids = (idlist *)&alist;
528     code = pr_IdToName(lids,lnames);
529     if (code) return code;
530     if (alist.prlist_val) free(alist.prlist_val);
531     return PRSUCCESS;
532 }
533
534
535 pr_ListEntry(id, aentry)
536   afs_int32 id;
537   struct prcheckentry *aentry;
538 {
539     register afs_int32 code;
540
541     code = ubik_Call (PR_ListEntry, pruclient, 0, id, aentry);
542     return code;
543 }
544
545 afs_int32 pr_ListEntries(flag, startindex, nentries, entries, nextstartindex)
546   afs_int32                startindex;
547   afs_int32                *nentries;
548   struct prlistentries **entries;
549   afs_int32                *nextstartindex;
550 {
551   afs_int32     code;
552   prentries bulkentries;
553
554   *nentries = 0;
555   *entries  = (struct prlistentries *)0;
556   *nextstartindex = -1;
557   bulkentries.prentries_val = 0;
558   bulkentries.prentries_len = 0;
559
560   code = ubik_Call(PR_ListEntries, pruclient, 0,
561                    flag, startindex, &bulkentries, nextstartindex);
562   *nentries = bulkentries.prentries_len;
563   *entries  = bulkentries.prentries_val;
564   return code;
565 }
566
567 pr_CheckEntryByName(name,id,owner,creator)
568 char *name;
569 afs_int32 *id;
570 char *owner;
571 char *creator;
572 {
573     /* struct prcheckentry returns other things, which aren't useful to show at this time. */
574     register afs_int32 code;
575     struct prcheckentry aentry;
576
577     code = pr_SNameToId(name,id);
578     if (code) return code;
579     if (*id == ANONYMOUSID) return PRNOENT;
580     code = ubik_Call(PR_ListEntry,pruclient,0,*id,&aentry);
581     if (code) return code;
582     /* this should be done in one RPC, but I'm lazy. */
583     code = pr_SIdToName(aentry.owner,owner);
584     if (code) return code;
585     code = pr_SIdToName(aentry.creator,creator);
586     if (code) return code;
587     return PRSUCCESS;
588 }
589
590 pr_CheckEntryById(name,id,owner,creator)
591 char *name;
592 afs_int32 id;
593 char *owner;
594 char *creator;
595 {
596     /* struct prcheckentry returns other things, which aren't useful to show at this time. */
597     register afs_int32 code;
598     struct prcheckentry aentry;
599
600     code = pr_SIdToName(id,name);
601     if (code) return code;
602     if (id == ANONYMOUSID) return PRNOENT;
603     code = ubik_Call(PR_ListEntry,pruclient,0,id,&aentry);
604     if (code) return code;
605     /* this should be done in one RPC, but I'm lazy. */
606     code = pr_SIdToName(aentry.owner,owner);
607     if (code) return code;
608     code = pr_SIdToName(aentry.creator,creator);
609     if (code) return code;
610     return PRSUCCESS;
611 }
612
613 pr_ChangeEntry(oldname,newname,newid,newowner)
614 char *oldname;
615 char *newname;
616 afs_int32 *newid;
617 char *newowner;
618 {
619     register afs_int32 code;
620     afs_int32 id;
621     afs_int32 oid =0;
622
623     code = pr_SNameToId(oldname,&id);
624     if (code) return code;
625     if (id == ANONYMOUSID) return PRNOENT;
626     if (newowner && *newowner) {
627         code = pr_SNameToId(newowner,&oid);
628         if (code) return code;
629         if (oid == ANONYMOUSID) return PRNOENT;
630     }
631     code = ubik_Call(PR_ChangeEntry,pruclient, 0,id,newname,oid,newid);
632     return code;
633 }
634
635 pr_IsAMemberOf(uname,gname,flag)
636 char *uname;
637 char *gname;
638 afs_int32 *flag;
639 {
640     register afs_int32 code;
641     namelist lnames;
642     idlist lids;
643
644     stolower(uname);
645     stolower(gname);
646     lnames.namelist_len = 2;
647     lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
648     strncpy(lnames.namelist_val[0],uname,PR_MAXNAMELEN);
649     strncpy(lnames.namelist_val[1],gname,PR_MAXNAMELEN);
650     lids.idlist_val= 0;
651     lids.idlist_len = 0;
652     code = pr_NameToId(&lnames,&lids);
653     if (code) {
654         if (lnames.namelist_val) free(lnames.namelist_val);
655         if (lids.idlist_val) free(lids.idlist_val);
656         return code;
657     }
658     code = ubik_Call(PR_IsAMemberOf,pruclient,0,lids.idlist_val[0],lids.idlist_val[1],flag);
659     if (lnames.namelist_val) free(lnames.namelist_val);
660     if (lids.idlist_val) free(lids.idlist_val);
661     return code;
662 }
663
664
665 pr_ListMaxUserId(mid)
666 afs_int32 *mid;
667 {
668     register afs_int32 code;
669     afs_int32 gid;
670     code = ubik_Call(PR_ListMax,pruclient,0,mid,&gid);
671     return code;
672 }
673
674 pr_SetMaxUserId(mid)
675 afs_int32 mid;
676 {
677     register afs_int32 code;
678     afs_int32 flag = 0;
679     code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
680     return code;
681 }
682
683 pr_ListMaxGroupId(mid)
684 afs_int32 *mid;
685 {
686     register afs_int32 code;
687     afs_int32 id;
688     code = ubik_Call(PR_ListMax,pruclient,0,&id,mid);
689     return code;
690 }
691
692 pr_SetMaxGroupId(mid)
693 afs_int32 mid;
694 {
695     register afs_int32 code;
696     afs_int32 flag = 0;
697
698     flag |= PRGRP;
699     code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
700     return code;
701 }
702
703 afs_int32 pr_SetFieldsEntry (id, mask, flags, ngroups, nusers)
704   afs_int32 id;
705   afs_int32 mask;
706   afs_int32 flags, ngroups, nusers;
707 {
708     register afs_int32 code;
709
710     code = ubik_Call(PR_SetFieldsEntry,pruclient,0,id,mask, flags, ngroups, nusers, 0,0);
711     return code;
712 }
713
714
715 stolower(s)
716 char *s;
717 {
718     while (*s) {
719         if (isupper(*s)) *s = tolower(*s);
720         s++;
721     }
722 }
723