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 initialize_lwp_error_table();
80 initialize_rx_error_table();
83 if (strcmp(confDir, tconfDir)) {
85 * Different conf dir; force re-evaluation.
87 tdir = (struct afsconf_dir *)0;
88 pruclient = (struct ubik_client *)0;
91 strncpy(tconfDir, confDir, sizeof(tconfDir));
95 cell = afs_LclCellName;
97 #else /* defined(UKERNEL) */
98 tdir = afsconf_Open(confDir);
101 "libprot: Could not open configuration directory: %s.\n",
107 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
110 "vos: can't get local cell name - check %s/%s\n",
111 confDir, AFSDIR_THISCELL_FILE);
116 #endif /* defined(UKERNEL) */
118 code = afsconf_GetCellInfo(tdir,cell,"afsprot",&info);
120 fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n",
121 cell, confDir, AFSDIR_CELLSERVDB_FILE);
126 /* If we already have a client and it is at the security level we
127 * want, don't get a new one. Unless the security level is 2 in
128 * which case we will get one (and re-read the key file).
130 if (pruclient && (lastLevel == secLevel) && (secLevel != 2))
135 fprintf(stderr,"libprot: Could not initialize rx.\n");
143 /* Most callers use secLevel==1, however, the fileserver uses secLevel==2
144 * to force use of the KeyFile. secLevel == 0 implies -noauth was
146 if ((secLevel == 2) && (afsconf_GetLatestKey (tdir, 0,0) == 0)) {
147 /* If secLevel is two assume we're on a file server and use
148 * ClientAuthSecure if possible. */
149 code = afsconf_ClientAuthSecure (tdir, &sc[2], &scIndex);
150 if (code) scIndex = 0; /* use noauth */
152 /* if there was a problem, an unauthenticated conn is returned */
155 else if (secLevel > 0) {
156 struct ktc_principal sname;
157 strcpy(sname.cell,info.name);
158 sname.instance[0] = 0;
159 strcpy(sname.name, "afs");
160 code = ktc_GetToken(&sname,&ttoken, sizeof(ttoken), (char *)0);
161 if (code) scIndex = 0;
163 if (ttoken.kvno >= 0 && ttoken.kvno <= 255)
164 /* this is a kerberos ticket, set scIndex accordingly */
168 "libprot: funny kvno (%d) in ticket, proceeding\n",
172 sc[2] = (struct rx_securityClass *) rxkad_NewClientSecurityObject
173 (rxkad_clear, &ttoken.sessionKey, ttoken.kvno,
174 ttoken.ticketLen, ttoken.ticket);
177 if (scIndex == 1) return PRBADARG;
178 if ((scIndex == 0) && (sc[0] == 0))
179 sc[0] = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
180 if ((scIndex == 0) && (secLevel != 0))
181 com_err (whoami, code,
182 "Could not get afs tokens, running unauthenticated.");
184 memset(serverconns, 0, sizeof(serverconns)); /* terminate list!!! */
185 for (i = 0;i<info.numServers;i++)
186 serverconns[i] = rx_NewConnection
187 (info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port,
188 PRSRV, sc[scIndex], scIndex);
190 code = ubik_ClientInit(serverconns, &pruclient);
192 com_err (whoami, code, "ubik client init failed.");
197 code = rxs_Release (sc[scIndex]);
207 code = ubik_ClientDestroy (pruclient);
215 pr_CreateUser(name,id)
216 char name[PR_MAXNAMELEN];
219 register afs_int32 code;
223 code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,0);
227 code = ubik_Call(PR_NewEntry, pruclient, 0, name,0,0,id);
233 pr_CreateGroup(name,owner, id)
234 char name[PR_MAXNAMELEN];
235 char owner[PR_MAXNAMELEN];
238 register afs_int32 code;
244 code = pr_SNameToId(owner,&oid);
245 if (code) return code;
246 if (oid == ANONYMOUSID) return PRNOENT;
250 code = ubik_Call(PR_INewEntry,pruclient,0,name,*id,oid);
254 code = ubik_Call(PR_NewEntry,pruclient, 0, name,flags,oid,id);
262 register afs_int32 code;
266 code = pr_SNameToId(name,&id);
267 if (code) return code;
268 if (id == ANONYMOUSID) return PRNOENT;
269 code = ubik_Call(PR_Delete,pruclient,0,id);
276 register afs_int32 code;
278 code = ubik_Call(PR_Delete,pruclient,0,id);
282 pr_AddToGroup(user,group)
286 register afs_int32 code;
290 lnames.namelist_len = 2;
291 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
292 strncpy(lnames.namelist_val[0],user,PR_MAXNAMELEN);
293 strncpy(lnames.namelist_val[1],group,PR_MAXNAMELEN);
296 code = pr_NameToId(&lnames,&lids);
298 /* if here, still could be missing an entry */
299 if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
303 code = ubik_Call(PR_AddToGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
305 if (lnames.namelist_val) free(lnames.namelist_val);
306 if (lids.idlist_val) free(lids.idlist_val);
310 pr_RemoveUserFromGroup(user,group)
314 register afs_int32 code;
318 lnames.namelist_len = 2;
319 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
320 strncpy(lnames.namelist_val[0],user,PR_MAXNAMELEN);
321 strncpy(lnames.namelist_val[1],group,PR_MAXNAMELEN);
324 code = pr_NameToId(&lnames,&lids);
327 if (lids.idlist_val[0] == ANONYMOUSID || lids.idlist_val[1] == ANONYMOUSID) {
331 code = ubik_Call(PR_RemoveFromGroup, pruclient, 0, lids.idlist_val[0], lids.idlist_val[1]);
333 if (lnames.namelist_val) free(lnames.namelist_val);
334 if (lids.idlist_val) free(lids.idlist_val);
339 pr_NameToId(names, ids)
343 register afs_int32 code;
344 register afs_int32 i;
346 for (i=0;i<names->namelist_len;i++)
347 stolower(names->namelist_val[i]);
348 code = ubik_Call(PR_NameToID,pruclient,0,names,ids);
352 pr_SNameToId(name,id)
353 char name[PR_MAXNAMELEN];
358 register afs_int32 code;
362 lnames.namelist_len = 1;
363 lnames.namelist_val = (prname *)malloc(PR_MAXNAMELEN);
365 strncpy(lnames.namelist_val[0],name,PR_MAXNAMELEN);
366 code = ubik_Call(PR_NameToID,pruclient,0,&lnames,&lids);
367 if (lids.idlist_val) {
368 *id = *lids.idlist_val;
369 free(lids.idlist_val);
371 if (lnames.namelist_val) free(lnames.namelist_val);
377 pr_IdToName(ids,names)
381 register afs_int32 code;
383 code = ubik_Call(PR_IDToName,pruclient,0,ids,names);
387 pr_SIdToName(id,name)
389 char name[PR_MAXNAMELEN];
393 register afs_int32 code;
396 lids.idlist_val = (afs_int32 *)malloc(sizeof(afs_int32));
397 *lids.idlist_val = id;
398 lnames.namelist_len = 0;
399 lnames.namelist_val = 0;
400 code = ubik_Call(PR_IDToName,pruclient,0,&lids,&lnames);
401 if (lnames.namelist_val) {
402 strncpy(name,lnames.namelist_val[0],PR_MAXNAMELEN);
403 free(lnames.namelist_val);
405 if (lids.idlist_val) free(lids.idlist_val);
415 register afs_int32 code;
419 code = ubik_Call(PR_GetCPS,pruclient,0,id,CPS,&over);
420 if (code != PRSUCCESS) return code;
422 /* do something about this, probably make a new call */
423 /* don't forget there's a hard limit in the interface */
424 fprintf (stderr, "membership list for id %d exceeds display limit\n", id);
430 pr_GetCPS2(id, host, CPS)
435 register afs_int32 code;
439 code = ubik_Call(PR_GetCPS2,pruclient,0,id,host,CPS,&over);
440 if (code != PRSUCCESS) return code;
442 /* do something about this, probably make a new call */
443 /* don't forget there's a hard limit in the interface */
444 fprintf (stderr, "membership list for id %d exceeds display limit\n", id);
449 pr_GetHostCPS(host, CPS)
453 register afs_int32 code;
457 code = ubik_Call(PR_GetHostCPS,pruclient,0,host,CPS,&over);
458 if (code != PRSUCCESS) return code;
460 /* do something about this, probably make a new call */
461 /* don't forget there's a hard limit in the interface */
462 fprintf (stderr, "membership list for host id %d exceeds display limit\n", host);
468 pr_ListMembers(group,lnames)
472 register afs_int32 code;
475 code = pr_SNameToId(group,&gid);
476 if (code) return code;
477 if (gid == ANONYMOUSID) return PRNOENT;
478 code = pr_IDListMembers(gid, lnames);
482 pr_ListOwned (oid,lnames,moreP)
487 register afs_int32 code;
491 alist.prlist_len = 0;
492 alist.prlist_val = 0;
493 code = ubik_Call(PR_ListOwned,pruclient,0,oid,&alist,moreP);
494 if (code) return code;
496 /* Remain backwards compatible when moreP was a T/F bit */
497 fprintf (stderr, "membership list for id %d exceeds display limit\n",
501 lids = (idlist *)&alist;
502 code = pr_IdToName(lids,lnames);
503 if (code) return code;
504 if (alist.prlist_val) free(alist.prlist_val);
508 pr_IDListMembers(gid,lnames)
512 register afs_int32 code;
517 alist.prlist_len = 0;
518 alist.prlist_val = 0;
519 code = ubik_Call(PR_ListElements,pruclient,0,gid,&alist,&over);
520 if (code) return code;
522 fprintf (stderr, "membership list for id %d exceeds display limit\n", gid);
524 lids = (idlist *)&alist;
525 code = pr_IdToName(lids,lnames);
526 if (code) return code;
527 if (alist.prlist_val) free(alist.prlist_val);
532 pr_ListEntry(id, aentry)
534 struct prcheckentry *aentry;
536 register afs_int32 code;
538 code = ubik_Call (PR_ListEntry, pruclient, 0, id, aentry);
542 afs_int32 pr_ListEntries(flag, startindex, nentries, entries, nextstartindex)
543 afs_int32 startindex;
545 struct prlistentries **entries;
546 afs_int32 *nextstartindex;
549 prentries bulkentries;
552 *entries = (struct prlistentries *)0;
553 *nextstartindex = -1;
554 bulkentries.prentries_val = 0;
555 bulkentries.prentries_len = 0;
557 code = ubik_Call(PR_ListEntries, pruclient, 0,
558 flag, startindex, &bulkentries, nextstartindex);
559 *nentries = bulkentries.prentries_len;
560 *entries = bulkentries.prentries_val;
564 pr_CheckEntryByName(name,id,owner,creator)
570 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
571 register afs_int32 code;
572 struct prcheckentry aentry;
574 code = pr_SNameToId(name,id);
575 if (code) return code;
576 if (*id == ANONYMOUSID) return PRNOENT;
577 code = ubik_Call(PR_ListEntry,pruclient,0,*id,&aentry);
578 if (code) return code;
579 /* this should be done in one RPC, but I'm lazy. */
580 code = pr_SIdToName(aentry.owner,owner);
581 if (code) return code;
582 code = pr_SIdToName(aentry.creator,creator);
583 if (code) return code;
587 pr_CheckEntryById(name,id,owner,creator)
593 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
594 register afs_int32 code;
595 struct prcheckentry aentry;
597 code = pr_SIdToName(id,name);
598 if (code) return code;
599 if (id == ANONYMOUSID) return PRNOENT;
600 code = ubik_Call(PR_ListEntry,pruclient,0,id,&aentry);
601 if (code) return code;
602 /* this should be done in one RPC, but I'm lazy. */
603 code = pr_SIdToName(aentry.owner,owner);
604 if (code) return code;
605 code = pr_SIdToName(aentry.creator,creator);
606 if (code) return code;
610 pr_ChangeEntry(oldname,newname,newid,newowner)
616 register afs_int32 code;
620 code = pr_SNameToId(oldname,&id);
621 if (code) return code;
622 if (id == ANONYMOUSID) return PRNOENT;
623 if (newowner && *newowner) {
624 code = pr_SNameToId(newowner,&oid);
625 if (code) return code;
626 if (oid == ANONYMOUSID) return PRNOENT;
628 code = ubik_Call(PR_ChangeEntry,pruclient, 0,id,newname,oid,newid);
632 pr_IsAMemberOf(uname,gname,flag)
637 register afs_int32 code;
643 lnames.namelist_len = 2;
644 lnames.namelist_val = (prname *)malloc(2*PR_MAXNAMELEN);
645 strncpy(lnames.namelist_val[0],uname,PR_MAXNAMELEN);
646 strncpy(lnames.namelist_val[1],gname,PR_MAXNAMELEN);
649 code = pr_NameToId(&lnames,&lids);
651 if (lnames.namelist_val) free(lnames.namelist_val);
652 if (lids.idlist_val) free(lids.idlist_val);
655 code = ubik_Call(PR_IsAMemberOf,pruclient,0,lids.idlist_val[0],lids.idlist_val[1],flag);
656 if (lnames.namelist_val) free(lnames.namelist_val);
657 if (lids.idlist_val) free(lids.idlist_val);
662 pr_ListMaxUserId(mid)
665 register afs_int32 code;
667 code = ubik_Call(PR_ListMax,pruclient,0,mid,&gid);
674 register afs_int32 code;
676 code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
680 pr_ListMaxGroupId(mid)
683 register afs_int32 code;
685 code = ubik_Call(PR_ListMax,pruclient,0,&id,mid);
689 pr_SetMaxGroupId(mid)
692 register afs_int32 code;
696 code = ubik_Call(PR_SetMax,pruclient,0,mid,flag);
700 afs_int32 pr_SetFieldsEntry (id, mask, flags, ngroups, nusers)
703 afs_int32 flags, ngroups, nusers;
705 register afs_int32 code;
707 code = ubik_Call(PR_SetFieldsEntry,pruclient,0,id,mask, flags, ngroups, nusers, 0,0);
716 if (isupper(*s)) *s = tolower(*s);