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>
27 #include <sys/types.h>
34 #include <WINNT/vptab.h>
35 #include <WINNT/afsreg.h>
40 #endif /* AFS_NT40_ENV */
42 #include <afs/afs_Admin.h>
43 #include <afs/afs_AdminErrors.h>
44 #include <afs/afs_utilAdmin.h>
45 #include <afs/afs_bosAdmin.h>
46 #include <afs/afs_clientAdmin.h>
47 #include <afs/afs_kasAdmin.h>
48 #include <afs/afs_ptsAdmin.h>
51 #include <afs/kautils.h>
52 #include <afs/bnode.h>
53 #include <afs/prerror.h>
55 #include <afs/dirpath.h>
56 #include <afs/cellconfig.h>
58 #include "cfginternal.h"
59 #include "afs_cfgAdmin.h"
60 #include "../adminutil/afs_AdminInternal.h"
64 /* Local declarations and definitions */
67 KasKeyIsZero(kas_encryptionKey_t * kasKey);
70 KasKeyEmbeddedInString(const char *keyString, kas_encryptionKey_t * kasKey);
75 /* ---------------- Exported Server Host functions ------------------ */
79 * cfg_HostQueryStatus() -- Query status of static server configuration
80 * on host, i.e., status of required configuration files, etc.
81 * Upon successful completion *configStP is set to the server
82 * configuration status, with a value of zero (0) indicating that
83 * the configuration is valid.
85 * If server configuration is not valid then *cellNameP is set to NULL;
86 * otherwise, *cellNameP is an allocated buffer containing server cell.
88 * Warning: in determining if server configuration is valid, no check
89 * is made for consistency with other servers in cell; also, the
90 * internal consistency of configuration files may not be verified.
93 cfg_HostQueryStatus(const char *hostName, /* name of host */
94 afs_status_p configStP, /* server config status */
95 char **cellNameP, /* server's cell */
97 { /* completion status */
99 afs_status_t tst2, tst = 0;
100 afs_status_t serverSt = 0;
101 char *serverCellName = NULL;
103 /* validate parameters */
105 if (hostName == NULL || *hostName == '\0') {
106 tst = ADMCFGHOSTNAMENULL;
107 } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) {
108 tst = ADMCFGHOSTNAMETOOLONG;
109 } else if (configStP == NULL) {
110 tst = ADMCFGCONFIGSTATUSPNULL;
111 } else if (cellNameP == NULL) {
112 tst = ADMCFGCELLNAMEPNULL;
115 /* remote configuration not yet supported; hostName must be local host */
120 if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) {
122 } else if (!isLocal) {
123 tst = ADMCFGNOTSUPPORTED;
127 /* check for existence and readability of required server config files */
131 const char *cfgfile[4];
133 cfgfile[0] = AFSDIR_SERVER_THISCELL_FILEPATH;
134 cfgfile[1] = AFSDIR_SERVER_CELLSERVDB_FILEPATH;
135 cfgfile[2] = AFSDIR_SERVER_KEY_FILEPATH;
136 cfgfile[3] = AFSDIR_SERVER_ULIST_FILEPATH;
138 for (i = 0; i < 4; i++) {
140 if ((fd = open(cfgfile[i], O_RDONLY)) < 0) {
147 if (errno == EACCES) {
150 serverSt = ADMCFGSERVERBASICINFOINVALID;
155 /* verify the required server config files to the degree possible */
157 if (tst == 0 && serverSt == 0) {
158 struct afsconf_dir *confdir;
160 if ((confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH)) == NULL) {
161 /* one or more config files appears to be invalid */
162 serverSt = ADMCFGSERVERBASICINFOINVALID;
164 struct afsconf_entry *cellentry;
166 if (confdir->cellName == NULL || *confdir->cellName == '\0') {
167 /* no cell set for server */
168 serverSt = ADMCFGSERVERNOTINCELL;
169 } else if (confdir->keystr == NULL || confdir->keystr->nkeys == 0) {
171 serverSt = ADMCFGSERVERNOKEYS;
173 for (cellentry = confdir->entries; cellentry != NULL;
174 cellentry = cellentry->next) {
176 (confdir->cellName, cellentry->cellInfo.name)) {
181 if (cellentry == NULL) {
182 serverSt = ADMCFGSERVERCELLNOTINDB;
183 } else if (cellentry->cellInfo.numServers <= 0) {
184 serverSt = ADMCFGSERVERCELLHASNODBENTRIES;
188 if (tst == 0 && serverSt == 0) {
189 /* everything looks good; malloc cell name buffer to return */
191 (char *)malloc(strlen(cellentry->cellInfo.name) + 1);
192 if (serverCellName == NULL) {
195 strcpy(serverCellName, cellentry->cellInfo.name);
199 (void)afsconf_Close(confdir);
204 /* return server status and cell name */
205 *configStP = serverSt;
208 *cellNameP = serverCellName;
213 /* indicate failure */
216 /* free cell name if allocated before failure */
217 if (serverCellName != NULL) {
218 free(serverCellName);
229 * cfg_HostOpen() -- Obtain host configuration handle.
232 cfg_HostOpen(void *cellHandle, /* cell handle */
233 const char *hostName, /* name of host to configure */
234 void **hostHandleP, /* host config handle */
236 { /* completion status */
238 afs_status_t tst2, tst = 0;
240 char fullHostName[MAXHOSTCHARS];
242 /* validate parameters and resolve host name to fully qualified name */
244 if (!CellHandleIsValid(cellHandle, &tst2)) {
246 } else if (hostName == NULL || *hostName == '\0') {
247 tst = ADMCFGHOSTNAMENULL;
248 } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) {
249 tst = ADMCFGHOSTNAMETOOLONG;
250 } else if (hostHandleP == NULL) {
251 tst = ADMCFGHOSTHANDLEPNULL;
252 } else if (!cfgutil_HostNameGetFull(hostName, fullHostName, &tst2)) {
256 /* remote configuration not yet supported; hostName must be local host */
261 if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) {
263 } else if (!isLocal) {
264 tst = ADMCFGNOTSUPPORTED;
268 /* allocate a host configuration handle */
273 if ((cfg_host = (cfg_host_p) malloc(sizeof(cfg_host_t))) == NULL) {
275 } else if ((localHostName = (char *)malloc(strlen(fullHostName) + 1))
280 /* initialize handle */
281 cfg_host->begin_magic = BEGIN_MAGIC;
282 cfg_host->is_valid = 1;
283 cfg_host->hostName = localHostName;
284 cfg_host->is_local = 1; /* not yet supporting remote config */
285 cfg_host->cellHandle = cellHandle;
286 cfg_host->bosHandle = NULL;
287 cfg_host->end_magic = END_MAGIC;
289 strcpy(localHostName, fullHostName);
291 if (!afsclient_CellNameGet
292 (cfg_host->cellHandle, &cfg_host->cellName, &tst2)) {
294 } else if (pthread_mutex_init(&cfg_host->mutex, NULL)) {
299 /* cell name lookup or mutex initialization failed */
307 /* success; return host config handle to user */
308 *hostHandleP = cfg_host;
310 /* indicate failure */
321 * cfg_HostClose() -- Release host configuration handle.
324 cfg_HostClose(void *hostHandle, /* host config handle */
326 { /* completion status */
328 afs_status_t tst2, tst = 0;
329 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
331 /* validate parameters */
333 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
337 /* free handle; can assume no other thread using this handle */
340 /* mark cfg handle invalid in case use after free (bug catcher) */
341 cfg_host->is_valid = 0;
343 if (cfg_host->bosHandle != NULL) {
344 if (!bos_ServerClose(cfg_host->bosHandle, &tst2)) {
348 free(cfg_host->hostName);
349 (void)pthread_mutex_destroy(&cfg_host->mutex);
364 * cfg_HostSetCell() -- Define server cell membership for host.
366 * The cellDbHosts argument is a multistring containing the names of
367 * the existing database servers already configured in the cell; this
368 * multistring list can be obtained via cfg_CellServDbEnumerate().
369 * If configuring the first server in a new cell then the cellDbHosts
370 * list contains only the name of that host.
372 * Note: The names in cellDbHosts MUST exactly match those in the
373 * cell-wide server CellServDB; using cfg_CellServDbEnumerate()
374 * is highly recommended.
377 cfg_HostSetCell(void *hostHandle, /* host config handle */
378 const char *cellName, /* cell name */
379 const char *cellDbHosts, /* cell database hosts */
381 { /* completion status */
383 afs_status_t tst2, tst = 0;
384 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
386 /* validate parameters */
388 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
390 } else if (cellName == NULL || *cellName == '\0') {
391 tst = ADMCFGCELLNAMENULL;
392 } else if (strlen(cellName) > (MAXCELLCHARS - 1)) {
393 tst = ADMCFGCELLNAMETOOLONG;
394 } else if (!cfgutil_HostHandleCellNameCompatible(cfg_host, cellName)) {
395 tst = ADMCFGCELLNAMECONFLICT;
396 } else if (cellDbHosts == NULL || *cellDbHosts == '\0') {
397 tst = ADMCFGCELLDBHOSTSNULL;
400 /* remote configuration not yet supported in this function */
403 if (!cfg_host->is_local) {
404 tst = ADMCFGNOTSUPPORTED;
408 /* define server cell and cell database hosts */
411 const char *dbHost = cellDbHosts;
412 struct afsconf_cell hostCell;
413 memset(&hostCell, 0, sizeof(hostCell));
415 strcpy(hostCell.name, cellName);
416 hostCell.numServers = 0;
418 while (*dbHost != '\0' && tst == 0) {
419 /* fill in each database host */
420 size_t dbHostLen = strlen(dbHost);
422 if (dbHostLen > (MAXHOSTCHARS - 1)) {
423 tst = ADMCFGHOSTNAMETOOLONG;
424 } else if (hostCell.numServers >= MAXHOSTSPERCELL) {
425 tst = ADMCFGCELLDBHOSTCOUNTTOOLARGE;
427 strcpy(hostCell.hostName[hostCell.numServers++], dbHost);
428 dbHost += dbHostLen + 1;
433 /* create server ThisCell/CellServDB dir if it does not exist */
435 (void)mkdir(AFSDIR_USR_DIRPATH);
436 (void)mkdir(AFSDIR_SERVER_AFS_DIRPATH);
437 (void)mkdir(AFSDIR_SERVER_ETC_DIRPATH);
439 (void)mkdir(AFSDIR_USR_DIRPATH, 0755);
440 (void)mkdir(AFSDIR_SERVER_AFS_DIRPATH, 0755);
441 (void)mkdir(AFSDIR_SERVER_ETC_DIRPATH, 0755);
443 if (afsconf_SetCellInfo
444 (NULL, AFSDIR_SERVER_ETC_DIRPATH, &hostCell)) {
445 /* failed; most likely cause is bad host name */
446 tst = ADMCFGSERVERSETCELLFAILED;
462 * cfg_HostSetAfsPrincipal() -- Put AFS server principal (afs) key in
463 * host's KeyFile; principal is created if it does not exist.
465 * If first server host in cell, passwd must be initial password for
466 * the afs principal; the afs principal is created.
468 * If additional server host, passwd can be specified or NULL; the
469 * afs principal must already exist by definition. If passwd is NULL
470 * then an attempt is made to fetch the afs key. If the key fetch fails
471 * because pre 3.5 database servers are in use (which will only return a
472 * key checksum) then the function fails with a return status of
473 * ADMCFGAFSKEYNOTAVAILABLE; in this case the function should be called
474 * again with passwd specified. If passwd is specified (not NULL) but the
475 * password key fails a checksum comparison with the current afs key
476 * then the function fails with a return status of ADMCFGAFSPASSWDINVALID.
478 * ASSUMPTIONS: Client configured and BOS server started; if first host in
479 * cell then Authentication server must be started as well.
482 cfg_HostSetAfsPrincipal(void *hostHandle, /* host config handle */
483 short isFirst, /* first server in cell flag */
484 const char *passwd, /* afs initial password */
486 { /* completion status */
488 afs_status_t tst2, tst = 0;
489 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
491 /* validate parameters */
493 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
495 } else if ((isFirst && passwd == NULL)
496 || (passwd != NULL && *passwd == '\0')) {
497 tst = ADMCFGPASSWDNULL;
500 /* put afs key in host's KeyFile */
503 kas_identity_t afsIdentity;
504 kas_encryptionKey_t afsKey;
507 strcpy(afsIdentity.principal, "afs");
508 afsIdentity.instance[0] = '\0';
511 /* create afs principal */
512 if (!kas_PrincipalCreate
513 (cfg_host->cellHandle, NULL, &afsIdentity, passwd, &tst2)
514 && tst2 != KAEXIST) {
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
525 (cfg_host->cellHandle, NULL, &afsIdentity, &afsEntry,
529 if (passwd != NULL) {
530 /* password given; form key and verify as most recent */
531 kas_encryptionKey_t passwdKey;
532 unsigned int passwdKeyCksum;
535 (cfg_host->cellName, passwd, &passwdKey, &tst2)
536 || !kas_KeyCheckSum(&passwdKey, &passwdKeyCksum,
538 /* failed to form key or key checksum */
541 } else if (passwdKeyCksum != afsEntry.keyCheckSum) {
542 /* passwd string does not generate most recent key;
543 * check if passwd string embeds key directly.
545 if (KasKeyEmbeddedInString(passwd, &passwdKey)) {
546 /* passwd string embeds kas key */
548 (&passwdKey, &passwdKeyCksum, &tst2)) {
550 } else if (passwdKeyCksum != afsEntry.keyCheckSum) {
551 /* passwd string does not embed valid key */
552 tst = ADMCFGAFSPASSWDINVALID;
555 /* passwd string does NOT embed key */
556 tst = ADMCFGAFSPASSWDINVALID;
561 /* passwd seems to generate/embed most recent key */
563 afsKvno = afsEntry.keyVersion;
567 /* password NOT given; check if key retrieved since
568 * pre 3.5 database servers only return key checksum
570 if (KasKeyIsZero(&afsEntry.key)) {
571 tst = ADMCFGAFSKEYNOTAVAILABLE;
573 afsKey = afsEntry.key;
574 afsKvno = afsEntry.keyVersion;
581 /* add key to host's KeyFile; RPC must be unauthenticated;
582 * bosserver is presumed to be in noauth mode.
584 void *cellHandle, *bosHandle;
586 if (!afsclient_NullCellOpen(&cellHandle, &tst2)) {
590 (cellHandle, cfg_host->hostName, &bosHandle, &tst2)) {
593 if (!bos_KeyCreate(bosHandle, afsKvno, &afsKey, &tst2)
594 && tst2 != BZKEYINUSE) {
595 /* failed to add key (and not because existed) */
599 if (!bos_ServerClose(bosHandle, &tst2)) {
604 if (!afsclient_CellClose(cellHandle, &tst2)) {
622 * cfg_HostSetAdminPrincipal() -- Put generic administrator principal in
623 * host's UserList; principal is created if it does not exist.
625 * If first server host in cell, passwd and afsUid must be the initial
626 * password and the AFS UID for the admin principal; the admin principal
629 * If additional server host, passwd and afsUid are ignored; the admin
630 * principal is assumed to exist.
632 * ASSUMPTIONS: Client configured and BOS server started; if first host in
633 * cell then Authentication and Protection servers must be started as well.
636 cfg_HostSetAdminPrincipal(void *hostHandle, /* host config handle */
637 short isFirst, /* first server in cell flag */
638 const char *admin, /* admin principal name */
639 const char *passwd, /* admin initial password */
640 unsigned int afsUid, /* admin AFS UID */
642 { /* completion status */
644 afs_status_t tst2, tst = 0;
645 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
647 /* validate parameters and prepare host handle for bos functions */
649 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
651 } else if (admin == NULL || *admin == '\0') {
652 tst = ADMCFGADMINPRINCIPALNULL;
653 } else if (strlen(admin) > (KAS_MAX_NAME_LEN - 1)) {
654 tst = ADMCFGADMINPRINCIPALTOOLONG;
655 } else if (isFirst && (passwd == NULL || *passwd == '\0')) {
656 tst = ADMCFGPASSWDNULL;
657 } else if (!cfgutil_HostHandleBosInit(cfg_host, &tst2)) {
661 /* put admin in host's UserList */
665 /* first server host in cell; create admin principal */
666 kas_identity_t adminIdentity;
667 int adminUid = afsUid;
668 kas_admin_t adminFlag = KAS_ADMIN;
670 strcpy(adminIdentity.principal, admin);
671 adminIdentity.instance[0] = '\0';
673 if (!kas_PrincipalCreate
674 (cfg_host->cellHandle, NULL, &adminIdentity, passwd, &tst2)
675 && tst2 != KAEXIST) {
676 /* failed to create principal (and not because existed) */
680 if (!kas_PrincipalFieldsSet
681 (cfg_host->cellHandle, NULL, &adminIdentity, &adminFlag,
682 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
684 /* failed to set admin attributes */
689 (cfg_host->cellHandle, admin, &adminUid, &tst2)
690 && tst2 != PREXIST) {
691 /* failed to create user (and not because existed) */
695 if (!pts_GroupMemberAdd
696 (cfg_host->cellHandle, admin, "system:administrators",
697 &tst2) && tst2 != PRIDEXIST) {
698 /* failed to add to group (not because already there) */
704 /* add admin to host's UserList */
705 if (!bos_AdminCreate(cfg_host->bosHandle, admin, &tst2)
707 /* failed to add admin (and not because existed) */
708 /* DANGER: platform-specific errno values being returned */
725 * cfg_HostInvalidate() -- Invalidate static server configuration on host.
727 * Server configuration invalidated only if BOS server is not running.
730 cfg_HostInvalidate(void *hostHandle, /* host config handle */
732 { /* completion status */
734 afs_status_t tst2, tst = 0;
735 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
737 /* validate parameters */
739 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
743 /* remote configuration not yet supported in this function */
746 if (!cfg_host->is_local) {
747 tst = ADMCFGNOTSUPPORTED;
751 /* make sure bosserver is not running on host */
754 /* Windows - bosserver is controlled via the BOS control service */
758 if (!cfgutil_WindowsServiceQuery
759 (AFSREG_SVR_SVC_NAME, &svcState, &tst2)) {
761 } else if (svcState != SERVICE_STOPPED) {
762 tst = ADMCFGBOSSERVERACTIVE;
767 /* function not yet implemented for Unix */
768 tst = ADMCFGNOTSUPPORTED;
770 #endif /* AFS_NT40_ENV */
773 /* remove server state files */
777 const char *cfgdir[3];
779 cfgdir[0] = AFSDIR_SERVER_ETC_DIRPATH;
780 cfgdir[1] = AFSDIR_SERVER_DB_DIRPATH;
781 cfgdir[2] = AFSDIR_SERVER_LOCAL_DIRPATH;
783 for (i = 0; i < 3 && tst == 0; i++) {
784 if (!cfgutil_CleanDirectory(cfgdir[i], &tst2)) {
790 /* remove all vice partition table entries */
794 struct vpt_iter vpiter;
795 struct vptab vpentry;
797 /* note: ignore errors except from removal attempts */
799 if (!vpt_Start(&vpiter)) {
800 while (!vpt_NextEntry(&vpiter, &vpentry)) {
801 if (vpt_RemoveEntry(vpentry.vp_name)) {
802 /* ENOENT implies entry does not exist; consider removed */
803 if (errno != ENOENT) {
804 if (errno == EACCES) {
807 tst = ADMCFGVPTABLEWRITEFAILED;
812 (void)vpt_Finish(&vpiter);
816 /* function not yet implemented for unix */
818 tst = ADMCFGNOTSUPPORTED;
820 #endif /* AFS_NT40_ENV */
834 * cfg_HostPartitionTableEnumerate() -- Enumerate AFS partition table entries.
836 * If the partition table is empty (or does not exist) then *tablePP
837 * is set to NULL and *nEntriesP is set to zero (0).
839 * Partitions in table are not necessarily those being exported; a table
840 * entry may have been added or removed since the fileserver last started.
843 cfg_HostPartitionTableEnumerate(void *hostHandle, /* host config handle */
844 cfg_partitionEntry_t ** tablePP, /* table */
845 int *nEntriesP, /* table entry count */
847 { /* completion status */
849 afs_status_t tst2, tst = 0;
850 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
852 /* validate parameters */
854 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
856 } else if (tablePP == NULL) {
857 tst = ADMCFGVPTABLEPNULL;
858 } else if (nEntriesP == NULL) {
859 tst = ADMCFGVPTABLECOUNTPNULL;
862 /* remote configuration not yet supported in this function */
865 if (!cfg_host->is_local) {
866 tst = ADMCFGNOTSUPPORTED;
870 /* enumerate the vice partition table */
874 struct vpt_iter vpiter;
875 struct vptab vpentry;
876 int vpentryCountMax = 0;
878 /* count table entries */
880 if (vpt_Start(&vpiter)) {
881 /* ENOENT implies table does not exist (which is OK) */
882 if (errno != ENOENT) {
883 if (errno == EACCES) {
886 tst = ADMCFGVPTABLEREADFAILED;
890 while (!vpt_NextEntry(&vpiter, &vpentry)) {
893 if (errno != ENOENT) {
894 tst = ADMCFGVPTABLEREADFAILED;
896 (void)vpt_Finish(&vpiter);
899 /* alloc storage for table entries; handle any entry count change */
902 if (vpentryCountMax == 0) {
906 /* return a two-part table; first points into second */
908 size_t metaTableSize;
911 vpentryCountMax * (sizeof(cfg_partitionEntry_t) +
912 sizeof(struct vptab));
914 if ((metaTablep = (void *)malloc(metaTableSize)) == NULL) {
918 cfg_partitionEntry_t *cpePart;
919 struct vptab *vptPart;
920 int vpentryCount = 0;
922 cpePart = (cfg_partitionEntry_t *) metaTablep;
923 vptPart = (struct vptab *)(&cpePart[vpentryCountMax]);
925 for (i = 0; i < vpentryCountMax; i++) {
926 cpePart[i].partitionName = vptPart[i].vp_name;
927 cpePart[i].deviceName = vptPart[i].vp_dev;
930 if (vpt_Start(&vpiter)) {
931 /* ENOENT implies table does not exist (which is OK) */
932 if (errno != ENOENT) {
933 if (errno == EACCES) {
936 tst = ADMCFGVPTABLEREADFAILED;
940 for (i = 0; i < vpentryCountMax; i++) {
941 if (vpt_NextEntry(&vpiter, &vptPart[i])) {
946 if (i < vpentryCountMax && errno != ENOENT) {
947 tst = ADMCFGVPTABLEREADFAILED;
951 (void)vpt_Finish(&vpiter);
955 *nEntriesP = vpentryCount;
957 if (vpentryCount != 0) {
958 *tablePP = (cfg_partitionEntry_t *) metaTablep;
971 /* function not yet implemented for Unix */
973 tst = ADMCFGNOTSUPPORTED;
975 #endif /* AFS_NT40_ENV */
988 * cfg_HostPartitionTableAddEntry() -- Add or update AFS partition table entry.
991 cfg_HostPartitionTableAddEntry(void *hostHandle, /* host config handle */
992 const char *partName, /* partition name */
993 const char *devName, /* device name */
995 { /* completion status */
997 afs_status_t tst2, tst = 0;
998 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
1001 /* validate parameters */
1003 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
1005 } else if (partName == NULL) {
1006 tst = ADMCFGPARTITIONNAMENULL;
1007 } else if (!vpt_PartitionNameValid(partName)) {
1008 tst = ADMCFGPARTITIONNAMEBAD;
1009 } else if (devName == NULL) {
1010 tst = ADMCFGDEVICENAMENULL;
1011 } else if (!vpt_DeviceNameValid(devName)) {
1012 tst = ADMCFGDEVICENAMEBAD;
1015 /* remote configuration not yet supported in this function */
1018 if (!cfg_host->is_local) {
1019 tst = ADMCFGNOTSUPPORTED;
1023 /* add entry to table */
1026 struct vptab vpentry;
1028 strcpy(vpentry.vp_name, partName);
1029 strcpy(vpentry.vp_dev, devName);
1031 if (vpt_AddEntry(&vpentry)) {
1032 if (errno == EACCES) {
1034 } else if (errno == EINVAL) {
1035 /* shouldn't happen since checked partition/dev names */
1036 tst = ADMCFGVPTABLEENTRYBAD;
1038 tst = ADMCFGVPTABLEWRITEFAILED;
1043 /* function not yet implemented for unix */
1045 tst = ADMCFGNOTSUPPORTED;
1047 #endif /* AFS_NT40_ENV */
1060 * cfg_HostPartitionTableRemoveEntry() -- Remove AFS partition table entry.
1063 cfg_HostPartitionTableRemoveEntry(void *hostHandle, /* host config handle */
1064 const char *partName, /* partition name */
1066 { /* completion status */
1068 afs_status_t tst2, tst = 0;
1069 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
1072 /* validate parameters */
1074 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
1076 } else if (partName == NULL) {
1077 tst = ADMCFGPARTITIONNAMENULL;
1078 } else if (!vpt_PartitionNameValid(partName)) {
1079 tst = ADMCFGPARTITIONNAMEBAD;
1082 /* remote configuration not yet supported in this function */
1085 if (!cfg_host->is_local) {
1086 tst = ADMCFGNOTSUPPORTED;
1090 /* remove entry from table */
1093 if (vpt_RemoveEntry(partName)) {
1094 /* ENOENT implies entry does not exist; consider to be removed */
1095 if (errno != ENOENT) {
1096 if (errno == EACCES) {
1098 } else if (errno == EINVAL) {
1099 /* shouldn't happen since checked partition/dev names */
1100 tst = ADMCFGPARTITIONNAMEBAD;
1102 tst = ADMCFGVPTABLEWRITEFAILED;
1108 /* function not yet implemented for unix */
1110 tst = ADMCFGNOTSUPPORTED;
1112 #endif /* AFS_NT40_ENV */
1125 * cfg_HostPartitionNameValid() -- check partition name syntax.
1128 cfg_HostPartitionNameValid(const char *partName, /* partition name */
1129 short *isValidP, /* syntax is valid */
1131 { /* completion status */
1133 afs_status_t tst = 0;
1135 /* validate parameters */
1137 if (partName == NULL) {
1138 tst = ADMCFGPARTITIONNAMENULL;
1139 } else if (isValidP == NULL) {
1140 tst = ADMCFGVALIDFLAGPNULL;
1143 /* check name syntax */
1147 *isValidP = vpt_PartitionNameValid(partName);
1150 /* function not yet implemented for Unix */
1152 tst = ADMCFGNOTSUPPORTED;
1168 * cfg_HostDeviceNameValid() -- check device name syntax.
1171 cfg_HostDeviceNameValid(const char *devName, /* device name */
1172 short *isValidP, /* syntax is valid */
1174 { /* completion status */
1176 afs_status_t tst = 0;
1178 /* validate parameters */
1180 if (devName == NULL) {
1181 tst = ADMCFGDEVICENAMENULL;
1182 } else if (isValidP == NULL) {
1183 tst = ADMCFGVALIDFLAGPNULL;
1186 /* check name syntax */
1190 *isValidP = vpt_DeviceNameValid(devName);
1193 /* function not yet implemented for Unix */
1195 tst = ADMCFGNOTSUPPORTED;
1210 /* ---------------- Exported Utility functions ------------------ */
1214 * cfg_StringDeallocate() -- Deallocate (multi)string returned by library.
1217 cfg_StringDeallocate(char *stringDataP, /* (multi)string to deallocate */
1219 { /* completion status */
1220 free((void *)stringDataP);
1229 * cfg_PartitionListDeallocate() -- Deallocate partition table enumeration
1230 * returned by library.
1233 cfg_PartitionListDeallocate(cfg_partitionEntry_t * partitionListDataP,
1236 free((void *)partitionListDataP);
1246 /* ---------------- Local functions ------------------ */
1250 * KasKeyIsZero() -- determine if kas key is zero
1252 * RETURN CODES: 1 if zero, 0 otherwise
1255 KasKeyIsZero(kas_encryptionKey_t * kasKey)
1257 char *keyp = (char *)kasKey;
1260 for (i = 0; i < sizeof(*kasKey); i++) {
1270 * KasKeyEmbeddedInString() -- determine if kas key is embedded in string
1271 * and return key if extant.
1273 * RETURN CODES: 1 if embedded key found, 0 otherwise
1276 KasKeyEmbeddedInString(const char *keyString, kas_encryptionKey_t * kasKey)
1278 char *octalDigits = "01234567";
1280 /* keyString format is exactly 24 octal digits if embeds kas key */
1281 if (strlen(keyString) == 24 && strspn(keyString, octalDigits) == 24) {
1282 /* kas key is embedded in keyString; extract it */
1285 for (i = 0; i < 24; i += 3) {
1287 unsigned char keyPieceVal;
1289 keyPiece[0] = keyString[i];
1290 keyPiece[1] = keyString[i + 1];
1291 keyPiece[2] = keyString[i + 2];
1294 keyPieceVal = (unsigned char)strtoul(keyPiece, NULL, 8);
1296 *((unsigned char *)kasKey + (i / 3)) = keyPieceVal;
1300 /* key NOT embedded in keyString */