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>
21 #include "afs/sysincludes.h"
22 #include "afs_usrops.h"
23 #include "afsincludes.h"
29 #include "afs/cellconfig.h"
30 #include "afs/afsutil.h"
31 #include "afs/ptclient.h"
32 #include "afs/ptuser.h"
33 #include "afs/pterror.h"
34 #else /* defined(UKERNEL) */
37 #include <sys/types.h>
41 #include <netinet/in.h>
55 #include <afs/cellconfig.h>
56 #include <afs/afsutil.h>
60 #endif /* defined(UKERNEL) */
63 struct ubik_client *pruclient = 0;
64 static afs_int32 lastLevel; /* security level pruclient, if any */
66 static char *whoami = "libprot";
69 pr_Initialize(IN afs_int32 secLevel, IN char *confDir, IN char *cell)
72 struct rx_connection *serverconns[MAXSERVERS];
73 struct rx_securityClass *sc[3];
74 static struct afsconf_dir *tdir = (struct afsconf_dir *)0; /* only do this once */
75 static char tconfDir[100] = "";
76 static char tcell[64] = "";
77 struct ktc_token ttoken;
79 static struct afsconf_cell info;
82 afs_int32 gottdir = 0;
83 afs_int32 refresh = 0;
85 initialize_PT_error_table();
86 initialize_RXK_error_table();
87 initialize_ACFG_error_table();
88 initialize_KTC_error_table();
92 cell = afs_LclCellName;
94 #else /* defined(UKERNEL) */
97 tdir = afsconf_Open(confDir);
99 if (confDir && strcmp(confDir, ""))
101 "libprot: Could not open configuration directory: %s.\n",
105 "libprot: No configuration directory specified.\n");
110 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
113 "libprot: Could not get local cell. [%d]\n", code);
118 #endif /* defined(UKERNEL) */
120 if (tdir == 0 || strcmp(confDir, tconfDir) || strcmp(cell, tcell)) {
122 * force re-evaluation. we either don't have an afsconf_dir,
123 * the directory has changed or the cell has changed.
125 if (tdir && !gottdir) {
127 tdir = (struct afsconf_dir *)0;
129 pruclient = (struct ubik_client *)0;
134 strncpy(tconfDir, confDir, sizeof(tconfDir));
135 strncpy(tcell, cell, sizeof(tcell));
139 #else /* defined(UKERNEL) */
141 tdir = afsconf_Open(confDir);
143 if (confDir && strcmp(confDir, ""))
145 "libprot: Could not open configuration directory: %s.\n",
149 "libprot: No configuration directory specified.\n");
152 #endif /* defined(UKERNEL) */
154 code = afsconf_GetCellInfo(tdir, cell, "afsprot", &info);
156 fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n",
157 cell, confDir, AFSDIR_CELLSERVDB_FILE);
162 /* If we already have a client and it is at the security level we
163 * want, don't get a new one. Unless the security level is 2 in
164 * which case we will get one (and re-read the key file).
166 if (pruclient && (lastLevel == secLevel) && (secLevel != 2))
171 fprintf(stderr, "libprot: Could not initialize rx.\n");
179 /* Most callers use secLevel==1, however, the fileserver uses secLevel==2
180 * to force use of the KeyFile. secLevel == 0 implies -noauth was
182 if ((secLevel == 2) && (afsconf_GetLatestKey(tdir, 0, 0) == 0)) {
183 /* If secLevel is two assume we're on a file server and use
184 * ClientAuthSecure if possible. */
185 code = afsconf_ClientAuthSecure(tdir, &sc[2], &scIndex);
188 "libprot: clientauthsecure returns %d %s"
189 " (so trying noauth)\n", code, error_message(code));
191 scIndex = 0; /* use noauth */
193 /* if there was a problem, an unauthenticated conn is returned */
195 } else if (secLevel > 0) {
196 struct ktc_principal sname;
197 strcpy(sname.cell, info.name);
198 sname.instance[0] = 0;
199 strcpy(sname.name, "afs");
200 code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
204 if (ttoken.kvno >= 0 && ttoken.kvno <= 256)
205 /* this is a kerberos ticket, set scIndex accordingly */
209 "libprot: funny kvno (%d) in ticket, proceeding\n",
214 rxkad_NewClientSecurityObject(rxkad_clear, &ttoken.sessionKey,
215 ttoken.kvno, ttoken.ticketLen,
221 if ((scIndex == 0) && (sc[0] == 0))
222 sc[0] = rxnull_NewClientSecurityObject();
223 if ((scIndex == 0) && (secLevel != 0))
224 com_err(whoami, code,
225 "Could not get afs tokens, running unauthenticated.");
227 memset(serverconns, 0, sizeof(serverconns)); /* terminate list!!! */
228 for (i = 0; i < info.numServers; i++)
230 rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
231 info.hostAddr[i].sin_port, PRSRV, sc[scIndex],
234 code = ubik_ClientInit(serverconns, &pruclient);
236 com_err(whoami, code, "ubik client init failed.");
241 code = rxs_Release(sc[scIndex]);
251 code = ubik_ClientDestroy(pruclient);
260 pr_CreateUser(char name[PR_MAXNAMELEN], afs_int32 *id)
262 register afs_int32 code;
266 code = ubik_Call(PR_INewEntry, pruclient, 0, name, *id, 0);
269 code = ubik_Call(PR_NewEntry, pruclient, 0, name, 0, 0, id);
276 pr_CreateGroup(char name[PR_MAXNAMELEN], char owner[PR_MAXNAMELEN], afs_int32 *id)
278 register afs_int32 code;
284 code = pr_SNameToId(owner, &oid);
287 if (oid == ANONYMOUSID)
292 code = ubik_Call(PR_INewEntry, pruclient, 0, name, *id, oid);
295 code = ubik_Call(PR_NewEntry, pruclient, 0, name, flags, oid, id);
301 pr_Delete(char *name)
303 register afs_int32 code;
307 code = pr_SNameToId(name, &id);
310 if (id == ANONYMOUSID)
312 code = ubik_Call(PR_Delete, pruclient, 0, id);
317 pr_DeleteByID(afs_int32 id)
319 register afs_int32 code;
321 code = ubik_Call(PR_Delete, pruclient, 0, id);
326 pr_AddToGroup(char *user, char *group)
328 register afs_int32 code;
332 lnames.namelist_len = 2;
333 lnames.namelist_val = (prname *) malloc(2 * PR_MAXNAMELEN);
334 strncpy(lnames.namelist_val[0], user, PR_MAXNAMELEN);
335 strncpy(lnames.namelist_val[1], group, PR_MAXNAMELEN);
338 code = pr_NameToId(&lnames, &lids);
341 /* if here, still could be missing an entry */
342 if (lids.idlist_val[0] == ANONYMOUSID
343 || lids.idlist_val[1] == ANONYMOUSID) {
348 ubik_Call(PR_AddToGroup, pruclient, 0, lids.idlist_val[0],
351 if (lnames.namelist_val)
352 free(lnames.namelist_val);
354 free(lids.idlist_val);
359 pr_RemoveUserFromGroup(char *user, char *group)
361 register afs_int32 code;
365 lnames.namelist_len = 2;
366 lnames.namelist_val = (prname *) malloc(2 * PR_MAXNAMELEN);
367 strncpy(lnames.namelist_val[0], user, PR_MAXNAMELEN);
368 strncpy(lnames.namelist_val[1], group, PR_MAXNAMELEN);
371 code = pr_NameToId(&lnames, &lids);
375 if (lids.idlist_val[0] == ANONYMOUSID
376 || lids.idlist_val[1] == ANONYMOUSID) {
381 ubik_Call(PR_RemoveFromGroup, pruclient, 0, lids.idlist_val[0],
384 if (lnames.namelist_val)
385 free(lnames.namelist_val);
387 free(lids.idlist_val);
393 pr_NameToId(namelist *names, idlist *ids)
395 register afs_int32 code;
396 register afs_int32 i;
398 for (i = 0; i < names->namelist_len; i++)
399 stolower(names->namelist_val[i]);
400 code = ubik_Call(PR_NameToID, pruclient, 0, names, ids);
405 pr_SNameToId(char name[PR_MAXNAMELEN], afs_int32 *id)
409 register afs_int32 code;
413 lnames.namelist_len = 1;
414 lnames.namelist_val = (prname *) malloc(PR_MAXNAMELEN);
416 strncpy(lnames.namelist_val[0], name, PR_MAXNAMELEN);
417 code = ubik_Call(PR_NameToID, pruclient, 0, &lnames, &lids);
418 if (lids.idlist_val) {
419 *id = *lids.idlist_val;
420 free(lids.idlist_val);
422 if (lnames.namelist_val)
423 free(lnames.namelist_val);
428 pr_IdToName(idlist *ids, namelist *names)
430 register afs_int32 code;
432 code = ubik_Call(PR_IDToName, pruclient, 0, ids, names);
437 pr_SIdToName(afs_int32 id, char name[PR_MAXNAMELEN])
441 register afs_int32 code;
444 lids.idlist_val = (afs_int32 *) malloc(sizeof(afs_int32));
445 *lids.idlist_val = id;
446 lnames.namelist_len = 0;
447 lnames.namelist_val = 0;
448 code = ubik_Call(PR_IDToName, pruclient, 0, &lids, &lnames);
449 if (lnames.namelist_val) {
450 strncpy(name, lnames.namelist_val[0], PR_MAXNAMELEN);
451 free(lnames.namelist_val);
454 free(lids.idlist_val);
459 pr_GetCPS(afs_int32 id, prlist *CPS)
461 register afs_int32 code;
465 code = ubik_Call(PR_GetCPS, pruclient, 0, id, CPS, &over);
466 if (code != PRSUCCESS)
469 /* do something about this, probably make a new call */
470 /* don't forget there's a hard limit in the interface */
471 fprintf(stderr, "membership list for id %d exceeds display limit\n",
478 pr_GetCPS2(afs_int32 id, afs_int32 host, prlist *CPS)
480 register afs_int32 code;
484 code = ubik_Call(PR_GetCPS2, pruclient, 0, id, host, CPS, &over);
485 if (code != PRSUCCESS)
488 /* do something about this, probably make a new call */
489 /* don't forget there's a hard limit in the interface */
490 fprintf(stderr, "membership list for id %d exceeds display limit\n",
497 pr_GetHostCPS(afs_int32 host, prlist *CPS)
499 register afs_int32 code;
503 code = ubik_Call(PR_GetHostCPS, pruclient, 0, host, CPS, &over);
504 if (code != PRSUCCESS)
507 /* do something about this, probably make a new call */
508 /* don't forget there's a hard limit in the interface */
510 "membership list for host id %d exceeds display limit\n",
517 pr_ListMembers(char *group, namelist *lnames)
519 register afs_int32 code;
522 code = pr_SNameToId(group, &gid);
525 if (gid == ANONYMOUSID)
527 code = pr_IDListMembers(gid, lnames);
532 pr_ListOwned(afs_int32 oid, namelist *lnames, afs_int32 *moreP)
534 register afs_int32 code;
538 alist.prlist_len = 0;
539 alist.prlist_val = 0;
540 code = ubik_Call(PR_ListOwned, pruclient, 0, oid, &alist, moreP);
544 /* Remain backwards compatible when moreP was a T/F bit */
545 fprintf(stderr, "membership list for id %d exceeds display limit\n",
549 lids = (idlist *) & alist;
550 code = pr_IdToName(lids, lnames);
553 if (alist.prlist_val)
554 free(alist.prlist_val);
559 pr_IDListMembers(afs_int32 gid, namelist *lnames)
561 register afs_int32 code;
566 alist.prlist_len = 0;
567 alist.prlist_val = 0;
568 code = ubik_Call(PR_ListElements, pruclient, 0, gid, &alist, &over);
572 fprintf(stderr, "membership list for id %d exceeds display limit\n",
575 lids = (idlist *) & alist;
576 code = pr_IdToName(lids, lnames);
579 if (alist.prlist_val)
580 free(alist.prlist_val);
585 pr_ListEntry(afs_int32 id, struct prcheckentry *aentry)
587 register afs_int32 code;
589 code = ubik_Call(PR_ListEntry, pruclient, 0, id, aentry);
594 pr_ListEntries(int flag, afs_int32 startindex, afs_int32 *nentries, struct prlistentries **entries, afs_int32 *nextstartindex)
597 prentries bulkentries;
601 *nextstartindex = -1;
602 bulkentries.prentries_val = 0;
603 bulkentries.prentries_len = 0;
606 ubik_Call(PR_ListEntries, pruclient, 0, flag, startindex,
607 &bulkentries, nextstartindex);
608 *nentries = bulkentries.prentries_len;
609 *entries = bulkentries.prentries_val;
614 pr_CheckEntryByName(char *name, afs_int32 *id, char *owner, char *creator)
616 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
617 register afs_int32 code;
618 struct prcheckentry aentry;
620 code = pr_SNameToId(name, id);
623 if (*id == ANONYMOUSID)
625 code = ubik_Call(PR_ListEntry, pruclient, 0, *id, &aentry);
628 /* this should be done in one RPC, but I'm lazy. */
629 code = pr_SIdToName(aentry.owner, owner);
632 code = pr_SIdToName(aentry.creator, creator);
639 pr_CheckEntryById(char *name, afs_int32 id, char *owner, char *creator)
641 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
642 register afs_int32 code;
643 struct prcheckentry aentry;
645 code = pr_SIdToName(id, name);
648 if (id == ANONYMOUSID)
650 code = ubik_Call(PR_ListEntry, pruclient, 0, id, &aentry);
653 /* this should be done in one RPC, but I'm lazy. */
654 code = pr_SIdToName(aentry.owner, owner);
657 code = pr_SIdToName(aentry.creator, creator);
664 pr_ChangeEntry(char *oldname, char *newname, afs_int32 *newid, char *newowner)
666 register afs_int32 code;
670 code = pr_SNameToId(oldname, &id);
673 if (id == ANONYMOUSID)
675 if (newowner && *newowner) {
676 code = pr_SNameToId(newowner, &oid);
679 if (oid == ANONYMOUSID)
682 code = ubik_Call(PR_ChangeEntry, pruclient, 0, id, newname, oid, newid);
687 pr_IsAMemberOf(char *uname, char *gname, afs_int32 *flag)
689 register afs_int32 code;
695 lnames.namelist_len = 2;
696 lnames.namelist_val = (prname *) malloc(2 * PR_MAXNAMELEN);
697 strncpy(lnames.namelist_val[0], uname, PR_MAXNAMELEN);
698 strncpy(lnames.namelist_val[1], gname, PR_MAXNAMELEN);
701 code = pr_NameToId(&lnames, &lids);
703 if (lnames.namelist_val)
704 free(lnames.namelist_val);
706 free(lids.idlist_val);
710 ubik_Call(PR_IsAMemberOf, pruclient, 0, lids.idlist_val[0],
711 lids.idlist_val[1], flag);
712 if (lnames.namelist_val)
713 free(lnames.namelist_val);
715 free(lids.idlist_val);
720 pr_ListMaxUserId(afs_int32 *mid)
722 register afs_int32 code;
724 code = ubik_Call(PR_ListMax, pruclient, 0, mid, &gid);
729 pr_SetMaxUserId(afs_int32 mid)
731 register afs_int32 code;
733 code = ubik_Call(PR_SetMax, pruclient, 0, mid, flag);
738 pr_ListMaxGroupId(afs_int32 *mid)
740 register afs_int32 code;
742 code = ubik_Call(PR_ListMax, pruclient, 0, &id, mid);
747 pr_SetMaxGroupId(afs_int32 mid)
749 register afs_int32 code;
753 code = ubik_Call(PR_SetMax, pruclient, 0, mid, flag);
758 pr_SetFieldsEntry(afs_int32 id, afs_int32 mask, afs_int32 flags, afs_int32 ngroups, afs_int32 nusers)
760 register afs_int32 code;
763 ubik_Call(PR_SetFieldsEntry, pruclient, 0, id, mask, flags, ngroups,