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 /* This file implements configuration functions in the following categories:
11 * cfg_Host*() - manipulate static server configuration information.
14 #include <afsconfig.h>
15 #include <afs/param.h>
25 #include <sys/types.h>
32 #include <WINNT/vptab.h>
33 #include <WINNT/afsreg.h>
38 #endif /* AFS_NT40_ENV */
41 #include <rx/rxstat.h>
43 #include <afs/afs_Admin.h>
44 #include <afs/afs_AdminErrors.h>
45 #include <afs/afs_utilAdmin.h>
46 #include <afs/afs_bosAdmin.h>
47 #include <afs/afs_clientAdmin.h>
48 #include <afs/afs_kasAdmin.h>
49 #include <afs/afs_ptsAdmin.h>
52 #include <afs/kautils.h>
53 #include <afs/bnode.h>
54 #include <afs/prerror.h>
56 #include <afs/dirpath.h>
57 #include <afs/cellconfig.h>
59 #include "cfginternal.h"
60 #include "afs_cfgAdmin.h"
61 #include "../adminutil/afs_AdminInternal.h"
65 /* Local declarations and definitions */
68 KasKeyIsZero(kas_encryptionKey_t * kasKey);
71 KasKeyEmbeddedInString(const char *keyString, kas_encryptionKey_t * kasKey);
76 /* ---------------- Exported Server Host functions ------------------ */
80 * cfg_HostQueryStatus() -- Query status of static server configuration
81 * on host, i.e., status of required configuration files, etc.
82 * Upon successful completion *configStP is set to the server
83 * configuration status, with a value of zero (0) indicating that
84 * the configuration is valid.
86 * If server configuration is not valid then *cellNameP is set to NULL;
87 * otherwise, *cellNameP is an allocated buffer containing server cell.
89 * Warning: in determining if server configuration is valid, no check
90 * is made for consistency with other servers in cell; also, the
91 * internal consistency of configuration files may not be verified.
94 cfg_HostQueryStatus(const char *hostName, /* name of host */
95 afs_status_p configStP, /* server config status */
96 char **cellNameP, /* server's cell */
98 { /* completion status */
100 afs_status_t tst2, tst = 0;
101 afs_status_t serverSt = 0;
102 char *serverCellName = NULL;
104 /* validate parameters */
106 if (hostName == NULL || *hostName == '\0') {
107 tst = ADMCFGHOSTNAMENULL;
108 } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) {
109 tst = ADMCFGHOSTNAMETOOLONG;
110 } else if (configStP == NULL) {
111 tst = ADMCFGCONFIGSTATUSPNULL;
112 } else if (cellNameP == NULL) {
113 tst = ADMCFGCELLNAMEPNULL;
116 /* remote configuration not yet supported; hostName must be local host */
121 if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) {
123 } else if (!isLocal) {
124 tst = ADMCFGNOTSUPPORTED;
128 /* check for existence and readability of required server config files */
132 const char *cfgfile[4];
134 cfgfile[0] = AFSDIR_SERVER_THISCELL_FILEPATH;
135 cfgfile[1] = AFSDIR_SERVER_CELLSERVDB_FILEPATH;
136 cfgfile[2] = AFSDIR_SERVER_KEY_FILEPATH;
137 cfgfile[3] = AFSDIR_SERVER_ULIST_FILEPATH;
139 for (i = 0; i < 4; i++) {
141 if ((fd = open(cfgfile[i], O_RDONLY)) < 0) {
148 if (errno == EACCES) {
151 serverSt = ADMCFGSERVERBASICINFOINVALID;
156 /* verify the required server config files to the degree possible */
158 if (tst == 0 && serverSt == 0) {
159 struct afsconf_dir *confdir;
161 if ((confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH)) == NULL) {
162 /* one or more config files appears to be invalid */
163 serverSt = ADMCFGSERVERBASICINFOINVALID;
165 struct afsconf_entry *cellentry;
167 if (confdir->cellName == NULL || *confdir->cellName == '\0') {
168 /* no cell set for server */
169 serverSt = ADMCFGSERVERNOTINCELL;
170 } else if (confdir->keystr == NULL || confdir->keystr->nkeys == 0) {
172 serverSt = ADMCFGSERVERNOKEYS;
174 for (cellentry = confdir->entries; cellentry != NULL;
175 cellentry = cellentry->next) {
177 (confdir->cellName, cellentry->cellInfo.name)) {
182 if (cellentry == NULL) {
183 serverSt = ADMCFGSERVERCELLNOTINDB;
184 } else if (cellentry->cellInfo.numServers <= 0) {
185 serverSt = ADMCFGSERVERCELLHASNODBENTRIES;
189 if (tst == 0 && serverSt == 0) {
190 /* everything looks good; malloc cell name buffer to return */
192 (char *)malloc(strlen(cellentry->cellInfo.name) + 1);
193 if (serverCellName == NULL) {
196 strcpy(serverCellName, cellentry->cellInfo.name);
200 (void)afsconf_Close(confdir);
205 /* return server status and cell name */
206 *configStP = serverSt;
209 *cellNameP = serverCellName;
214 /* indicate failure */
217 /* free cell name if allocated before failure */
218 if (serverCellName != NULL) {
219 free(serverCellName);
230 * cfg_HostOpen() -- Obtain host configuration handle.
233 cfg_HostOpen(void *cellHandle, /* cell handle */
234 const char *hostName, /* name of host to configure */
235 void **hostHandleP, /* host config handle */
237 { /* completion status */
239 afs_status_t tst2, tst = 0;
241 char fullHostName[MAXHOSTCHARS];
243 /* validate parameters and resolve host name to fully qualified name */
245 if (!CellHandleIsValid(cellHandle, &tst2)) {
247 } else if (hostName == NULL || *hostName == '\0') {
248 tst = ADMCFGHOSTNAMENULL;
249 } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) {
250 tst = ADMCFGHOSTNAMETOOLONG;
251 } else if (hostHandleP == NULL) {
252 tst = ADMCFGHOSTHANDLEPNULL;
253 } else if (!cfgutil_HostNameGetFull(hostName, fullHostName, &tst2)) {
257 /* remote configuration not yet supported; hostName must be local host */
262 if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) {
264 } else if (!isLocal) {
265 tst = ADMCFGNOTSUPPORTED;
269 /* allocate a host configuration handle */
274 if ((cfg_host = (cfg_host_p) malloc(sizeof(cfg_host_t))) == NULL) {
276 } else if ((localHostName = (char *)malloc(strlen(fullHostName) + 1))
281 /* initialize handle */
282 cfg_host->begin_magic = BEGIN_MAGIC;
283 cfg_host->is_valid = 1;
284 cfg_host->hostName = localHostName;
285 cfg_host->is_local = 1; /* not yet supporting remote config */
286 cfg_host->cellHandle = cellHandle;
287 cfg_host->bosHandle = NULL;
288 cfg_host->end_magic = END_MAGIC;
290 strcpy(localHostName, fullHostName);
292 if (!afsclient_CellNameGet
293 (cfg_host->cellHandle, &cfg_host->cellName, &tst2)) {
295 } else if (pthread_mutex_init(&cfg_host->mutex, NULL)) {
300 /* cell name lookup or mutex initialization failed */
308 /* success; return host config handle to user */
309 *hostHandleP = cfg_host;
311 /* indicate failure */
322 * cfg_HostClose() -- Release host configuration handle.
325 cfg_HostClose(void *hostHandle, /* host config handle */
327 { /* completion status */
329 afs_status_t tst2, tst = 0;
330 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
332 /* validate parameters */
334 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
338 /* free handle; can assume no other thread using this handle */
341 /* mark cfg handle invalid in case use after free (bug catcher) */
342 cfg_host->is_valid = 0;
344 if (cfg_host->bosHandle != NULL) {
345 if (!bos_ServerClose(cfg_host->bosHandle, &tst2)) {
349 free(cfg_host->hostName);
350 (void)pthread_mutex_destroy(&cfg_host->mutex);
365 * cfg_HostSetCell() -- Define server cell membership for host.
367 * The cellDbHosts argument is a multistring containing the names of
368 * the existing database servers already configured in the cell; this
369 * multistring list can be obtained via cfg_CellServDbEnumerate().
370 * If configuring the first server in a new cell then the cellDbHosts
371 * list contains only the name of that host.
373 * Note: The names in cellDbHosts MUST exactly match those in the
374 * cell-wide server CellServDB; using cfg_CellServDbEnumerate()
375 * is highly recommended.
378 cfg_HostSetCell(void *hostHandle, /* host config handle */
379 const char *cellName, /* cell name */
380 const char *cellDbHosts, /* cell database hosts */
382 { /* completion status */
384 afs_status_t tst2, tst = 0;
385 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
387 /* validate parameters */
389 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
391 } else if (cellName == NULL || *cellName == '\0') {
392 tst = ADMCFGCELLNAMENULL;
393 } else if (strlen(cellName) > (MAXCELLCHARS - 1)) {
394 tst = ADMCFGCELLNAMETOOLONG;
395 } else if (!cfgutil_HostHandleCellNameCompatible(cfg_host, cellName)) {
396 tst = ADMCFGCELLNAMECONFLICT;
397 } else if (cellDbHosts == NULL || *cellDbHosts == '\0') {
398 tst = ADMCFGCELLDBHOSTSNULL;
401 /* remote configuration not yet supported in this function */
404 if (!cfg_host->is_local) {
405 tst = ADMCFGNOTSUPPORTED;
409 /* define server cell and cell database hosts */
412 const char *dbHost = cellDbHosts;
413 struct afsconf_cell hostCell;
414 memset(&hostCell, 0, sizeof(hostCell));
416 strcpy(hostCell.name, cellName);
417 hostCell.numServers = 0;
419 while (*dbHost != '\0' && tst == 0) {
420 /* fill in each database host */
421 size_t dbHostLen = strlen(dbHost);
423 if (dbHostLen > (MAXHOSTCHARS - 1)) {
424 tst = ADMCFGHOSTNAMETOOLONG;
425 } else if (hostCell.numServers >= MAXHOSTSPERCELL) {
426 tst = ADMCFGCELLDBHOSTCOUNTTOOLARGE;
428 strcpy(hostCell.hostName[hostCell.numServers++], dbHost);
429 dbHost += dbHostLen + 1;
434 /* create server ThisCell/CellServDB dir if it does not exist */
436 (void)mkdir(AFSDIR_USR_DIRPATH);
437 (void)mkdir(AFSDIR_SERVER_AFS_DIRPATH);
438 (void)mkdir(AFSDIR_SERVER_ETC_DIRPATH);
440 (void)mkdir(AFSDIR_USR_DIRPATH, 0755);
441 (void)mkdir(AFSDIR_SERVER_AFS_DIRPATH, 0755);
442 (void)mkdir(AFSDIR_SERVER_ETC_DIRPATH, 0755);
444 if (afsconf_SetCellInfo
445 (NULL, AFSDIR_SERVER_ETC_DIRPATH, &hostCell)) {
446 /* failed; most likely cause is bad host name */
447 tst = ADMCFGSERVERSETCELLFAILED;
463 * cfg_HostSetAfsPrincipal() -- Put AFS server principal (afs) key in
464 * host's KeyFile; principal is created if it does not exist.
466 * If first server host in cell, passwd must be initial password for
467 * the afs principal; the afs principal is created.
469 * If additional server host, passwd can be specified or NULL; the
470 * afs principal must already exist by definition. If passwd is NULL
471 * then an attempt is made to fetch the afs key. If the key fetch fails
472 * because pre 3.5 database servers are in use (which will only return a
473 * key checksum) then the function fails with a return status of
474 * ADMCFGAFSKEYNOTAVAILABLE; in this case the function should be called
475 * again with passwd specified. If passwd is specified (not NULL) but the
476 * password key fails a checksum comparison with the current afs key
477 * then the function fails with a return status of ADMCFGAFSPASSWDINVALID.
479 * ASSUMPTIONS: Client configured and BOS server started; if first host in
480 * cell then Authentication server must be started as well.
483 cfg_HostSetAfsPrincipal(void *hostHandle, /* host config handle */
484 short isFirst, /* first server in cell flag */
485 const char *passwd, /* afs initial password */
487 { /* completion status */
489 afs_status_t tst2, tst = 0;
490 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
492 /* validate parameters */
494 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
496 } else if ((isFirst && passwd == NULL)
497 || (passwd != NULL && *passwd == '\0')) {
498 tst = ADMCFGPASSWDNULL;
501 /* put afs key in host's KeyFile */
504 kas_identity_t afsIdentity;
505 kas_encryptionKey_t afsKey;
508 strcpy(afsIdentity.principal, "afs");
509 afsIdentity.instance[0] = '\0';
512 /* create afs principal */
513 if (!kas_PrincipalCreate
514 (cfg_host->cellHandle, NULL, &afsIdentity, passwd, &tst2)
515 && tst2 != KAEXIST) {
516 /* failed to create principal (and not because existed) */
522 /* retrive afs principal information to verify or obtain key */
523 kas_principalEntry_t afsEntry;
525 if (!kas_PrincipalGet
526 (cfg_host->cellHandle, NULL, &afsIdentity, &afsEntry,
530 if (passwd != NULL) {
531 /* password given; form key and verify as most recent */
532 kas_encryptionKey_t passwdKey;
533 unsigned int passwdKeyCksum;
536 (cfg_host->cellName, passwd, &passwdKey, &tst2)
537 || !kas_KeyCheckSum(&passwdKey, &passwdKeyCksum,
539 /* failed to form key or key checksum */
542 } else if (passwdKeyCksum != afsEntry.keyCheckSum) {
543 /* passwd string does not generate most recent key;
544 * check if passwd string embeds key directly.
546 if (KasKeyEmbeddedInString(passwd, &passwdKey)) {
547 /* passwd string embeds kas key */
549 (&passwdKey, &passwdKeyCksum, &tst2)) {
551 } else if (passwdKeyCksum != afsEntry.keyCheckSum) {
552 /* passwd string does not embed valid key */
553 tst = ADMCFGAFSPASSWDINVALID;
556 /* passwd string does NOT embed key */
557 tst = ADMCFGAFSPASSWDINVALID;
562 /* passwd seems to generate/embed most recent key */
564 afsKvno = afsEntry.keyVersion;
568 /* password NOT given; check if key retrieved since
569 * pre 3.5 database servers only return key checksum
571 if (KasKeyIsZero(&afsEntry.key)) {
572 tst = ADMCFGAFSKEYNOTAVAILABLE;
574 afsKey = afsEntry.key;
575 afsKvno = afsEntry.keyVersion;
582 /* add key to host's KeyFile; RPC must be unauthenticated;
583 * bosserver is presumed to be in noauth mode.
585 void *cellHandle, *bosHandle;
587 if (!afsclient_NullCellOpen(&cellHandle, &tst2)) {
591 (cellHandle, cfg_host->hostName, &bosHandle, &tst2)) {
594 if (!bos_KeyCreate(bosHandle, afsKvno, &afsKey, &tst2)
595 && tst2 != BZKEYINUSE) {
596 /* failed to add key (and not because existed) */
600 if (!bos_ServerClose(bosHandle, &tst2)) {
605 if (!afsclient_CellClose(cellHandle, &tst2)) {
623 * cfg_HostSetAdminPrincipal() -- Put generic administrator principal in
624 * host's UserList; principal is created if it does not exist.
626 * If first server host in cell, passwd and afsUid must be the initial
627 * password and the AFS UID for the admin principal; the admin principal
630 * If additional server host, passwd and afsUid are ignored; the admin
631 * principal is assumed to exist.
633 * ASSUMPTIONS: Client configured and BOS server started; if first host in
634 * cell then Authentication and Protection servers must be started as well.
637 cfg_HostSetAdminPrincipal(void *hostHandle, /* host config handle */
638 short isFirst, /* first server in cell flag */
639 char *admin, /* admin principal name */
640 const char *passwd, /* admin initial password */
641 unsigned int afsUid, /* admin AFS UID */
643 { /* completion status */
645 afs_status_t tst2, tst = 0;
646 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
648 /* validate parameters and prepare host handle for bos functions */
650 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
652 } else if (admin == NULL || *admin == '\0') {
653 tst = ADMCFGADMINPRINCIPALNULL;
654 } else if (strlen(admin) > (KAS_MAX_NAME_LEN - 1)) {
655 tst = ADMCFGADMINPRINCIPALTOOLONG;
656 } else if (isFirst && (passwd == NULL || *passwd == '\0')) {
657 tst = ADMCFGPASSWDNULL;
658 } else if (!cfgutil_HostHandleBosInit(cfg_host, &tst2)) {
662 /* put admin in host's UserList */
666 /* first server host in cell; create admin principal */
667 kas_identity_t adminIdentity;
668 int adminUid = afsUid;
669 kas_admin_t adminFlag = KAS_ADMIN;
671 strcpy(adminIdentity.principal, admin);
672 adminIdentity.instance[0] = '\0';
674 if (!kas_PrincipalCreate
675 (cfg_host->cellHandle, NULL, &adminIdentity, passwd, &tst2)
676 && tst2 != KAEXIST) {
677 /* failed to create principal (and not because existed) */
681 if (!kas_PrincipalFieldsSet
682 (cfg_host->cellHandle, NULL, &adminIdentity, &adminFlag,
683 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
685 /* failed to set admin attributes */
690 (cfg_host->cellHandle, admin, &adminUid, &tst2)
691 && tst2 != PREXIST) {
692 /* failed to create user (and not because existed) */
696 if (!pts_GroupMemberAdd
697 (cfg_host->cellHandle, admin, "system:administrators",
698 &tst2) && tst2 != PRIDEXIST) {
699 /* failed to add to group (not because already there) */
705 /* add admin to host's UserList */
706 if (!bos_AdminCreate(cfg_host->bosHandle, admin, &tst2)
708 /* failed to add admin (and not because existed) */
709 /* DANGER: platform-specific errno values being returned */
726 * cfg_HostInvalidate() -- Invalidate static server configuration on host.
728 * Server configuration invalidated only if BOS server is not running.
731 cfg_HostInvalidate(void *hostHandle, /* host config handle */
733 { /* completion status */
735 afs_status_t tst2, tst = 0;
736 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
738 /* validate parameters */
740 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
744 /* remote configuration not yet supported in this function */
747 if (!cfg_host->is_local) {
748 tst = ADMCFGNOTSUPPORTED;
752 /* make sure bosserver is not running on host */
755 /* Windows - bosserver is controlled via the BOS control service */
759 if (!cfgutil_WindowsServiceQuery
760 (AFSREG_SVR_SVC_NAME, &svcState, &tst2)) {
762 } else if (svcState != SERVICE_STOPPED) {
763 tst = ADMCFGBOSSERVERACTIVE;
768 /* function not yet implemented for Unix */
769 tst = ADMCFGNOTSUPPORTED;
771 #endif /* AFS_NT40_ENV */
774 /* remove server state files */
778 const char *cfgdir[3];
780 cfgdir[0] = AFSDIR_SERVER_ETC_DIRPATH;
781 cfgdir[1] = AFSDIR_SERVER_DB_DIRPATH;
782 cfgdir[2] = AFSDIR_SERVER_LOCAL_DIRPATH;
784 for (i = 0; i < 3 && tst == 0; i++) {
785 if (!cfgutil_CleanDirectory(cfgdir[i], &tst2)) {
791 /* remove all vice partition table entries */
795 struct vpt_iter vpiter;
796 struct vptab vpentry;
798 /* note: ignore errors except from removal attempts */
800 if (!vpt_Start(&vpiter)) {
801 while (!vpt_NextEntry(&vpiter, &vpentry)) {
802 if (vpt_RemoveEntry(vpentry.vp_name)) {
803 /* ENOENT implies entry does not exist; consider removed */
804 if (errno != ENOENT) {
805 if (errno == EACCES) {
808 tst = ADMCFGVPTABLEWRITEFAILED;
813 (void)vpt_Finish(&vpiter);
817 /* function not yet implemented for unix */
819 tst = ADMCFGNOTSUPPORTED;
821 #endif /* AFS_NT40_ENV */
835 * cfg_HostPartitionTableEnumerate() -- Enumerate AFS partition table entries.
837 * If the partition table is empty (or does not exist) then *tablePP
838 * is set to NULL and *nEntriesP is set to zero (0).
840 * Partitions in table are not necessarily those being exported; a table
841 * entry may have been added or removed since the fileserver last started.
844 cfg_HostPartitionTableEnumerate(void *hostHandle, /* host config handle */
845 cfg_partitionEntry_t ** tablePP, /* table */
846 int *nEntriesP, /* table entry count */
848 { /* completion status */
850 afs_status_t tst2, tst = 0;
851 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
853 /* validate parameters */
855 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
857 } else if (tablePP == NULL) {
858 tst = ADMCFGVPTABLEPNULL;
859 } else if (nEntriesP == NULL) {
860 tst = ADMCFGVPTABLECOUNTPNULL;
863 /* remote configuration not yet supported in this function */
866 if (!cfg_host->is_local) {
867 tst = ADMCFGNOTSUPPORTED;
871 /* enumerate the vice partition table */
875 struct vpt_iter vpiter;
876 struct vptab vpentry;
877 int vpentryCountMax = 0;
879 /* count table entries */
881 if (vpt_Start(&vpiter)) {
882 /* ENOENT implies table does not exist (which is OK) */
883 if (errno != ENOENT) {
884 if (errno == EACCES) {
887 tst = ADMCFGVPTABLEREADFAILED;
891 while (!vpt_NextEntry(&vpiter, &vpentry)) {
894 if (errno != ENOENT) {
895 tst = ADMCFGVPTABLEREADFAILED;
897 (void)vpt_Finish(&vpiter);
900 /* alloc storage for table entries; handle any entry count change */
903 if (vpentryCountMax == 0) {
907 /* return a two-part table; first points into second */
909 size_t metaTableSize;
912 vpentryCountMax * (sizeof(cfg_partitionEntry_t) +
913 sizeof(struct vptab));
915 if ((metaTablep = (void *)malloc(metaTableSize)) == NULL) {
919 cfg_partitionEntry_t *cpePart;
920 struct vptab *vptPart;
921 int vpentryCount = 0;
923 cpePart = (cfg_partitionEntry_t *) metaTablep;
924 vptPart = (struct vptab *)(&cpePart[vpentryCountMax]);
926 for (i = 0; i < vpentryCountMax; i++) {
927 cpePart[i].partitionName = vptPart[i].vp_name;
928 cpePart[i].deviceName = vptPart[i].vp_dev;
931 if (vpt_Start(&vpiter)) {
932 /* ENOENT implies table does not exist (which is OK) */
933 if (errno != ENOENT) {
934 if (errno == EACCES) {
937 tst = ADMCFGVPTABLEREADFAILED;
941 for (i = 0; i < vpentryCountMax; i++) {
942 if (vpt_NextEntry(&vpiter, &vptPart[i])) {
947 if (i < vpentryCountMax && errno != ENOENT) {
948 tst = ADMCFGVPTABLEREADFAILED;
952 (void)vpt_Finish(&vpiter);
956 *nEntriesP = vpentryCount;
958 if (vpentryCount != 0) {
959 *tablePP = (cfg_partitionEntry_t *) metaTablep;
972 /* function not yet implemented for Unix */
974 tst = ADMCFGNOTSUPPORTED;
976 #endif /* AFS_NT40_ENV */
989 * cfg_HostPartitionTableAddEntry() -- Add or update AFS partition table entry.
992 cfg_HostPartitionTableAddEntry(void *hostHandle, /* host config handle */
993 const char *partName, /* partition name */
994 const char *devName, /* device name */
996 { /* completion status */
998 afs_status_t tst = 0;
1001 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
1005 /* validate parameters */
1007 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
1009 } else if (partName == NULL) {
1010 tst = ADMCFGPARTITIONNAMENULL;
1011 } else if (!vpt_PartitionNameValid(partName)) {
1012 tst = ADMCFGPARTITIONNAMEBAD;
1013 } else if (devName == NULL) {
1014 tst = ADMCFGDEVICENAMENULL;
1015 } else if (!vpt_DeviceNameValid(devName)) {
1016 tst = ADMCFGDEVICENAMEBAD;
1019 /* remote configuration not yet supported in this function */
1022 if (!cfg_host->is_local) {
1023 tst = ADMCFGNOTSUPPORTED;
1027 /* add entry to table */
1030 struct vptab vpentry;
1032 strcpy(vpentry.vp_name, partName);
1033 strcpy(vpentry.vp_dev, devName);
1035 if (vpt_AddEntry(&vpentry)) {
1036 if (errno == EACCES) {
1038 } else if (errno == EINVAL) {
1039 /* shouldn't happen since checked partition/dev names */
1040 tst = ADMCFGVPTABLEENTRYBAD;
1042 tst = ADMCFGVPTABLEWRITEFAILED;
1047 /* function not yet implemented for unix */
1049 tst = ADMCFGNOTSUPPORTED;
1051 #endif /* AFS_NT40_ENV */
1064 * cfg_HostPartitionTableRemoveEntry() -- Remove AFS partition table entry.
1067 cfg_HostPartitionTableRemoveEntry(void *hostHandle, /* host config handle */
1068 const char *partName, /* partition name */
1070 { /* completion status */
1072 afs_status_t tst = 0;
1075 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
1079 /* validate parameters */
1081 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
1083 } else if (partName == NULL) {
1084 tst = ADMCFGPARTITIONNAMENULL;
1085 } else if (!vpt_PartitionNameValid(partName)) {
1086 tst = ADMCFGPARTITIONNAMEBAD;
1089 /* remote configuration not yet supported in this function */
1092 if (!cfg_host->is_local) {
1093 tst = ADMCFGNOTSUPPORTED;
1097 /* remove entry from table */
1100 if (vpt_RemoveEntry(partName)) {
1101 /* ENOENT implies entry does not exist; consider to be removed */
1102 if (errno != ENOENT) {
1103 if (errno == EACCES) {
1105 } else if (errno == EINVAL) {
1106 /* shouldn't happen since checked partition/dev names */
1107 tst = ADMCFGPARTITIONNAMEBAD;
1109 tst = ADMCFGVPTABLEWRITEFAILED;
1115 /* function not yet implemented for unix */
1117 tst = ADMCFGNOTSUPPORTED;
1119 #endif /* AFS_NT40_ENV */
1132 * cfg_HostPartitionNameValid() -- check partition name syntax.
1135 cfg_HostPartitionNameValid(const char *partName, /* partition name */
1136 short *isValidP, /* syntax is valid */
1138 { /* completion status */
1140 afs_status_t tst = 0;
1142 /* validate parameters */
1144 if (partName == NULL) {
1145 tst = ADMCFGPARTITIONNAMENULL;
1146 } else if (isValidP == NULL) {
1147 tst = ADMCFGVALIDFLAGPNULL;
1150 /* check name syntax */
1154 *isValidP = vpt_PartitionNameValid(partName);
1157 /* function not yet implemented for Unix */
1159 tst = ADMCFGNOTSUPPORTED;
1175 * cfg_HostDeviceNameValid() -- check device name syntax.
1178 cfg_HostDeviceNameValid(const char *devName, /* device name */
1179 short *isValidP, /* syntax is valid */
1181 { /* completion status */
1183 afs_status_t tst = 0;
1185 /* validate parameters */
1187 if (devName == NULL) {
1188 tst = ADMCFGDEVICENAMENULL;
1189 } else if (isValidP == NULL) {
1190 tst = ADMCFGVALIDFLAGPNULL;
1193 /* check name syntax */
1197 *isValidP = vpt_DeviceNameValid(devName);
1200 /* function not yet implemented for Unix */
1202 tst = ADMCFGNOTSUPPORTED;
1217 /* ---------------- Exported Utility functions ------------------ */
1221 * cfg_StringDeallocate() -- Deallocate (multi)string returned by library.
1224 cfg_StringDeallocate(char *stringDataP, /* (multi)string to deallocate */
1226 { /* completion status */
1227 free((void *)stringDataP);
1236 * cfg_PartitionListDeallocate() -- Deallocate partition table enumeration
1237 * returned by library.
1240 cfg_PartitionListDeallocate(cfg_partitionEntry_t * partitionListDataP,
1243 free((void *)partitionListDataP);
1253 /* ---------------- Local functions ------------------ */
1257 * KasKeyIsZero() -- determine if kas key is zero
1259 * RETURN CODES: 1 if zero, 0 otherwise
1262 KasKeyIsZero(kas_encryptionKey_t * kasKey)
1264 char *keyp = (char *)kasKey;
1267 for (i = 0; i < sizeof(*kasKey); i++) {
1277 * KasKeyEmbeddedInString() -- determine if kas key is embedded in string
1278 * and return key if extant.
1280 * RETURN CODES: 1 if embedded key found, 0 otherwise
1283 KasKeyEmbeddedInString(const char *keyString, kas_encryptionKey_t * kasKey)
1285 char *octalDigits = "01234567";
1287 /* keyString format is exactly 24 octal digits if embeds kas key */
1288 if (strlen(keyString) == 24 && strspn(keyString, octalDigits) == 24) {
1289 /* kas key is embedded in keyString; extract it */
1292 for (i = 0; i < 24; i += 3) {
1294 unsigned char keyPieceVal;
1296 keyPiece[0] = keyString[i];
1297 keyPiece[1] = keyString[i + 1];
1298 keyPiece[2] = keyString[i + 2];
1301 keyPieceVal = (unsigned char)strtoul(keyPiece, NULL, 8);
1303 *((unsigned char *)kasKey + (i / 3)) = keyPieceVal;
1307 /* key NOT embedded in keyString */