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
11 #include "../afs/param.h"
12 #include "../afs/sysincludes.h"
13 #include "../afs/afs_usrops.h"
14 #include "../afs/afsincludes.h"
15 #include "../afs/stds.h"
17 #include "../rx/xdr.h"
18 #include "../rx/rxkad.h"
19 #include "../afs/auth.h"
20 #include "../afs/cellconfig.h"
21 #include "../afs/afsutil.h"
23 #include "../afs/ptclient.h"
24 #include "../afs/pterror.h"
26 #else /* defined(UKERNEL) */
27 #include <afs/param.h>
30 #include <sys/types.h>
34 #include <netinet/in.h>
41 #include <afs/cellconfig.h>
42 #include <afs/afsutil.h>
45 #endif /* defined(UKERNEL) */
48 struct ubik_client *pruclient = 0;
49 static afs_int32 lastLevel; /* security level pruclient, if any */
51 static char *whoami = "libprot";
53 afs_int32 pr_Initialize (secLevel, confDir, cell)
54 IN afs_int32 secLevel;
59 struct rx_connection *serverconns[MAXSERVERS];
60 struct rx_securityClass *sc[3];
61 static struct afsconf_dir *tdir = 0; /* only do this once */
62 static char tconfDir[100];
63 struct ktc_token ttoken;
65 static struct afsconf_cell info;
69 initialize_pt_error_table();
70 initialize_rxk_error_table();
71 initialize_acfg_error_table();
72 initialize_ktc_error_table();
74 initialize_lwp_error_table();
75 initialize_rx_error_table();
78 if (strcmp(confDir, tconfDir)) {
80 * Different conf dir; force re-evaluation.
82 tdir = (struct afsconf_dir *)0;
83 pruclient = (struct ubik_client *)0;
86 strncpy(tconfDir, confDir, sizeof(tconfDir));
90 cell = afs_LclCellName;
92 #else /* defined(UKERNEL) */
93 tdir = afsconf_Open(confDir);
96 "libprot: Could not open configuration directory: %s.\n",
102 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
105 "vos: can't get local cell name - check %s/%s\n",
106 confDir, AFSDIR_THISCELL_FILE);
111 #endif /* defined(UKERNEL) */
113 code = afsconf_GetCellInfo(tdir,cell,"afsprot",&info);
115 fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n",
116 cell, confDir, AFSDIR_CELLSERVDB_FILE);
121 /* If we already have a client and it is at the security level we
122 * want, don't get a new one. Unless the security level is 2 in
123 * which case we will get one (and re-read the key file).
125 if (pruclient && (lastLevel == secLevel) && (secLevel != 2))
130 fprintf(stderr,"libprot: Could not initialize rx.\n");
138 /* Most callers use secLevel==1, however, the fileserver uses secLevel==2
139 * to force use of the KeyFile. secLevel == 0 implies -noauth was
141 if ((secLevel == 2) && (afsconf_GetLatestKey (tdir, 0,0) == 0)) {
142 /* If secLevel is two assume we're on a file server and use
143 * ClientAuthSecure if possible. */
144 code = afsconf_ClientAuthSecure (tdir, &sc[2], &scIndex);
145 if (code) scIndex = 0; /* use noauth */
147 /* if there was a problem, an unauthenticated conn is returned */
150 else if (secLevel > 0) {
151 struct ktc_principal sname;
152 strcpy(sname.cell,info.name);
153 sname.instance[0] = 0;
154 strcpy(sname.name, "afs");
155 code = ktc_GetToken(&sname,&ttoken, sizeof(ttoken), (char *)0);
156 if (code) scIndex = 0;
158 if (ttoken.kvno >= 0 && ttoken.kvno <= 255)
159 /* this is a kerberos ticket, set scIndex accordingly */
163 "libprot: funny kvno (%d) in ticket, proceeding\n",
167 sc[2] = (struct rx_securityClass *) rxkad_NewClientSecurityObject
168 (rxkad_clear, &ttoken.sessionKey, ttoken.kvno,
169 ttoken.ticketLen, ttoken.ticket);
172 if (scIndex == 1) return PRBADARG;
173 if ((scIndex == 0) && (sc[0] == 0))
174 sc[0] = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
175 if ((scIndex == 0) && (secLevel != 0))
176 com_err (whoami, code,
177 "Could not get afs tokens, running unauthenticated.");
179 bzero (serverconns, sizeof(serverconns)); /* terminate list!!! */
180 for (i = 0;i<info.numServers;i++)
181 serverconns[i] = rx_NewConnection
182 (info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
183 PRSRV, sc[scIndex], scIndex);
185 code = ubik_ClientInit(serverconns, &pruclient);
187 com_err (whoami, code, "ubik client init failed.");
192 code = rxs_Release (sc[scIndex]);
202 code = ubik_ClientDestroy (pruclient);
210 pr_CreateUser(name,id)
211 char name[PR_MAXNAMELEN];
214 register afs_int32 code;
218 code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,0);
222 code = ubik_Call(PR_NewEntry, pruclient, 0, name,0,0,id);
228 pr_CreateGroup(name,owner, id)
229 char name[PR_MAXNAMELEN];
230 char owner[PR_MAXNAMELEN];
233 register afs_int32 code;
239 code = pr_SNameToId(owner,&oid);
240 if (code) return code;
241 if (oid == ANONYMOUSID) return PRNOENT;
245 code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,oid);
249 code = ubik_Call(PR_NewEntry,pruclient, 0, name,flags,oid,id);
257 register afs_int32 code;
261 code = pr_SNameToId(name,&id);
262 if (code) return code;
263 if (id == ANONYMOUSID) return PRNOENT;
264 code = ubik_Call(PR_Delete,pruclient,0,id);
271 register afs_int32 code;
273 code = ubik_Call(PR_Delete,pruclient,0,id);
277 pr_AddToGroup(user,group)
281 register afs_int32 code;
285 lnames.namelist_len = 2;
286 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
287 strncpy(lnames.namelist_val[0],user,PR_MAXNAMELEN);
288 strncpy(lnames.namelist_val[1],group,PR_MAXNAMELEN);
291 code = pr_NameToId(&lnames,&lids);
293 /* if here, still could be missing an entry */
294 if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
298 code = ubik_Call(PR_AddToGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
300 if (lnames.namelist_val) free(lnames.namelist_val);
301 if (lids.idlist_val) free(lids.idlist_val);
305 pr_RemoveUserFromGroup(user,group)
309 register afs_int32 code;
313 lnames.namelist_len = 2;
314 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
315 strncpy(lnames.namelist_val[0],user,PR_MAXNAMELEN);
316 strncpy(lnames.namelist_val[1],group,PR_MAXNAMELEN);
319 code = pr_NameToId(&lnames,&lids);
322 if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
326 code = ubik_Call(PR_RemoveFromGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
328 if (lnames.namelist_val) free(lnames.namelist_val);
329 if (lids.idlist_val) free(lids.idlist_val);
334 pr_NameToId(names, ids)
338 register afs_int32 code;
339 register afs_int32 i;
341 for (i=0;i<names->namelist_len;i++)
342 stolower(names->namelist_val[i]);
343 code = ubik_Call(PR_NameToID,pruclient,0,names,ids);
347 pr_SNameToId(name,id)
348 char name[PR_MAXNAMELEN];
353 register afs_int32 code;
357 lnames.namelist_len = 1;
358 lnames.namelist_val = (prname *)malloc(PR_MAXNAMELEN);
360 strncpy(lnames.namelist_val[0],name,PR_MAXNAMELEN);
361 code = ubik_Call(PR_NameToID,pruclient,0,&lnames,&lids);
362 if (lids.idlist_val) {
363 *id = *lids.idlist_val;
364 free(lids.idlist_val);
366 if (lnames.namelist_val) free(lnames.namelist_val);
372 pr_IdToName(ids,names)
376 register afs_int32 code;
378 code = ubik_Call(PR_IDToName,pruclient,0,ids,names);
382 pr_SIdToName(id,name)
384 char name[PR_MAXNAMELEN];
388 register afs_int32 code;
391 lids.idlist_val = (afs_int32 *)malloc(sizeof(afs_int32));
392 *lids.idlist_val = id;
393 lnames.namelist_len = 0;
394 lnames.namelist_val = 0;
395 code = ubik_Call(PR_IDToName,pruclient,0,&lids,&lnames);
396 if (lnames.namelist_val) {
397 strncpy(name,lnames.namelist_val[0],PR_MAXNAMELEN);
398 free(lnames.namelist_val);
400 if (lids.idlist_val) free(lids.idlist_val);
410 register afs_int32 code;
414 code = ubik_Call(PR_GetCPS,pruclient,0,id,CPS,&over);
415 if (code != PRSUCCESS) return code;
417 /* do something about this, probably make a new call */
418 /* don't forget there's a hard limit in the interface */
419 fprintf (stderr, "membership list for id %d exceeds display limit\n", id);
425 pr_GetCPS2(id, host, CPS)
430 register afs_int32 code;
434 code = ubik_Call(PR_GetCPS2,pruclient,0,id,host,CPS,&over);
435 if (code != PRSUCCESS) return code;
437 /* do something about this, probably make a new call */
438 /* don't forget there's a hard limit in the interface */
439 fprintf (stderr, "membership list for id %d exceeds display limit\n", id);
444 pr_GetHostCPS(host, CPS)
448 register afs_int32 code;
452 code = ubik_Call(PR_GetHostCPS,pruclient,0,host,CPS,&over);
453 if (code != PRSUCCESS) return code;
455 /* do something about this, probably make a new call */
456 /* don't forget there's a hard limit in the interface */
457 fprintf (stderr, "membership list for host id %d exceeds display limit\n", host);
463 pr_ListMembers(group,lnames)
467 register afs_int32 code;
470 code = pr_SNameToId(group,&gid);
471 if (code) return code;
472 if (gid == ANONYMOUSID) return PRNOENT;
473 code = pr_IDListMembers(gid, lnames);
477 pr_ListOwned (oid,lnames,moreP)
482 register afs_int32 code;
486 alist.prlist_len = 0;
487 alist.prlist_val = 0;
488 code = ubik_Call(PR_ListOwned,pruclient,0,oid,&alist,moreP);
489 if (code) return code;
491 /* Remain backwards compatible when moreP was a T/F bit */
492 fprintf (stderr, "membership list for id %d exceeds display limit\n",
496 lids = (idlist *)&alist;
497 code = pr_IdToName(lids,lnames);
498 if (code) return code;
499 if (alist.prlist_val) free(alist.prlist_val);
503 pr_IDListMembers(gid,lnames)
507 register afs_int32 code;
512 alist.prlist_len = 0;
513 alist.prlist_val = 0;
514 code = ubik_Call(PR_ListElements,pruclient,0,gid,&alist,&over);
515 if (code) return code;
517 fprintf (stderr, "membership list for id %d exceeds display limit\n", gid);
519 lids = (idlist *)&alist;
520 code = pr_IdToName(lids,lnames);
521 if (code) return code;
522 if (alist.prlist_val) free(alist.prlist_val);
527 pr_ListEntry(id, aentry)
529 struct prcheckentry *aentry;
531 register afs_int32 code;
533 code = ubik_Call (PR_ListEntry, pruclient, 0, id, aentry);
537 afs_int32 pr_ListEntries(flag, startindex, nentries, entries, nextstartindex)
538 afs_int32 startindex;
540 struct prlistentries **entries;
541 afs_int32 *nextstartindex;
544 prentries bulkentries;
547 *entries = (struct prlistentries *)0;
548 *nextstartindex = -1;
549 bulkentries.prentries_val = 0;
550 bulkentries.prentries_len = 0;
552 code = ubik_Call(PR_ListEntries, pruclient, 0,
553 flag, startindex, &bulkentries, nextstartindex);
554 *nentries = bulkentries.prentries_len;
555 *entries = bulkentries.prentries_val;
559 pr_CheckEntryByName(name,id,owner,creator)
565 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
566 register afs_int32 code;
567 struct prcheckentry aentry;
569 code = pr_SNameToId(name,id);
570 if (code) return code;
571 if (*id == ANONYMOUSID) return PRNOENT;
572 code = ubik_Call(PR_ListEntry,pruclient,0,*id,&aentry);
573 if (code) return code;
574 /* this should be done in one RPC, but I'm lazy. */
575 code = pr_SIdToName(aentry.owner,owner);
576 if (code) return code;
577 code = pr_SIdToName(aentry.creator,creator);
578 if (code) return code;
582 pr_CheckEntryById(name,id,owner,creator)
588 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
589 register afs_int32 code;
590 struct prcheckentry aentry;
592 code = pr_SIdToName(id,name);
593 if (code) return code;
594 if (id == ANONYMOUSID) return PRNOENT;
595 code = ubik_Call(PR_ListEntry,pruclient,0,id,&aentry);
596 if (code) return code;
597 /* this should be done in one RPC, but I'm lazy. */
598 code = pr_SIdToName(aentry.owner,owner);
599 if (code) return code;
600 code = pr_SIdToName(aentry.creator,creator);
601 if (code) return code;
605 pr_ChangeEntry(oldname,newname,newid,newowner)
611 register afs_int32 code;
615 code = pr_SNameToId(oldname,&id);
616 if (code) return code;
617 if (id == ANONYMOUSID) return PRNOENT;
618 if (newowner && *newowner) {
619 code = pr_SNameToId(newowner,&oid);
620 if (code) return code;
621 if (oid == ANONYMOUSID) return PRNOENT;
623 code = ubik_Call(PR_ChangeEntry,pruclient, 0,id,newname,oid,newid);
627 pr_IsAMemberOf(uname,gname,flag)
632 register afs_int32 code;
638 lnames.namelist_len = 2;
639 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
640 strncpy(lnames.namelist_val[0],uname,PR_MAXNAMELEN);
641 strncpy(lnames.namelist_val[1],gname,PR_MAXNAMELEN);
644 code = pr_NameToId(&lnames,&lids);
646 if (lnames.namelist_val) free(lnames.namelist_val);
647 if (lids.idlist_val) free(lids.idlist_val);
650 code = ubik_Call(PR_IsAMemberOf,pruclient,0,lids.idlist_val[0],lids.idlist_val[1],flag);
651 if (lnames.namelist_val) free(lnames.namelist_val);
652 if (lids.idlist_val) free(lids.idlist_val);
657 pr_ListMaxUserId(mid)
660 register afs_int32 code;
662 code = ubik_Call(PR_ListMax,pruclient,0,mid,&gid);
669 register afs_int32 code;
671 code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
675 pr_ListMaxGroupId(mid)
678 register afs_int32 code;
680 code = ubik_Call(PR_ListMax,pruclient,0,&id,mid);
684 pr_SetMaxGroupId(mid)
687 register afs_int32 code;
691 code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
695 afs_int32 pr_SetFieldsEntry (id, mask, flags, ngroups, nusers)
698 afs_int32 flags, ngroups, nusers;
700 register afs_int32 code;
702 code = ubik_Call(PR_SetFieldsEntry,pruclient,0,id,mask, flags, ngroups, nusers, 0,0);
711 if (isupper(*s)) *s = tolower(*s);