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>
46 #include <afs/cellconfig.h>
47 #include <afs/afsutil.h>
50 #endif /* defined(UKERNEL) */
53 struct ubik_client *pruclient = 0;
54 static afs_int32 lastLevel; /* security level pruclient, if any */
56 static char *whoami = "libprot";
58 afs_int32 pr_Initialize (secLevel, confDir, cell)
59 IN afs_int32 secLevel;
64 struct rx_connection *serverconns[MAXSERVERS];
65 struct rx_securityClass *sc[3];
66 static struct afsconf_dir *tdir = 0; /* only do this once */
67 static char tconfDir[100];
68 struct ktc_token ttoken;
70 static struct afsconf_cell info;
74 initialize_PT_error_table();
75 initialize_RXK_error_table();
76 initialize_ACFG_error_table();
77 initialize_KTC_error_table();
79 if (strcmp(confDir, tconfDir)) {
81 * Different conf dir; force re-evaluation.
83 tdir = (struct afsconf_dir *)0;
84 pruclient = (struct ubik_client *)0;
87 strncpy(tconfDir, confDir, sizeof(tconfDir));
91 cell = afs_LclCellName;
93 #else /* defined(UKERNEL) */
94 tdir = afsconf_Open(confDir);
97 "libprot: Could not open configuration directory: %s.\n",
103 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
106 "vos: can't get local cell name - check %s/%s\n",
107 confDir, AFSDIR_THISCELL_FILE);
112 #endif /* defined(UKERNEL) */
114 code = afsconf_GetCellInfo(tdir,cell,"afsprot",&info);
116 fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n",
117 cell, confDir, AFSDIR_CELLSERVDB_FILE);
122 /* If we already have a client and it is at the security level we
123 * want, don't get a new one. Unless the security level is 2 in
124 * which case we will get one (and re-read the key file).
126 if (pruclient && (lastLevel == secLevel) && (secLevel != 2))
131 fprintf(stderr,"libprot: Could not initialize rx.\n");
139 /* Most callers use secLevel==1, however, the fileserver uses secLevel==2
140 * to force use of the KeyFile. secLevel == 0 implies -noauth was
142 if ((secLevel == 2) && (afsconf_GetLatestKey (tdir, 0,0) == 0)) {
143 /* If secLevel is two assume we're on a file server and use
144 * ClientAuthSecure if possible. */
145 code = afsconf_ClientAuthSecure (tdir, &sc[2], &scIndex);
146 if (code) scIndex = 0; /* use noauth */
148 /* if there was a problem, an unauthenticated conn is returned */
151 else if (secLevel > 0) {
152 struct ktc_principal sname;
153 strcpy(sname.cell,info.name);
154 sname.instance[0] = 0;
155 strcpy(sname.name, "afs");
156 code = ktc_GetToken(&sname,&ttoken, sizeof(ttoken), (char *)0);
157 if (code) scIndex = 0;
159 if (ttoken.kvno >= 0 && ttoken.kvno <= 255)
160 /* this is a kerberos ticket, set scIndex accordingly */
164 "libprot: funny kvno (%d) in ticket, proceeding\n",
168 sc[2] = (struct rx_securityClass *) rxkad_NewClientSecurityObject
169 (rxkad_clear, &ttoken.sessionKey, ttoken.kvno,
170 ttoken.ticketLen, ttoken.ticket);
173 if (scIndex == 1) return PRBADARG;
174 if ((scIndex == 0) && (sc[0] == 0))
175 sc[0] = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
176 if ((scIndex == 0) && (secLevel != 0))
177 com_err (whoami, code,
178 "Could not get afs tokens, running unauthenticated.");
180 memset(serverconns, 0, sizeof(serverconns)); /* terminate list!!! */
181 for (i = 0;i<info.numServers;i++)
182 serverconns[i] = rx_NewConnection
183 (info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
184 PRSRV, sc[scIndex], scIndex);
186 code = ubik_ClientInit(serverconns, &pruclient);
188 com_err (whoami, code, "ubik client init failed.");
193 code = rxs_Release (sc[scIndex]);
203 code = ubik_ClientDestroy (pruclient);
211 pr_CreateUser(name,id)
212 char name[PR_MAXNAMELEN];
215 register afs_int32 code;
219 code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,0);
223 code = ubik_Call(PR_NewEntry, pruclient, 0, name,0,0,id);
229 pr_CreateGroup(name,owner, id)
230 char name[PR_MAXNAMELEN];
231 char owner[PR_MAXNAMELEN];
234 register afs_int32 code;
240 code = pr_SNameToId(owner,&oid);
241 if (code) return code;
242 if (oid == ANONYMOUSID) return PRNOENT;
246 code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,oid);
250 code = ubik_Call(PR_NewEntry,pruclient, 0, name,flags,oid,id);
258 register afs_int32 code;
262 code = pr_SNameToId(name,&id);
263 if (code) return code;
264 if (id == ANONYMOUSID) return PRNOENT;
265 code = ubik_Call(PR_Delete,pruclient,0,id);
272 register afs_int32 code;
274 code = ubik_Call(PR_Delete,pruclient,0,id);
278 pr_AddToGroup(user,group)
282 register afs_int32 code;
286 lnames.namelist_len = 2;
287 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
288 strncpy(lnames.namelist_val[0],user,PR_MAXNAMELEN);
289 strncpy(lnames.namelist_val[1],group,PR_MAXNAMELEN);
292 code = pr_NameToId(&lnames,&lids);
294 /* if here, still could be missing an entry */
295 if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
299 code = ubik_Call(PR_AddToGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
301 if (lnames.namelist_val) free(lnames.namelist_val);
302 if (lids.idlist_val) free(lids.idlist_val);
306 pr_RemoveUserFromGroup(user,group)
310 register afs_int32 code;
314 lnames.namelist_len = 2;
315 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
316 strncpy(lnames.namelist_val[0],user,PR_MAXNAMELEN);
317 strncpy(lnames.namelist_val[1],group,PR_MAXNAMELEN);
320 code = pr_NameToId(&lnames,&lids);
323 if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
327 code = ubik_Call(PR_RemoveFromGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
329 if (lnames.namelist_val) free(lnames.namelist_val);
330 if (lids.idlist_val) free(lids.idlist_val);
335 pr_NameToId(names, ids)
339 register afs_int32 code;
340 register afs_int32 i;
342 for (i=0;i<names->namelist_len;i++)
343 stolower(names->namelist_val[i]);
344 code = ubik_Call(PR_NameToID,pruclient,0,names,ids);
348 pr_SNameToId(name,id)
349 char name[PR_MAXNAMELEN];
354 register afs_int32 code;
358 lnames.namelist_len = 1;
359 lnames.namelist_val = (prname *)malloc(PR_MAXNAMELEN);
361 strncpy(lnames.namelist_val[0],name,PR_MAXNAMELEN);
362 code = ubik_Call(PR_NameToID,pruclient,0,&lnames,&lids);
363 if (lids.idlist_val) {
364 *id = *lids.idlist_val;
365 free(lids.idlist_val);
367 if (lnames.namelist_val) free(lnames.namelist_val);
373 pr_IdToName(ids,names)
377 register afs_int32 code;
379 code = ubik_Call(PR_IDToName,pruclient,0,ids,names);
383 pr_SIdToName(id,name)
385 char name[PR_MAXNAMELEN];
389 register afs_int32 code;
392 lids.idlist_val = (afs_int32 *)malloc(sizeof(afs_int32));
393 *lids.idlist_val = id;
394 lnames.namelist_len = 0;
395 lnames.namelist_val = 0;
396 code = ubik_Call(PR_IDToName,pruclient,0,&lids,&lnames);
397 if (lnames.namelist_val) {
398 strncpy(name,lnames.namelist_val[0],PR_MAXNAMELEN);
399 free(lnames.namelist_val);
401 if (lids.idlist_val) free(lids.idlist_val);
411 register afs_int32 code;
415 code = ubik_Call(PR_GetCPS,pruclient,0,id,CPS,&over);
416 if (code != PRSUCCESS) return code;
418 /* do something about this, probably make a new call */
419 /* don't forget there's a hard limit in the interface */
420 fprintf (stderr, "membership list for id %d exceeds display limit\n", id);
426 pr_GetCPS2(id, host, CPS)
431 register afs_int32 code;
435 code = ubik_Call(PR_GetCPS2,pruclient,0,id,host,CPS,&over);
436 if (code != PRSUCCESS) return code;
438 /* do something about this, probably make a new call */
439 /* don't forget there's a hard limit in the interface */
440 fprintf (stderr, "membership list for id %d exceeds display limit\n", id);
445 pr_GetHostCPS(host, CPS)
449 register afs_int32 code;
453 code = ubik_Call(PR_GetHostCPS,pruclient,0,host,CPS,&over);
454 if (code != PRSUCCESS) return code;
456 /* do something about this, probably make a new call */
457 /* don't forget there's a hard limit in the interface */
458 fprintf (stderr, "membership list for host id %d exceeds display limit\n", host);
464 pr_ListMembers(group,lnames)
468 register afs_int32 code;
471 code = pr_SNameToId(group,&gid);
472 if (code) return code;
473 if (gid == ANONYMOUSID) return PRNOENT;
474 code = pr_IDListMembers(gid, lnames);
478 pr_ListOwned (oid,lnames,moreP)
483 register afs_int32 code;
487 alist.prlist_len = 0;
488 alist.prlist_val = 0;
489 code = ubik_Call(PR_ListOwned,pruclient,0,oid,&alist,moreP);
490 if (code) return code;
492 /* Remain backwards compatible when moreP was a T/F bit */
493 fprintf (stderr, "membership list for id %d exceeds display limit\n",
497 lids = (idlist *)&alist;
498 code = pr_IdToName(lids,lnames);
499 if (code) return code;
500 if (alist.prlist_val) free(alist.prlist_val);
504 pr_IDListMembers(gid,lnames)
508 register afs_int32 code;
513 alist.prlist_len = 0;
514 alist.prlist_val = 0;
515 code = ubik_Call(PR_ListElements,pruclient,0,gid,&alist,&over);
516 if (code) return code;
518 fprintf (stderr, "membership list for id %d exceeds display limit\n", gid);
520 lids = (idlist *)&alist;
521 code = pr_IdToName(lids,lnames);
522 if (code) return code;
523 if (alist.prlist_val) free(alist.prlist_val);
528 pr_ListEntry(id, aentry)
530 struct prcheckentry *aentry;
532 register afs_int32 code;
534 code = ubik_Call (PR_ListEntry, pruclient, 0, id, aentry);
538 afs_int32 pr_ListEntries(flag, startindex, nentries, entries, nextstartindex)
539 afs_int32 startindex;
541 struct prlistentries **entries;
542 afs_int32 *nextstartindex;
545 prentries bulkentries;
548 *entries = (struct prlistentries *)0;
549 *nextstartindex = -1;
550 bulkentries.prentries_val = 0;
551 bulkentries.prentries_len = 0;
553 code = ubik_Call(PR_ListEntries, pruclient, 0,
554 flag, startindex, &bulkentries, nextstartindex);
555 *nentries = bulkentries.prentries_len;
556 *entries = bulkentries.prentries_val;
560 pr_CheckEntryByName(name,id,owner,creator)
566 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
567 register afs_int32 code;
568 struct prcheckentry aentry;
570 code = pr_SNameToId(name,id);
571 if (code) return code;
572 if (*id == ANONYMOUSID) return PRNOENT;
573 code = ubik_Call(PR_ListEntry,pruclient,0,*id,&aentry);
574 if (code) return code;
575 /* this should be done in one RPC, but I'm lazy. */
576 code = pr_SIdToName(aentry.owner,owner);
577 if (code) return code;
578 code = pr_SIdToName(aentry.creator,creator);
579 if (code) return code;
583 pr_CheckEntryById(name,id,owner,creator)
589 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
590 register afs_int32 code;
591 struct prcheckentry aentry;
593 code = pr_SIdToName(id,name);
594 if (code) return code;
595 if (id == ANONYMOUSID) return PRNOENT;
596 code = ubik_Call(PR_ListEntry,pruclient,0,id,&aentry);
597 if (code) return code;
598 /* this should be done in one RPC, but I'm lazy. */
599 code = pr_SIdToName(aentry.owner,owner);
600 if (code) return code;
601 code = pr_SIdToName(aentry.creator,creator);
602 if (code) return code;
606 pr_ChangeEntry(oldname,newname,newid,newowner)
612 register afs_int32 code;
616 code = pr_SNameToId(oldname,&id);
617 if (code) return code;
618 if (id == ANONYMOUSID) return PRNOENT;
619 if (newowner && *newowner) {
620 code = pr_SNameToId(newowner,&oid);
621 if (code) return code;
622 if (oid == ANONYMOUSID) return PRNOENT;
624 code = ubik_Call(PR_ChangeEntry,pruclient, 0,id,newname,oid,newid);
628 pr_IsAMemberOf(uname,gname,flag)
633 register afs_int32 code;
639 lnames.namelist_len = 2;
640 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
641 strncpy(lnames.namelist_val[0],uname,PR_MAXNAMELEN);
642 strncpy(lnames.namelist_val[1],gname,PR_MAXNAMELEN);
645 code = pr_NameToId(&lnames,&lids);
647 if (lnames.namelist_val) free(lnames.namelist_val);
648 if (lids.idlist_val) free(lids.idlist_val);
651 code = ubik_Call(PR_IsAMemberOf,pruclient,0,lids.idlist_val[0],lids.idlist_val[1],flag);
652 if (lnames.namelist_val) free(lnames.namelist_val);
653 if (lids.idlist_val) free(lids.idlist_val);
658 pr_ListMaxUserId(mid)
661 register afs_int32 code;
663 code = ubik_Call(PR_ListMax,pruclient,0,mid,&gid);
670 register afs_int32 code;
672 code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
676 pr_ListMaxGroupId(mid)
679 register afs_int32 code;
681 code = ubik_Call(PR_ListMax,pruclient,0,&id,mid);
685 pr_SetMaxGroupId(mid)
688 register afs_int32 code;
692 code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
696 afs_int32 pr_SetFieldsEntry (id, mask, flags, ngroups, nusers)
699 afs_int32 flags, ngroups, nusers;
701 register afs_int32 code;
703 code = ubik_Call(PR_SetFieldsEntry,pruclient,0,id,mask, flags, ngroups, nusers, 0,0);
712 if (isupper(*s)) *s = tolower(*s);