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"
28 #include "afs/cellconfig.h"
29 #include "afs/afsutil.h"
30 #include "afs/ptclient.h"
31 #include "afs/ptuser.h"
32 #include "afs/pterror.h"
33 #else /* defined(UKERNEL) */
36 #include <sys/types.h>
40 #include <netinet/in.h>
47 #include <afs/cellconfig.h>
48 #include <afs/afsutil.h>
49 #include <afs/com_err.h>
53 #endif /* defined(UKERNEL) */
56 struct ubik_client *pruclient = 0;
57 static afs_int32 lastLevel; /* security level pruclient, if any */
59 static char *whoami = "libprot";
62 pr_Initialize(IN afs_int32 secLevel, IN const char *confDir, IN char *cell)
65 struct rx_connection *serverconns[MAXSERVERS];
66 struct rx_securityClass *sc[3];
67 static struct afsconf_dir *tdir = (struct afsconf_dir *)NULL; /* only do this once */
68 static char tconfDir[100] = "";
69 static char tcell[64] = "";
70 struct ktc_token ttoken;
72 static struct afsconf_cell info;
75 afs_int32 gottdir = 0;
76 afs_int32 refresh = 0;
78 initialize_PT_error_table();
79 initialize_RXK_error_table();
80 initialize_ACFG_error_table();
81 initialize_KTC_error_table();
85 cell = afs_LclCellName;
87 #else /* defined(UKERNEL) */
90 tdir = afsconf_Open(confDir);
92 if (confDir && strcmp(confDir, ""))
94 "%s: Could not open configuration directory: %s.\n",
98 "%s: No configuration directory specified.\n",
104 code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
107 "libprot: Could not get local cell. [%d]\n", code);
112 #endif /* defined(UKERNEL) */
114 if (tdir == NULL || strcmp(confDir, tconfDir) || strcmp(cell, tcell)) {
116 * force re-evaluation. we either don't have an afsconf_dir,
117 * the directory has changed or the cell has changed.
119 if (tdir && !gottdir) {
121 tdir = (struct afsconf_dir *)NULL;
123 pruclient = (struct ubik_client *)NULL;
128 strncpy(tconfDir, confDir, sizeof(tconfDir));
129 strncpy(tcell, cell, sizeof(tcell));
133 #else /* defined(UKERNEL) */
135 tdir = afsconf_Open(confDir);
137 if (confDir && strcmp(confDir, ""))
139 "libprot: Could not open configuration directory: %s.\n",
143 "libprot: No configuration directory specified.\n");
146 #endif /* defined(UKERNEL) */
148 code = afsconf_GetCellInfo(tdir, cell, "afsprot", &info);
150 fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n",
151 cell, confDir, AFSDIR_CELLSERVDB_FILE);
156 /* If we already have a client and it is at the security level we
157 * want, don't get a new one. Unless the security level is 2 in
158 * which case we will get one (and re-read the key file).
160 if (pruclient && (lastLevel == secLevel) && (secLevel != 2)) {
166 fprintf(stderr, "libprot: Could not initialize rx.\n");
174 /* Most callers use secLevel==1, however, the fileserver uses secLevel==2
175 * to force use of the KeyFile. secLevel == 0 implies -noauth was
178 code = afsconf_GetLatestKey(tdir, 0, 0);
180 afs_com_err(whoami, code,
181 "(getting key from local KeyFile)\n");
182 scIndex = 0; /* use noauth */
184 /* If secLevel is two assume we're on a file server and use
185 * ClientAuthSecure if possible. */
186 code = afsconf_ClientAuthSecure(tdir, &sc[2], &scIndex);
188 afs_com_err(whoami, code,
189 "(calling client secure)\n");
190 scIndex = 0; /* use noauth */
194 /* if there was a problem, an unauthenticated conn is returned */
196 } else if (secLevel > 0) {
197 struct ktc_principal sname;
198 strcpy(sname.cell, info.name);
199 sname.instance[0] = 0;
200 strcpy(sname.name, "afs");
201 code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
203 afs_com_err(whoami, code, "(getting token)");
208 if (ttoken.kvno >= 0 && ttoken.kvno <= 256)
209 /* this is a kerberos ticket, set scIndex accordingly */
213 "%s: funny kvno (%d) in ticket, proceeding\n",
214 whoami, ttoken.kvno);
218 rxkad_NewClientSecurityObject((secLevel > 1) ? rxkad_crypt :
219 rxkad_clear, &ttoken.sessionKey,
220 ttoken.kvno, ttoken.ticketLen,
227 if ((scIndex == 0) && (sc[0] == 0))
228 sc[0] = rxnull_NewClientSecurityObject();
229 if ((scIndex == 0) && (secLevel != 0))
231 "%s: Could not get afs tokens, running unauthenticated\n",
234 memset(serverconns, 0, sizeof(serverconns)); /* terminate list!!! */
235 for (i = 0; i < info.numServers; i++)
237 rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
238 info.hostAddr[i].sin_port, PRSRV, sc[scIndex],
241 code = ubik_ClientInit(serverconns, &pruclient);
243 afs_com_err(whoami, code, "ubik client init failed.");
248 code = rxs_Release(sc[scIndex]);
258 code = ubik_ClientDestroy(pruclient);
267 pr_CreateUser(char name[PR_MAXNAMELEN], afs_int32 *id)
269 register afs_int32 code;
273 code = ubik_PR_INewEntry(pruclient, 0, name, *id, 0);
276 code = ubik_PR_NewEntry(pruclient, 0, name, 0, 0, id);
283 pr_CreateGroup(char name[PR_MAXNAMELEN], char owner[PR_MAXNAMELEN], afs_int32 *id)
285 register afs_int32 code;
291 code = pr_SNameToId(owner, &oid);
294 if (oid == ANONYMOUSID)
299 code = ubik_PR_INewEntry(pruclient, 0, name, *id, oid);
302 code = ubik_PR_NewEntry(pruclient, 0, name, flags, oid, id);
308 pr_Delete(char *name)
310 register afs_int32 code;
314 code = pr_SNameToId(name, &id);
317 if (id == ANONYMOUSID)
319 code = ubik_PR_Delete(pruclient, 0, id);
324 pr_DeleteByID(afs_int32 id)
326 register afs_int32 code;
328 code = ubik_PR_Delete(pruclient, 0, id);
333 pr_AddToGroup(char *user, char *group)
335 register afs_int32 code;
339 lnames.namelist_len = 2;
340 lnames.namelist_val = (prname *) malloc(2 * PR_MAXNAMELEN);
341 strncpy(lnames.namelist_val[0], user, PR_MAXNAMELEN);
342 strncpy(lnames.namelist_val[1], group, PR_MAXNAMELEN);
345 code = pr_NameToId(&lnames, &lids);
348 /* if here, still could be missing an entry */
349 if (lids.idlist_val[0] == ANONYMOUSID
350 || lids.idlist_val[1] == ANONYMOUSID) {
355 ubik_PR_AddToGroup(pruclient, 0, lids.idlist_val[0],
358 if (lnames.namelist_val)
359 free(lnames.namelist_val);
361 free(lids.idlist_val);
366 pr_RemoveUserFromGroup(char *user, char *group)
368 register afs_int32 code;
372 lnames.namelist_len = 2;
373 lnames.namelist_val = (prname *) malloc(2 * PR_MAXNAMELEN);
374 strncpy(lnames.namelist_val[0], user, PR_MAXNAMELEN);
375 strncpy(lnames.namelist_val[1], group, PR_MAXNAMELEN);
378 code = pr_NameToId(&lnames, &lids);
382 if (lids.idlist_val[0] == ANONYMOUSID
383 || lids.idlist_val[1] == ANONYMOUSID) {
388 ubik_PR_RemoveFromGroup(pruclient, 0, lids.idlist_val[0],
391 if (lnames.namelist_val)
392 free(lnames.namelist_val);
394 free(lids.idlist_val);
400 pr_NameToId(namelist *names, idlist *ids)
402 register afs_int32 code;
403 register afs_int32 i;
405 for (i = 0; i < names->namelist_len; i++)
406 stolower(names->namelist_val[i]);
407 code = ubik_PR_NameToID(pruclient, 0, names, ids);
412 pr_SNameToId(char name[PR_MAXNAMELEN], afs_int32 *id)
416 register afs_int32 code;
420 lnames.namelist_len = 1;
421 lnames.namelist_val = (prname *) malloc(PR_MAXNAMELEN);
423 strncpy(lnames.namelist_val[0], name, PR_MAXNAMELEN);
424 code = ubik_PR_NameToID(pruclient, 0, &lnames, &lids);
425 if (lids.idlist_val) {
426 *id = *lids.idlist_val;
427 free(lids.idlist_val);
429 if (lnames.namelist_val)
430 free(lnames.namelist_val);
435 pr_IdToName(idlist *ids, namelist *names)
437 register afs_int32 code;
439 code = ubik_PR_IDToName(pruclient, 0, ids, names);
444 pr_SIdToName(afs_int32 id, char name[PR_MAXNAMELEN])
448 register afs_int32 code;
451 lids.idlist_val = (afs_int32 *) malloc(sizeof(afs_int32));
452 *lids.idlist_val = id;
453 lnames.namelist_len = 0;
454 lnames.namelist_val = 0;
455 code = ubik_PR_IDToName(pruclient, 0, &lids, &lnames);
456 if (lnames.namelist_val) {
457 strncpy(name, lnames.namelist_val[0], PR_MAXNAMELEN);
458 free(lnames.namelist_val);
461 free(lids.idlist_val);
466 pr_GetCPS(afs_int32 id, prlist *CPS)
468 register afs_int32 code;
472 code = ubik_PR_GetCPS(pruclient, 0, id, CPS, &over);
473 if (code != PRSUCCESS)
476 /* do something about this, probably make a new call */
477 /* don't forget there's a hard limit in the interface */
478 fprintf(stderr, "membership list for id %d exceeds display limit\n",
485 pr_GetCPS2(afs_int32 id, afs_int32 host, prlist *CPS)
487 register afs_int32 code;
491 code = ubik_PR_GetCPS2(pruclient, 0, id, host, CPS, &over);
492 if (code != PRSUCCESS)
495 /* do something about this, probably make a new call */
496 /* don't forget there's a hard limit in the interface */
497 fprintf(stderr, "membership list for id %d exceeds display limit\n",
504 pr_GetHostCPS(afs_int32 host, prlist *CPS)
506 register afs_int32 code;
510 code = ubik_PR_GetHostCPS(pruclient, 0, host, CPS, &over);
511 if (code != PRSUCCESS)
514 /* do something about this, probably make a new call */
515 /* don't forget there's a hard limit in the interface */
517 "membership list for host id %d exceeds display limit\n",
524 pr_ListMembers(char *group, namelist *lnames)
526 register afs_int32 code;
529 code = pr_SNameToId(group, &gid);
532 if (gid == ANONYMOUSID)
534 code = pr_IDListMembers(gid, lnames);
539 pr_ListOwned(afs_int32 oid, namelist *lnames, afs_int32 *moreP)
541 register afs_int32 code;
545 alist.prlist_len = 0;
546 alist.prlist_val = 0;
547 code = ubik_PR_ListOwned(pruclient, 0, oid, &alist, moreP);
551 /* Remain backwards compatible when moreP was a T/F bit */
552 fprintf(stderr, "membership list for id %d exceeds display limit\n",
556 lids = (idlist *) & alist;
557 code = pr_IdToName(lids, lnames);
560 if (alist.prlist_val)
561 free(alist.prlist_val);
566 pr_IDListMembers(afs_int32 gid, namelist *lnames)
568 register afs_int32 code;
573 alist.prlist_len = 0;
574 alist.prlist_val = 0;
575 code = ubik_PR_ListElements(pruclient, 0, gid, &alist, &over);
579 fprintf(stderr, "membership list for id %d exceeds display limit\n",
582 lids = (idlist *) & alist;
583 code = pr_IdToName(lids, lnames);
586 if (alist.prlist_val)
587 free(alist.prlist_val);
592 pr_ListEntry(afs_int32 id, struct prcheckentry *aentry)
594 register afs_int32 code;
596 code = ubik_PR_ListEntry(pruclient, 0, id, aentry);
601 pr_ListEntries(int flag, afs_int32 startindex, afs_int32 *nentries, struct prlistentries **entries, afs_int32 *nextstartindex)
604 prentries bulkentries;
608 *nextstartindex = -1;
609 bulkentries.prentries_val = 0;
610 bulkentries.prentries_len = 0;
613 ubik_PR_ListEntries(pruclient, 0, flag, startindex,
614 &bulkentries, nextstartindex);
615 *nentries = bulkentries.prentries_len;
616 *entries = bulkentries.prentries_val;
621 pr_CheckEntryByName(char *name, afs_int32 *id, char *owner, char *creator)
623 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
624 register afs_int32 code;
625 struct prcheckentry aentry;
627 code = pr_SNameToId(name, id);
630 if (*id == ANONYMOUSID)
632 code = ubik_PR_ListEntry(pruclient, 0, *id, &aentry);
635 /* this should be done in one RPC, but I'm lazy. */
636 code = pr_SIdToName(aentry.owner, owner);
639 code = pr_SIdToName(aentry.creator, creator);
646 pr_CheckEntryById(char *name, afs_int32 id, char *owner, char *creator)
648 /* struct prcheckentry returns other things, which aren't useful to show at this time. */
649 register afs_int32 code;
650 struct prcheckentry aentry;
652 code = pr_SIdToName(id, name);
655 if (id == ANONYMOUSID)
657 code = ubik_PR_ListEntry(pruclient, 0, id, &aentry);
660 /* this should be done in one RPC, but I'm lazy. */
661 code = pr_SIdToName(aentry.owner, owner);
664 code = pr_SIdToName(aentry.creator, creator);
671 pr_ChangeEntry(char *oldname, char *newname, afs_int32 *newid, char *newowner)
673 register afs_int32 code;
677 code = pr_SNameToId(oldname, &id);
680 if (id == ANONYMOUSID)
682 if (newowner && *newowner) {
683 code = pr_SNameToId(newowner, &oid);
686 if (oid == ANONYMOUSID)
690 code = ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid, *newid);
692 code = ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid, 0);
697 pr_IsAMemberOf(char *uname, char *gname, afs_int32 *flag)
699 register afs_int32 code;
705 lnames.namelist_len = 2;
706 lnames.namelist_val = (prname *) malloc(2 * PR_MAXNAMELEN);
707 strncpy(lnames.namelist_val[0], uname, PR_MAXNAMELEN);
708 strncpy(lnames.namelist_val[1], gname, PR_MAXNAMELEN);
711 code = pr_NameToId(&lnames, &lids);
713 if (lnames.namelist_val)
714 free(lnames.namelist_val);
716 free(lids.idlist_val);
720 ubik_PR_IsAMemberOf(pruclient, 0, lids.idlist_val[0],
721 lids.idlist_val[1], flag);
722 if (lnames.namelist_val)
723 free(lnames.namelist_val);
725 free(lids.idlist_val);
730 pr_ListMaxUserId(afs_int32 *mid)
732 register afs_int32 code;
734 code = ubik_PR_ListMax(pruclient, 0, mid, &gid);
739 pr_SetMaxUserId(afs_int32 mid)
741 register afs_int32 code;
743 code = ubik_PR_SetMax(pruclient, 0, mid, flag);
748 pr_ListMaxGroupId(afs_int32 *mid)
750 register afs_int32 code;
752 code = ubik_PR_ListMax(pruclient, 0, &id, mid);
757 pr_SetMaxGroupId(afs_int32 mid)
759 register afs_int32 code;
763 code = ubik_PR_SetMax(pruclient, 0, mid, flag);
768 pr_SetFieldsEntry(afs_int32 id, afs_int32 mask, afs_int32 flags, afs_int32 ngroups, afs_int32 nusers)
770 register afs_int32 code;
773 ubik_PR_SetFieldsEntry(pruclient, 0, id, mask, flags, ngroups,