2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
12 #include "../afs/param.h"
14 #include <afs/param.h>
20 #include "../afs/sysincludes.h"
21 #include "../afs/afs_usrops.h"
22 #include "../afs/afsincludes.h"
23 #include "../afs/stds.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) */
35 #include <sys/types.h>
39 #include <netinet/in.h>
53 #include <afs/cellconfig.h>
54 #include <afs/afsutil.h>
57 #endif /* defined(UKERNEL) */
60 struct ubik_client *pruclient = 0;
61 static afs_int32 lastLevel; /* security level pruclient, if any */
63 static char *whoami = "libprot";
65 afs_int32 pr_Initialize (secLevel, confDir, cell)
66 IN afs_int32 secLevel;
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;
77 static struct afsconf_cell info;
81 initialize_PT_error_table();
82 initialize_RXK_error_table();
83 initialize_ACFG_error_table();
84 initialize_KTC_error_table();
86 if (strcmp(confDir, tconfDir)) {
88 * Different conf dir; force re-evaluation.
90 tdir = (struct afsconf_dir *)0;
91 pruclient = (struct ubik_client *)0;
94 strncpy(tconfDir, confDir, sizeof(tconfDir));
98 cell = afs_LclCellName;
100 #else /* defined(UKERNEL) */
101 tdir = afsconf_Open(confDir);
104 "libprot: Could not open configuration directory: %s.\n",
110 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
113 "vos: can't get local cell name - check %s/%s\n",
114 confDir, AFSDIR_THISCELL_FILE);
119 #endif /* defined(UKERNEL) */
121 code = afsconf_GetCellInfo(tdir,cell,"afsprot",&info);
123 fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n",
124 cell, confDir, AFSDIR_CELLSERVDB_FILE);
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).
133 if (pruclient && (lastLevel == secLevel) && (secLevel != 2))
138 fprintf(stderr,"libprot: Could not initialize rx.\n");
146 /* Most callers use secLevel==1, however, the fileserver uses secLevel==2
147 * to force use of the KeyFile. secLevel == 0 implies -noauth was
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 */
155 /* if there was a problem, an unauthenticated conn is returned */
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;
166 if (ttoken.kvno >= 0 && ttoken.kvno <= 255)
167 /* this is a kerberos ticket, set scIndex accordingly */
171 "libprot: funny kvno (%d) in ticket, proceeding\n",
175 sc[2] = (struct rx_securityClass *) rxkad_NewClientSecurityObject
176 (rxkad_clear, &ttoken.sessionKey, ttoken.kvno,
177 ttoken.ticketLen, ttoken.ticket);
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.");
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);
193 code = ubik_ClientInit(serverconns, &pruclient);
195 com_err (whoami, code, "ubik client init failed.");
200 code = rxs_Release (sc[scIndex]);
210 code = ubik_ClientDestroy (pruclient);
218 pr_CreateUser(name,id)
219 char name[PR_MAXNAMELEN];
222 register afs_int32 code;
226 code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,0);
230 code = ubik_Call(PR_NewEntry, pruclient, 0, name,0,0,id);
236 pr_CreateGroup(name,owner, id)
237 char name[PR_MAXNAMELEN];
238 char owner[PR_MAXNAMELEN];
241 register afs_int32 code;
247 code = pr_SNameToId(owner,&oid);
248 if (code) return code;
249 if (oid == ANONYMOUSID) return PRNOENT;
253 code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,oid);
257 code = ubik_Call(PR_NewEntry,pruclient, 0, name,flags,oid,id);
265 register afs_int32 code;
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);
279 register afs_int32 code;
281 code = ubik_Call(PR_Delete,pruclient,0,id);
285 pr_AddToGroup(user,group)
289 register afs_int32 code;
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);
299 code = pr_NameToId(&lnames,&lids);
301 /* if here, still could be missing an entry */
302 if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
306 code = ubik_Call(PR_AddToGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
308 if (lnames.namelist_val) free(lnames.namelist_val);
309 if (lids.idlist_val) free(lids.idlist_val);
313 pr_RemoveUserFromGroup(user,group)
317 register afs_int32 code;
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);
327 code = pr_NameToId(&lnames,&lids);
330 if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
334 code = ubik_Call(PR_RemoveFromGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
336 if (lnames.namelist_val) free(lnames.namelist_val);
337 if (lids.idlist_val) free(lids.idlist_val);
342 pr_NameToId(names, ids)
346 register afs_int32 code;
347 register afs_int32 i;
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);
355 pr_SNameToId(name,id)
356 char name[PR_MAXNAMELEN];
361 register afs_int32 code;
365 lnames.namelist_len = 1;
366 lnames.namelist_val = (prname *)malloc(PR_MAXNAMELEN);
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);
374 if (lnames.namelist_val) free(lnames.namelist_val);
380 pr_IdToName(ids,names)
384 register afs_int32 code;
386 code = ubik_Call(PR_IDToName,pruclient,0,ids,names);
390 pr_SIdToName(id,name)
392 char name[PR_MAXNAMELEN];
396 register afs_int32 code;
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);
408 if (lids.idlist_val) free(lids.idlist_val);
418 register afs_int32 code;
422 code = ubik_Call(PR_GetCPS,pruclient,0,id,CPS,&over);
423 if (code != PRSUCCESS) return code;
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);
433 pr_GetCPS2(id, host, CPS)
438 register afs_int32 code;
442 code = ubik_Call(PR_GetCPS2,pruclient,0,id,host,CPS,&over);
443 if (code != PRSUCCESS) return code;
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);
452 pr_GetHostCPS(host, CPS)
456 register afs_int32 code;
460 code = ubik_Call(PR_GetHostCPS,pruclient,0,host,CPS,&over);
461 if (code != PRSUCCESS) return code;
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);
471 pr_ListMembers(group,lnames)
475 register afs_int32 code;
478 code = pr_SNameToId(group,&gid);
479 if (code) return code;
480 if (gid == ANONYMOUSID) return PRNOENT;
481 code = pr_IDListMembers(gid, lnames);
485 pr_ListOwned (oid,lnames,moreP)
490 register afs_int32 code;
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;
499 /* Remain backwards compatible when moreP was a T/F bit */
500 fprintf (stderr, "membership list for id %d exceeds display limit\n",
504 lids = (idlist *)&alist;
505 code = pr_IdToName(lids,lnames);
506 if (code) return code;
507 if (alist.prlist_val) free(alist.prlist_val);
511 pr_IDListMembers(gid,lnames)
515 register afs_int32 code;
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;
525 fprintf (stderr, "membership list for id %d exceeds display limit\n", gid);
527 lids = (idlist *)&alist;
528 code = pr_IdToName(lids,lnames);
529 if (code) return code;
530 if (alist.prlist_val) free(alist.prlist_val);
535 pr_ListEntry(id, aentry)
537 struct prcheckentry *aentry;
539 register afs_int32 code;
541 code = ubik_Call (PR_ListEntry, pruclient, 0, id, aentry);
545 afs_int32 pr_ListEntries(flag, startindex, nentries, entries, nextstartindex)
546 afs_int32 startindex;
548 struct prlistentries **entries;
549 afs_int32 *nextstartindex;
552 prentries bulkentries;
555 *entries = (struct prlistentries *)0;
556 *nextstartindex = -1;
557 bulkentries.prentries_val = 0;
558 bulkentries.prentries_len = 0;
560 code = ubik_Call(PR_ListEntries, pruclient, 0,
561 flag, startindex, &bulkentries, nextstartindex);
562 *nentries = bulkentries.prentries_len;
563 *entries = bulkentries.prentries_val;
567 pr_CheckEntryByName(name,id,owner,creator)
573 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
574 register afs_int32 code;
575 struct prcheckentry aentry;
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;
590 pr_CheckEntryById(name,id,owner,creator)
596 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
597 register afs_int32 code;
598 struct prcheckentry aentry;
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;
613 pr_ChangeEntry(oldname,newname,newid,newowner)
619 register afs_int32 code;
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;
631 code = ubik_Call(PR_ChangeEntry,pruclient, 0,id,newname,oid,newid);
635 pr_IsAMemberOf(uname,gname,flag)
640 register afs_int32 code;
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);
652 code = pr_NameToId(&lnames,&lids);
654 if (lnames.namelist_val) free(lnames.namelist_val);
655 if (lids.idlist_val) free(lids.idlist_val);
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);
665 pr_ListMaxUserId(mid)
668 register afs_int32 code;
670 code = ubik_Call(PR_ListMax,pruclient,0,mid,&gid);
677 register afs_int32 code;
679 code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
683 pr_ListMaxGroupId(mid)
686 register afs_int32 code;
688 code = ubik_Call(PR_ListMax,pruclient,0,&id,mid);
692 pr_SetMaxGroupId(mid)
695 register afs_int32 code;
699 code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
703 afs_int32 pr_SetFieldsEntry (id, mask, flags, ngroups, nusers)
706 afs_int32 flags, ngroups, nusers;
708 register afs_int32 code;
710 code = ubik_Call(PR_SetFieldsEntry,pruclient,0,id,mask, flags, ngroups, nusers, 0,0);
719 if (isupper(*s)) *s = tolower(*s);