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 <afs/param.h>
22 #include <sys/types.h>
29 #include <WINNT/vptab.h>
30 #include <WINNT/afsreg.h>
35 #endif /* AFS_NT40_ENV */
37 #include <afs/afs_Admin.h>
38 #include <afs/afs_AdminErrors.h>
39 #include <afs/afs_utilAdmin.h>
40 #include <afs/afs_bosAdmin.h>
41 #include <afs/afs_clientAdmin.h>
42 #include <afs/afs_kasAdmin.h>
43 #include <afs/afs_ptsAdmin.h>
46 #include <afs/kautils.h>
47 #include <afs/bnode.h>
48 #include <afs/prerror.h>
50 #include <afs/dirpath.h>
51 #include <afs/cellconfig.h>
53 #include "cfginternal.h"
54 #include "afs_cfgAdmin.h"
55 #include "../adminutil/afs_AdminInternal.h"
59 /* Local declarations and definitions */
62 KasKeyIsZero(kas_encryptionKey_t *kasKey);
65 KasKeyEmbeddedInString(const char *keyString, kas_encryptionKey_t *kasKey);
70 /* ---------------- Exported Server Host functions ------------------ */
74 * cfg_HostQueryStatus() -- Query status of static server configuration
75 * on host, i.e., status of required configuration files, etc.
76 * Upon successful completion *configStP is set to the server
77 * configuration status, with a value of zero (0) indicating that
78 * the configuration is valid.
80 * If server configuration is not valid then *cellNameP is set to NULL;
81 * otherwise, *cellNameP is an allocated buffer containing server cell.
83 * Warning: in determining if server configuration is valid, no check
84 * is made for consistency with other servers in cell; also, the
85 * internal consistency of configuration files may not be verified.
88 cfg_HostQueryStatus(const char *hostName, /* name of host */
89 afs_status_p configStP, /* server config status */
90 char **cellNameP, /* server's cell */
91 afs_status_p st) /* completion status */
94 afs_status_t tst2, tst = 0;
95 afs_status_t serverSt = 0;
96 char *serverCellName = NULL;
98 /* validate parameters */
100 if (hostName == NULL || *hostName == '\0') {
101 tst = ADMCFGHOSTNAMENULL;
102 } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) {
103 tst = ADMCFGHOSTNAMETOOLONG;
104 } else if (configStP == NULL) {
105 tst = ADMCFGCONFIGSTATUSPNULL;
106 } else if (cellNameP == NULL) {
107 tst = ADMCFGCELLNAMEPNULL;
110 /* remote configuration not yet supported; hostName must be local host */
115 if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) {
117 } else if (!isLocal) {
118 tst = ADMCFGNOTSUPPORTED;
122 /* check for existence and readability of required server config files */
126 const char *cfgfile[4];
128 cfgfile[0] = AFSDIR_SERVER_THISCELL_FILEPATH;
129 cfgfile[1] = AFSDIR_SERVER_CELLSERVDB_FILEPATH;
130 cfgfile[2] = AFSDIR_SERVER_KEY_FILEPATH;
131 cfgfile[3] = AFSDIR_SERVER_ULIST_FILEPATH;
133 for (i = 0; i < 4; i++) {
135 if ((fd = open(cfgfile[i], O_RDONLY)) < 0) {
142 if (errno == EACCES) {
145 serverSt = ADMCFGSERVERBASICINFOINVALID;
150 /* verify the required server config files to the degree possible */
152 if (tst == 0 && serverSt == 0) {
153 struct afsconf_dir *confdir;
155 if ((confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH)) == NULL) {
156 /* one or more config files appears to be invalid */
157 serverSt = ADMCFGSERVERBASICINFOINVALID;
159 struct afsconf_entry *cellentry;
161 if (confdir->cellName == NULL || *confdir->cellName == '\0') {
162 /* no cell set for server */
163 serverSt = ADMCFGSERVERNOTINCELL;
164 } else if (confdir->keystr == NULL ||
165 confdir->keystr->nkeys == 0) {
167 serverSt = ADMCFGSERVERNOKEYS;
169 for (cellentry = confdir->entries;
171 cellentry = cellentry->next) {
172 if (!strcasecmp(confdir->cellName,
173 cellentry->cellInfo.name)) {
178 if (cellentry == NULL) {
179 serverSt = ADMCFGSERVERCELLNOTINDB;
180 } else if (cellentry->cellInfo.numServers <= 0) {
181 serverSt = ADMCFGSERVERCELLHASNODBENTRIES;
185 if (tst == 0 && serverSt == 0) {
186 /* everything looks good; malloc cell name buffer to return */
188 (char *) malloc(strlen(cellentry->cellInfo.name) + 1);
189 if (serverCellName == NULL) {
192 strcpy(serverCellName, cellentry->cellInfo.name);
196 (void)afsconf_Close(confdir);
201 /* return server status and cell name */
202 *configStP = serverSt;
205 *cellNameP = serverCellName;
210 /* indicate failure */
213 /* free cell name if allocated before failure */
214 if (serverCellName != NULL) {
215 free(serverCellName);
226 * cfg_HostOpen() -- Obtain host configuration handle.
229 cfg_HostOpen(void *cellHandle, /* cell handle */
230 const char *hostName, /* name of host to configure */
231 void **hostHandleP, /* host config handle */
232 afs_status_p st) /* completion status */
235 afs_status_t tst2, tst = 0;
237 char fullHostName[MAXHOSTCHARS];
239 /* validate parameters and resolve host name to fully qualified name */
241 if (!CellHandleIsValid(cellHandle, &tst2)) {
243 } else if (hostName == NULL || *hostName == '\0') {
244 tst = ADMCFGHOSTNAMENULL;
245 } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) {
246 tst = ADMCFGHOSTNAMETOOLONG;
247 } else if (hostHandleP == NULL) {
248 tst = ADMCFGHOSTHANDLEPNULL;
249 } else if (!cfgutil_HostNameGetFull(hostName, fullHostName, &tst2)) {
253 /* remote configuration not yet supported; hostName must be local host */
258 if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) {
260 } else if (!isLocal) {
261 tst = ADMCFGNOTSUPPORTED;
265 /* allocate a host configuration handle */
270 if ((cfg_host = (cfg_host_p)malloc(sizeof(cfg_host_t))) == NULL) {
272 } else if ((localHostName =
273 (char *)malloc(strlen(fullHostName) + 1)) == NULL) {
277 /* initialize handle */
278 cfg_host->begin_magic = BEGIN_MAGIC;
279 cfg_host->is_valid = 1;
280 cfg_host->hostName = localHostName;
281 cfg_host->is_local = 1; /* not yet supporting remote config */
282 cfg_host->cellHandle = cellHandle;
283 cfg_host->bosHandle = NULL;
284 cfg_host->end_magic = END_MAGIC;
286 strcpy(localHostName, fullHostName);
288 if (!afsclient_CellNameGet(cfg_host->cellHandle,
289 &cfg_host->cellName, &tst2)) {
291 } else if (pthread_mutex_init(&cfg_host->mutex, NULL)) {
296 /* cell name lookup or mutex initialization failed */
304 /* success; return host config handle to user */
305 *hostHandleP = cfg_host;
307 /* indicate failure */
318 * cfg_HostClose() -- Release host configuration handle.
321 cfg_HostClose(void *hostHandle, /* host config handle */
322 afs_status_p st) /* completion status */
325 afs_status_t tst2, tst = 0;
326 cfg_host_p cfg_host = (cfg_host_p)hostHandle;
328 /* validate parameters */
330 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
334 /* free handle; can assume no other thread using this handle */
337 /* mark cfg handle invalid in case use after free (bug catcher) */
338 cfg_host->is_valid = 0;
340 if (cfg_host->bosHandle != NULL) {
341 if (!bos_ServerClose(cfg_host->bosHandle, &tst2)) {
345 free(cfg_host->hostName);
346 (void)pthread_mutex_destroy(&cfg_host->mutex);
361 * cfg_HostSetCell() -- Define server cell membership for host.
363 * The cellDbHosts argument is a multistring containing the names of
364 * the existing database servers already configured in the cell; this
365 * multistring list can be obtained via cfg_CellServDbEnumerate().
366 * If configuring the first server in a new cell then the cellDbHosts
367 * list contains only the name of that host.
369 * Note: The names in cellDbHosts MUST exactly match those in the
370 * cell-wide server CellServDB; using cfg_CellServDbEnumerate()
371 * is highly recommended.
374 cfg_HostSetCell(void *hostHandle, /* host config handle */
375 const char *cellName, /* cell name */
376 const char *cellDbHosts, /* cell database hosts */
377 afs_status_p st) /* completion status */
380 afs_status_t tst2, tst = 0;
381 cfg_host_p cfg_host = (cfg_host_p)hostHandle;
383 /* validate parameters */
385 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
387 } else if (cellName == NULL || *cellName == '\0') {
388 tst = ADMCFGCELLNAMENULL;
389 } else if (strlen(cellName) > (MAXCELLCHARS - 1)) {
390 tst = ADMCFGCELLNAMETOOLONG;
391 } else if (!cfgutil_HostHandleCellNameCompatible(cfg_host, cellName)) {
392 tst = ADMCFGCELLNAMECONFLICT;
393 } else if (cellDbHosts == NULL || *cellDbHosts == '\0') {
394 tst = ADMCFGCELLDBHOSTSNULL;
397 /* remote configuration not yet supported in this function */
400 if (!cfg_host->is_local) {
401 tst = ADMCFGNOTSUPPORTED;
405 /* define server cell and cell database hosts */
408 const char *dbHost = cellDbHosts;
409 struct afsconf_cell hostCell;
410 memset(&hostCell, 0, sizeof(hostCell));
412 strcpy(hostCell.name, cellName);
413 hostCell.numServers = 0;
415 while (*dbHost != '\0' && tst == 0) {
416 /* fill in each database host */
417 size_t dbHostLen = strlen(dbHost);
419 if (dbHostLen > (MAXHOSTCHARS - 1)) {
420 tst = ADMCFGHOSTNAMETOOLONG;
421 } else if (hostCell.numServers >= MAXHOSTSPERCELL) {
422 tst = ADMCFGCELLDBHOSTCOUNTTOOLARGE;
424 strcpy(hostCell.hostName[hostCell.numServers++], dbHost);
425 dbHost += dbHostLen + 1;
430 /* create server ThisCell/CellServDB dir if it does not exist */
432 (void) mkdir(AFSDIR_USR_DIRPATH);
433 (void) mkdir(AFSDIR_SERVER_AFS_DIRPATH);
434 (void) mkdir(AFSDIR_SERVER_ETC_DIRPATH);
436 (void) mkdir(AFSDIR_USR_DIRPATH, 0755);
437 (void) mkdir(AFSDIR_SERVER_AFS_DIRPATH, 0755);
438 (void) mkdir(AFSDIR_SERVER_ETC_DIRPATH, 0755);
440 if (afsconf_SetCellInfo(NULL,
441 AFSDIR_SERVER_ETC_DIRPATH, &hostCell)) {
442 /* failed; most likely cause is bad host name */
443 tst = ADMCFGSERVERSETCELLFAILED;
459 * cfg_HostSetAfsPrincipal() -- Put AFS server principal (afs) key in
460 * host's KeyFile; principal is created if it does not exist.
462 * If first server host in cell, passwd must be initial password for
463 * the afs principal; the afs principal is created.
465 * If additional server host, passwd can be specified or NULL; the
466 * afs principal must already exist by definition. If passwd is NULL
467 * then an attempt is made to fetch the afs key. If the key fetch fails
468 * because pre 3.5 database servers are in use (which will only return a
469 * key checksum) then the function fails with a return status of
470 * ADMCFGAFSKEYNOTAVAILABLE; in this case the function should be called
471 * again with passwd specified. If passwd is specified (not NULL) but the
472 * password key fails a checksum comparison with the current afs key
473 * then the function fails with a return status of ADMCFGAFSPASSWDINVALID.
475 * ASSUMPTIONS: Client configured and BOS server started; if first host in
476 * cell then Authentication server must be started as well.
479 cfg_HostSetAfsPrincipal(void *hostHandle, /* host config handle */
480 short isFirst, /* first server in cell flag */
481 const char *passwd, /* afs initial password */
482 afs_status_p st) /* completion status */
485 afs_status_t tst2, tst = 0;
486 cfg_host_p cfg_host = (cfg_host_p)hostHandle;
488 /* validate parameters */
490 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
492 } else if ((isFirst && passwd == NULL) ||
493 (passwd != NULL && *passwd == '\0')) {
494 tst = ADMCFGPASSWDNULL;
497 /* put afs key in host's KeyFile */
500 kas_identity_t afsIdentity;
501 kas_encryptionKey_t afsKey;
504 strcpy(afsIdentity.principal, "afs");
505 afsIdentity.instance[0] = '\0';
508 /* create afs principal */
509 if (!kas_PrincipalCreate(cfg_host->cellHandle,
515 /* failed to create principal (and not because existed) */
521 /* retrive afs principal information to verify or obtain key */
522 kas_principalEntry_t afsEntry;
524 if (!kas_PrincipalGet(cfg_host->cellHandle,
531 if (passwd != NULL) {
532 /* password given; form key and verify as most recent */
533 kas_encryptionKey_t passwdKey;
534 unsigned int passwdKeyCksum;
536 if (!kas_StringToKey(cfg_host->cellName,
541 !kas_KeyCheckSum(&passwdKey, &passwdKeyCksum, &tst2)) {
542 /* failed to form key or key checksum */
545 } else if (passwdKeyCksum != afsEntry.keyCheckSum) {
546 /* passwd string does not generate most recent key;
547 * check if passwd string embeds key directly.
549 if (KasKeyEmbeddedInString(passwd, &passwdKey)) {
550 /* passwd string embeds kas key */
551 if (!kas_KeyCheckSum(&passwdKey,
552 &passwdKeyCksum, &tst2)) {
554 } else if (passwdKeyCksum !=
555 afsEntry.keyCheckSum) {
556 /* passwd string does not embed valid key */
557 tst = ADMCFGAFSPASSWDINVALID;
560 /* passwd string does NOT embed key */
561 tst = ADMCFGAFSPASSWDINVALID;
566 /* passwd seems to generate/embed most recent key */
568 afsKvno = afsEntry.keyVersion;
572 /* password NOT given; check if key retrieved since
573 * pre 3.5 database servers only return key checksum
575 if (KasKeyIsZero(&afsEntry.key)) {
576 tst = ADMCFGAFSKEYNOTAVAILABLE;
578 afsKey = afsEntry.key;
579 afsKvno = afsEntry.keyVersion;
586 /* add key to host's KeyFile; RPC must be unauthenticated;
587 * bosserver is presumed to be in noauth mode.
589 void *cellHandle, *bosHandle;
591 if (!afsclient_NullCellOpen(&cellHandle, &tst2)) {
594 if (!bos_ServerOpen(cellHandle,
595 cfg_host->hostName, &bosHandle, &tst2)) {
598 if (!bos_KeyCreate(bosHandle, afsKvno, &afsKey, &tst2) &&
599 tst2 != BZKEYINUSE) {
600 /* failed to add key (and not because existed) */
604 if (!bos_ServerClose(bosHandle, &tst2)) {
609 if (!afsclient_CellClose(cellHandle, &tst2)) {
627 * cfg_HostSetAdminPrincipal() -- Put generic administrator principal in
628 * host's UserList; principal is created if it does not exist.
630 * If first server host in cell, passwd and afsUid must be the initial
631 * password and the AFS UID for the admin principal; the admin principal
634 * If additional server host, passwd and afsUid are ignored; the admin
635 * principal is assumed to exist.
637 * ASSUMPTIONS: Client configured and BOS server started; if first host in
638 * cell then Authentication and Protection servers must be started as well.
641 cfg_HostSetAdminPrincipal(void *hostHandle, /* host config handle */
642 short isFirst, /* first server in cell flag */
643 const char *admin, /* admin principal name */
644 const char *passwd, /* admin initial password */
645 unsigned int afsUid, /* admin AFS UID */
646 afs_status_p st) /* completion status */
649 afs_status_t tst2, tst = 0;
650 cfg_host_p cfg_host = (cfg_host_p)hostHandle;
652 /* validate parameters and prepare host handle for bos functions */
654 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
656 } else if (admin == NULL || *admin == '\0') {
657 tst = ADMCFGADMINPRINCIPALNULL;
658 } else if (strlen(admin) > (KAS_MAX_NAME_LEN - 1)) {
659 tst = ADMCFGADMINPRINCIPALTOOLONG;
660 } else if (isFirst && (passwd == NULL || *passwd == '\0')) {
661 tst = ADMCFGPASSWDNULL;
662 } else if (!cfgutil_HostHandleBosInit(cfg_host, &tst2)) {
666 /* put admin in host's UserList */
670 /* first server host in cell; create admin principal */
671 kas_identity_t adminIdentity;
672 int adminUid = afsUid;
673 kas_admin_t adminFlag = KAS_ADMIN;
675 strcpy(adminIdentity.principal, admin);
676 adminIdentity.instance[0] = '\0';
678 if (!kas_PrincipalCreate(cfg_host->cellHandle,
684 /* failed to create principal (and not because existed) */
687 } else if (!kas_PrincipalFieldsSet(cfg_host->cellHandle,
691 NULL, NULL, NULL, NULL,
692 NULL, NULL, NULL, NULL, NULL,
694 /* failed to set admin attributes */
697 } else if (!pts_UserCreate(cfg_host->cellHandle,
702 /* failed to create user (and not because existed) */
705 } else if (!pts_GroupMemberAdd(cfg_host->cellHandle,
707 "system:administrators",
710 /* failed to add to group (not because already there) */
716 /* add admin to host's UserList */
717 if (!bos_AdminCreate(cfg_host->bosHandle, admin, &tst2) &&
719 /* failed to add admin (and not because existed) */
720 /* DANGER: platform-specific errno values being returned */
737 * cfg_HostInvalidate() -- Invalidate static server configuration on host.
739 * Server configuration invalidated only if BOS server is not running.
742 cfg_HostInvalidate(void *hostHandle, /* host config handle */
743 afs_status_p st) /* completion status */
746 afs_status_t tst2, tst = 0;
747 cfg_host_p cfg_host = (cfg_host_p)hostHandle;
749 /* validate parameters */
751 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
755 /* remote configuration not yet supported in this function */
758 if (!cfg_host->is_local) {
759 tst = ADMCFGNOTSUPPORTED;
763 /* make sure bosserver is not running on host */
766 /* Windows - bosserver is controlled via the BOS control service */
770 if (!cfgutil_WindowsServiceQuery(AFSREG_SVR_SVC_NAME,
774 } else if (svcState != SERVICE_STOPPED) {
775 tst = ADMCFGBOSSERVERACTIVE;
780 /* function not yet implemented for Unix */
781 tst = ADMCFGNOTSUPPORTED;
783 #endif /* AFS_NT40_ENV */
786 /* remove server state files */
790 const char *cfgdir[3];
792 cfgdir[0] = AFSDIR_SERVER_ETC_DIRPATH;
793 cfgdir[1] = AFSDIR_SERVER_DB_DIRPATH;
794 cfgdir[2] = AFSDIR_SERVER_LOCAL_DIRPATH;
796 for (i = 0; i < 3 && tst == 0; i++) {
797 if (!cfgutil_CleanDirectory(cfgdir[i], &tst2)) {
803 /* remove all vice partition table entries */
807 struct vpt_iter vpiter;
808 struct vptab vpentry;
810 /* note: ignore errors except from removal attempts */
812 if (!vpt_Start(&vpiter)) {
813 while (!vpt_NextEntry(&vpiter, &vpentry)) {
814 if (vpt_RemoveEntry(vpentry.vp_name)) {
815 /* ENOENT implies entry does not exist; consider removed */
816 if (errno != ENOENT) {
817 if (errno == EACCES) {
820 tst = ADMCFGVPTABLEWRITEFAILED;
825 (void)vpt_Finish(&vpiter);
829 /* function not yet implemented for unix */
831 tst = ADMCFGNOTSUPPORTED;
833 #endif /* AFS_NT40_ENV */
847 * cfg_HostPartitionTableEnumerate() -- Enumerate AFS partition table entries.
849 * If the partition table is empty (or does not exist) then *tablePP
850 * is set to NULL and *nEntriesP is set to zero (0).
852 * Partitions in table are not necessarily those being exported; a table
853 * entry may have been added or removed since the fileserver last started.
856 cfg_HostPartitionTableEnumerate(void *hostHandle, /* host config handle */
857 cfg_partitionEntry_t **tablePP, /* table */
858 int *nEntriesP, /* table entry count */
859 afs_status_p st) /* completion status */
862 afs_status_t tst2, tst = 0;
863 cfg_host_p cfg_host = (cfg_host_p)hostHandle;
865 /* validate parameters */
867 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
869 } else if (tablePP == NULL) {
870 tst = ADMCFGVPTABLEPNULL;
871 } else if (nEntriesP == NULL) {
872 tst = ADMCFGVPTABLECOUNTPNULL;
875 /* remote configuration not yet supported in this function */
878 if (!cfg_host->is_local) {
879 tst = ADMCFGNOTSUPPORTED;
883 /* enumerate the vice partition table */
887 struct vpt_iter vpiter;
888 struct vptab vpentry;
889 int vpentryCountMax = 0;
891 /* count table entries */
893 if (vpt_Start(&vpiter)) {
894 /* ENOENT implies table does not exist (which is OK) */
895 if (errno != ENOENT) {
896 if (errno == EACCES) {
899 tst = ADMCFGVPTABLEREADFAILED;
903 while (!vpt_NextEntry(&vpiter, &vpentry)) {
906 if (errno != ENOENT) {
907 tst = ADMCFGVPTABLEREADFAILED;
909 (void)vpt_Finish(&vpiter);
912 /* alloc storage for table entries; handle any entry count change */
915 if (vpentryCountMax == 0) {
919 /* return a two-part table; first points into second */
921 size_t metaTableSize;
924 vpentryCountMax * (sizeof(cfg_partitionEntry_t) +
925 sizeof(struct vptab));
927 if ((metaTablep = (void *)malloc(metaTableSize)) == NULL) {
931 cfg_partitionEntry_t *cpePart;
932 struct vptab *vptPart;
933 int vpentryCount = 0;
935 cpePart = (cfg_partitionEntry_t *)metaTablep;
936 vptPart = (struct vptab *)(&cpePart[vpentryCountMax]);
938 for (i = 0; i < vpentryCountMax; i++) {
939 cpePart[i].partitionName = vptPart[i].vp_name;
940 cpePart[i].deviceName = vptPart[i].vp_dev;
943 if (vpt_Start(&vpiter)) {
944 /* ENOENT implies table does not exist (which is OK) */
945 if (errno != ENOENT) {
946 if (errno == EACCES) {
949 tst = ADMCFGVPTABLEREADFAILED;
953 for (i = 0; i < vpentryCountMax; i++) {
954 if (vpt_NextEntry(&vpiter, &vptPart[i])) {
959 if (i < vpentryCountMax && errno != ENOENT) {
960 tst = ADMCFGVPTABLEREADFAILED;
964 (void)vpt_Finish(&vpiter);
968 *nEntriesP = vpentryCount;
970 if (vpentryCount != 0) {
971 *tablePP = (cfg_partitionEntry_t *)metaTablep;
985 /* function not yet implemented for Unix */
987 tst = ADMCFGNOTSUPPORTED;
989 #endif /* AFS_NT40_ENV */
1002 * cfg_HostPartitionTableAddEntry() -- Add or update AFS partition table entry.
1005 cfg_HostPartitionTableAddEntry(void *hostHandle, /* host config handle */
1006 const char *partName, /* partition name */
1007 const char *devName, /* device name */
1008 afs_status_p st) /* completion status */
1011 afs_status_t tst2, tst = 0;
1012 cfg_host_p cfg_host = (cfg_host_p)hostHandle;
1015 /* validate parameters */
1017 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
1019 } else if (partName == NULL) {
1020 tst = ADMCFGPARTITIONNAMENULL;
1021 } else if (!vpt_PartitionNameValid(partName)) {
1022 tst = ADMCFGPARTITIONNAMEBAD;
1023 } else if (devName == NULL) {
1024 tst = ADMCFGDEVICENAMENULL;
1025 } else if (!vpt_DeviceNameValid(devName)) {
1026 tst = ADMCFGDEVICENAMEBAD;
1029 /* remote configuration not yet supported in this function */
1032 if (!cfg_host->is_local) {
1033 tst = ADMCFGNOTSUPPORTED;
1037 /* add entry to table */
1040 struct vptab vpentry;
1042 strcpy(vpentry.vp_name, partName);
1043 strcpy(vpentry.vp_dev, devName);
1045 if (vpt_AddEntry(&vpentry)) {
1046 if (errno == EACCES) {
1048 } else if (errno == EINVAL) {
1049 /* shouldn't happen since checked partition/dev names */
1050 tst = ADMCFGVPTABLEENTRYBAD;
1052 tst = ADMCFGVPTABLEWRITEFAILED;
1058 /* function not yet implemented for unix */
1060 tst = ADMCFGNOTSUPPORTED;
1062 #endif /* AFS_NT40_ENV */
1075 * cfg_HostPartitionTableRemoveEntry() -- Remove AFS partition table entry.
1078 cfg_HostPartitionTableRemoveEntry(void *hostHandle, /* host config handle */
1079 const char *partName, /* partition name */
1080 afs_status_p st) /* completion status */
1083 afs_status_t tst2, tst = 0;
1084 cfg_host_p cfg_host = (cfg_host_p)hostHandle;
1087 /* validate parameters */
1089 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
1091 } else if (partName == NULL) {
1092 tst = ADMCFGPARTITIONNAMENULL;
1093 } else if (!vpt_PartitionNameValid(partName)) {
1094 tst = ADMCFGPARTITIONNAMEBAD;
1097 /* remote configuration not yet supported in this function */
1100 if (!cfg_host->is_local) {
1101 tst = ADMCFGNOTSUPPORTED;
1105 /* remove entry from table */
1108 if (vpt_RemoveEntry(partName)) {
1109 /* ENOENT implies entry does not exist; consider to be removed */
1110 if (errno != ENOENT) {
1111 if (errno == EACCES) {
1113 } else if (errno == EINVAL) {
1114 /* shouldn't happen since checked partition/dev names */
1115 tst = ADMCFGPARTITIONNAMEBAD;
1117 tst = ADMCFGVPTABLEWRITEFAILED;
1124 /* function not yet implemented for unix */
1126 tst = ADMCFGNOTSUPPORTED;
1128 #endif /* AFS_NT40_ENV */
1141 * cfg_HostPartitionNameValid() -- check partition name syntax.
1144 cfg_HostPartitionNameValid(const char *partName, /* partition name */
1145 short *isValidP, /* syntax is valid */
1146 afs_status_p st) /* completion status */
1149 afs_status_t tst = 0;
1151 /* validate parameters */
1153 if (partName == NULL) {
1154 tst = ADMCFGPARTITIONNAMENULL;
1155 } else if (isValidP == NULL) {
1156 tst = ADMCFGVALIDFLAGPNULL;
1159 /* check name syntax */
1163 *isValidP = vpt_PartitionNameValid(partName);
1166 /* function not yet implemented for Unix */
1168 tst = ADMCFGNOTSUPPORTED;
1184 * cfg_HostDeviceNameValid() -- check device name syntax.
1187 cfg_HostDeviceNameValid(const char *devName, /* device name */
1188 short *isValidP, /* syntax is valid */
1189 afs_status_p st) /* completion status */
1192 afs_status_t tst = 0;
1194 /* validate parameters */
1196 if (devName == NULL) {
1197 tst = ADMCFGDEVICENAMENULL;
1198 } else if (isValidP == NULL) {
1199 tst = ADMCFGVALIDFLAGPNULL;
1202 /* check name syntax */
1206 *isValidP = vpt_DeviceNameValid(devName);
1209 /* function not yet implemented for Unix */
1211 tst = ADMCFGNOTSUPPORTED;
1226 /* ---------------- Exported Utility functions ------------------ */
1230 * cfg_StringDeallocate() -- Deallocate (multi)string returned by library.
1233 cfg_StringDeallocate(char *stringDataP, /* (multi)string to deallocate */
1234 afs_status_p st) /* completion status */
1236 free((void *)stringDataP);
1245 * cfg_PartitionListDeallocate() -- Deallocate partition table enumeration
1246 * returned by library.
1249 cfg_PartitionListDeallocate(cfg_partitionEntry_t *partitionListDataP,
1252 free((void *)partitionListDataP);
1262 /* ---------------- Local functions ------------------ */
1266 * KasKeyIsZero() -- determine if kas key is zero
1268 * RETURN CODES: 1 if zero, 0 otherwise
1271 KasKeyIsZero(kas_encryptionKey_t *kasKey)
1273 char *keyp = (char *)kasKey;
1276 for (i = 0; i < sizeof(*kasKey); i++) {
1286 * KasKeyEmbeddedInString() -- determine if kas key is embedded in string
1287 * and return key if extant.
1289 * RETURN CODES: 1 if embedded key found, 0 otherwise
1292 KasKeyEmbeddedInString(const char *keyString, kas_encryptionKey_t *kasKey)
1294 char *octalDigits = "01234567";
1296 /* keyString format is exactly 24 octal digits if embeds kas key */
1297 if (strlen(keyString) == 24 &&
1298 strspn(keyString, octalDigits) == 24) {
1299 /* kas key is embedded in keyString; extract it */
1302 for (i = 0; i < 24; i += 3) {
1304 unsigned char keyPieceVal;
1306 keyPiece[0] = keyString[i];
1307 keyPiece[1] = keyString[i + 1];
1308 keyPiece[2] = keyString[i + 2];
1311 keyPieceVal = (unsigned char)strtoul(keyPiece, NULL, 8);
1313 *((unsigned char *)kasKey + (i / 3)) = keyPieceVal;
1317 /* key NOT embedded in keyString */