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>
26 #include <sys/types.h>
33 #include <WINNT/vptab.h>
34 #include <WINNT/afsreg.h>
39 #endif /* AFS_NT40_ENV */
42 #include <rx/rxstat.h>
44 #include <afs/afs_Admin.h>
45 #include <afs/afs_AdminErrors.h>
46 #include <afs/afs_utilAdmin.h>
47 #include <afs/afs_bosAdmin.h>
48 #include <afs/afs_clientAdmin.h>
49 #include <afs/afs_kasAdmin.h>
50 #include <afs/afs_ptsAdmin.h>
53 #include <afs/kautils.h>
54 #include <afs/bnode.h>
55 #include <afs/prerror.h>
57 #include <afs/dirpath.h>
58 #include <afs/cellconfig.h>
60 #include "cfginternal.h"
61 #include "afs_cfgAdmin.h"
62 #include "../adminutil/afs_AdminInternal.h"
66 /* Local declarations and definitions */
69 KasKeyIsZero(kas_encryptionKey_t * kasKey);
72 KasKeyEmbeddedInString(const char *keyString, kas_encryptionKey_t * kasKey);
77 /* ---------------- Exported Server Host functions ------------------ */
81 * cfg_HostQueryStatus() -- Query status of static server configuration
82 * on host, i.e., status of required configuration files, etc.
83 * Upon successful completion *configStP is set to the server
84 * configuration status, with a value of zero (0) indicating that
85 * the configuration is valid.
87 * If server configuration is not valid then *cellNameP is set to NULL;
88 * otherwise, *cellNameP is an allocated buffer containing server cell.
90 * Warning: in determining if server configuration is valid, no check
91 * is made for consistency with other servers in cell; also, the
92 * internal consistency of configuration files may not be verified.
95 cfg_HostQueryStatus(const char *hostName, /* name of host */
96 afs_status_p configStP, /* server config status */
97 char **cellNameP, /* server's cell */
99 { /* completion status */
101 struct afsconf_keys keys;
102 afs_status_t tst2, tst = 0;
103 afs_status_t serverSt = 0;
104 char *serverCellName = NULL;
106 /* validate parameters */
108 if (hostName == NULL || *hostName == '\0') {
109 tst = ADMCFGHOSTNAMENULL;
110 } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) {
111 tst = ADMCFGHOSTNAMETOOLONG;
112 } else if (configStP == NULL) {
113 tst = ADMCFGCONFIGSTATUSPNULL;
114 } else if (cellNameP == NULL) {
115 tst = ADMCFGCELLNAMEPNULL;
118 /* remote configuration not yet supported; hostName must be local host */
123 if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) {
125 } else if (!isLocal) {
126 tst = ADMCFGNOTSUPPORTED;
130 /* check for existence and readability of required server config files */
134 const char *cfgfile[4];
136 cfgfile[0] = AFSDIR_SERVER_THISCELL_FILEPATH;
137 cfgfile[1] = AFSDIR_SERVER_CELLSERVDB_FILEPATH;
138 cfgfile[2] = AFSDIR_SERVER_KEY_FILEPATH;
139 cfgfile[3] = AFSDIR_SERVER_ULIST_FILEPATH;
141 for (i = 0; i < 4; i++) {
143 if ((fd = open(cfgfile[i], O_RDONLY)) < 0) {
150 if (errno == EACCES) {
153 serverSt = ADMCFGSERVERBASICINFOINVALID;
158 /* verify the required server config files to the degree possible */
160 if (tst == 0 && serverSt == 0) {
161 struct afsconf_dir *confdir;
163 if ((confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH)) == NULL) {
164 /* one or more config files appears to be invalid */
165 serverSt = ADMCFGSERVERBASICINFOINVALID;
167 struct afsconf_entry *cellentry = NULL;
169 if (confdir->cellName == NULL || *confdir->cellName == '\0') {
170 /* no cell set for server */
171 serverSt = ADMCFGSERVERNOTINCELL;
172 } else if ((afsconf_GetKeys(confdir, &keys) != 0)
173 || (keys.nkeys == 0)) {
175 serverSt = ADMCFGSERVERNOKEYS;
177 for (cellentry = confdir->entries; cellentry != NULL;
178 cellentry = cellentry->next) {
180 (confdir->cellName, cellentry->cellInfo.name)) {
185 if (cellentry == NULL) {
186 serverSt = ADMCFGSERVERCELLNOTINDB;
187 } else if (cellentry->cellInfo.numServers <= 0) {
188 serverSt = ADMCFGSERVERCELLHASNODBENTRIES;
192 if (tst == 0 && serverSt == 0) {
193 /* everything looks good; malloc cell name buffer to return */
195 (char *)malloc(strlen(cellentry->cellInfo.name) + 1);
196 if (serverCellName == NULL) {
199 strcpy(serverCellName, cellentry->cellInfo.name);
203 (void)afsconf_Close(confdir);
208 /* return server status and cell name */
209 *configStP = serverSt;
212 *cellNameP = serverCellName;
217 /* indicate failure */
220 /* free cell name if allocated before failure */
221 if (serverCellName != NULL) {
222 free(serverCellName);
233 * cfg_HostOpen() -- Obtain host configuration handle.
236 cfg_HostOpen(void *cellHandle, /* cell handle */
237 const char *hostName, /* name of host to configure */
238 void **hostHandleP, /* host config handle */
240 { /* completion status */
242 afs_status_t tst2, tst = 0;
244 char fullHostName[MAXHOSTCHARS];
246 /* validate parameters and resolve host name to fully qualified name */
248 if (!CellHandleIsValid(cellHandle, &tst2)) {
250 } else if (hostName == NULL || *hostName == '\0') {
251 tst = ADMCFGHOSTNAMENULL;
252 } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) {
253 tst = ADMCFGHOSTNAMETOOLONG;
254 } else if (hostHandleP == NULL) {
255 tst = ADMCFGHOSTHANDLEPNULL;
256 } else if (!cfgutil_HostNameGetFull(hostName, fullHostName, &tst2)) {
260 /* remote configuration not yet supported; hostName must be local host */
265 if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) {
267 } else if (!isLocal) {
268 tst = ADMCFGNOTSUPPORTED;
272 /* allocate a host configuration handle */
277 if ((cfg_host = (cfg_host_p) malloc(sizeof(cfg_host_t))) == NULL) {
279 } else if ((localHostName = (char *)malloc(strlen(fullHostName) + 1))
284 /* initialize handle */
285 cfg_host->begin_magic = BEGIN_MAGIC;
286 cfg_host->is_valid = 1;
287 cfg_host->hostName = localHostName;
288 cfg_host->is_local = 1; /* not yet supporting remote config */
289 cfg_host->cellHandle = cellHandle;
290 cfg_host->bosHandle = NULL;
291 cfg_host->end_magic = END_MAGIC;
293 strcpy(localHostName, fullHostName);
295 if (!afsclient_CellNameGet
296 (cfg_host->cellHandle, &cfg_host->cellName, &tst2)) {
298 } else if (pthread_mutex_init(&cfg_host->mutex, NULL)) {
303 /* cell name lookup or mutex initialization failed */
311 /* success; return host config handle to user */
312 *hostHandleP = cfg_host;
314 /* indicate failure */
325 * cfg_HostClose() -- Release host configuration handle.
328 cfg_HostClose(void *hostHandle, /* host config handle */
330 { /* completion status */
332 afs_status_t tst2, tst = 0;
333 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
335 /* validate parameters */
337 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
341 /* free handle; can assume no other thread using this handle */
344 /* mark cfg handle invalid in case use after free (bug catcher) */
345 cfg_host->is_valid = 0;
347 if (cfg_host->bosHandle != NULL) {
348 if (!bos_ServerClose(cfg_host->bosHandle, &tst2)) {
352 free(cfg_host->hostName);
353 (void)pthread_mutex_destroy(&cfg_host->mutex);
368 * cfg_HostSetCell() -- Define server cell membership for host.
370 * The cellDbHosts argument is a multistring containing the names of
371 * the existing database servers already configured in the cell; this
372 * multistring list can be obtained via cfg_CellServDbEnumerate().
373 * If configuring the first server in a new cell then the cellDbHosts
374 * list contains only the name of that host.
376 * Note: The names in cellDbHosts MUST exactly match those in the
377 * cell-wide server CellServDB; using cfg_CellServDbEnumerate()
378 * is highly recommended.
381 cfg_HostSetCell(void *hostHandle, /* host config handle */
382 const char *cellName, /* cell name */
383 const char *cellDbHosts, /* cell database hosts */
385 { /* completion status */
387 afs_status_t tst2, tst = 0;
388 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
390 /* validate parameters */
392 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
394 } else if (cellName == NULL || *cellName == '\0') {
395 tst = ADMCFGCELLNAMENULL;
396 } else if (strlen(cellName) > (MAXCELLCHARS - 1)) {
397 tst = ADMCFGCELLNAMETOOLONG;
398 } else if (!cfgutil_HostHandleCellNameCompatible(cfg_host, cellName)) {
399 tst = ADMCFGCELLNAMECONFLICT;
400 } else if (cellDbHosts == NULL || *cellDbHosts == '\0') {
401 tst = ADMCFGCELLDBHOSTSNULL;
404 /* remote configuration not yet supported in this function */
407 if (!cfg_host->is_local) {
408 tst = ADMCFGNOTSUPPORTED;
412 /* define server cell and cell database hosts */
415 const char *dbHost = cellDbHosts;
416 struct afsconf_cell hostCell;
417 memset(&hostCell, 0, sizeof(hostCell));
419 strcpy(hostCell.name, cellName);
420 hostCell.numServers = 0;
422 while (*dbHost != '\0' && tst == 0) {
423 /* fill in each database host */
424 size_t dbHostLen = strlen(dbHost);
426 if (dbHostLen > (MAXHOSTCHARS - 1)) {
427 tst = ADMCFGHOSTNAMETOOLONG;
428 } else if (hostCell.numServers >= MAXHOSTSPERCELL) {
429 tst = ADMCFGCELLDBHOSTCOUNTTOOLARGE;
431 strcpy(hostCell.hostName[hostCell.numServers++], dbHost);
432 dbHost += dbHostLen + 1;
437 /* create server ThisCell/CellServDB dir if it does not exist */
439 (void)mkdir(AFSDIR_USR_DIRPATH);
440 (void)mkdir(AFSDIR_SERVER_AFS_DIRPATH);
441 (void)mkdir(AFSDIR_SERVER_ETC_DIRPATH);
443 (void)mkdir(AFSDIR_USR_DIRPATH, 0755);
444 (void)mkdir(AFSDIR_SERVER_AFS_DIRPATH, 0755);
445 (void)mkdir(AFSDIR_SERVER_ETC_DIRPATH, 0755);
447 if (afsconf_SetCellInfo
448 (NULL, AFSDIR_SERVER_ETC_DIRPATH, &hostCell)) {
449 /* failed; most likely cause is bad host name */
450 tst = ADMCFGSERVERSETCELLFAILED;
466 * cfg_HostSetAfsPrincipal() -- Put AFS server principal (afs) key in
467 * host's KeyFile; principal is created if it does not exist.
469 * If first server host in cell, passwd must be initial password for
470 * the afs principal; the afs principal is created.
472 * If additional server host, passwd can be specified or NULL; the
473 * afs principal must already exist by definition. If passwd is NULL
474 * then an attempt is made to fetch the afs key. If the key fetch fails
475 * because pre 3.5 database servers are in use (which will only return a
476 * key checksum) then the function fails with a return status of
477 * ADMCFGAFSKEYNOTAVAILABLE; in this case the function should be called
478 * again with passwd specified. If passwd is specified (not NULL) but the
479 * password key fails a checksum comparison with the current afs key
480 * then the function fails with a return status of ADMCFGAFSPASSWDINVALID.
482 * ASSUMPTIONS: Client configured and BOS server started; if first host in
483 * cell then Authentication server must be started as well.
486 cfg_HostSetAfsPrincipal(void *hostHandle, /* host config handle */
487 short isFirst, /* first server in cell flag */
488 const char *passwd, /* afs initial password */
490 { /* completion status */
492 afs_status_t tst2, tst = 0;
493 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
495 /* validate parameters */
497 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
499 } else if ((isFirst && passwd == NULL)
500 || (passwd != NULL && *passwd == '\0')) {
501 tst = ADMCFGPASSWDNULL;
504 /* put afs key in host's KeyFile */
507 kas_identity_t afsIdentity;
508 kas_encryptionKey_t afsKey;
511 strcpy(afsIdentity.principal, "afs");
512 afsIdentity.instance[0] = '\0';
515 /* create afs principal */
516 if (!kas_PrincipalCreate
517 (cfg_host->cellHandle, NULL, &afsIdentity, passwd, &tst2)
518 && tst2 != KAEXIST) {
519 /* failed to create principal (and not because existed) */
525 /* retrive afs principal information to verify or obtain key */
526 kas_principalEntry_t afsEntry;
528 if (!kas_PrincipalGet
529 (cfg_host->cellHandle, NULL, &afsIdentity, &afsEntry,
533 if (passwd != NULL) {
534 /* password given; form key and verify as most recent */
535 kas_encryptionKey_t passwdKey;
536 unsigned int passwdKeyCksum;
539 (cfg_host->cellName, passwd, &passwdKey, &tst2)
540 || !kas_KeyCheckSum(&passwdKey, &passwdKeyCksum,
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 */
552 (&passwdKey, &passwdKeyCksum, &tst2)) {
554 } else if (passwdKeyCksum != afsEntry.keyCheckSum) {
555 /* passwd string does not embed valid key */
556 tst = ADMCFGAFSPASSWDINVALID;
559 /* passwd string does NOT embed key */
560 tst = ADMCFGAFSPASSWDINVALID;
565 /* passwd seems to generate/embed most recent key */
567 afsKvno = afsEntry.keyVersion;
571 /* password NOT given; check if key retrieved since
572 * pre 3.5 database servers only return key checksum
574 if (KasKeyIsZero(&afsEntry.key)) {
575 tst = ADMCFGAFSKEYNOTAVAILABLE;
577 afsKey = afsEntry.key;
578 afsKvno = afsEntry.keyVersion;
585 /* add key to host's KeyFile; RPC must be unauthenticated;
586 * bosserver is presumed to be in noauth mode.
588 void *cellHandle, *bosHandle;
590 if (!afsclient_NullCellOpen(&cellHandle, &tst2)) {
594 (cellHandle, cfg_host->hostName, &bosHandle, &tst2)) {
597 if (!bos_KeyCreate(bosHandle, afsKvno, &afsKey, &tst2)
598 && tst2 != BZKEYINUSE) {
599 /* failed to add key (and not because existed) */
603 if (!bos_ServerClose(bosHandle, &tst2)) {
608 if (!afsclient_CellClose(cellHandle, &tst2)) {
626 * cfg_HostSetAdminPrincipal() -- Put generic administrator principal in
627 * host's UserList; principal is created if it does not exist.
629 * If first server host in cell, passwd and afsUid must be the initial
630 * password and the AFS UID for the admin principal; the admin principal
633 * If additional server host, passwd and afsUid are ignored; the admin
634 * principal is assumed to exist.
636 * ASSUMPTIONS: Client configured and BOS server started; if first host in
637 * cell then Authentication and Protection servers must be started as well.
640 cfg_HostSetAdminPrincipal(void *hostHandle, /* host config handle */
641 short isFirst, /* first server in cell flag */
642 char *admin, /* admin principal name */
643 const char *passwd, /* admin initial password */
644 unsigned int afsUid, /* admin AFS UID */
646 { /* completion status */
648 afs_status_t tst2, tst = 0;
649 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
651 /* validate parameters and prepare host handle for bos functions */
653 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
655 } else if (admin == NULL || *admin == '\0') {
656 tst = ADMCFGADMINPRINCIPALNULL;
657 } else if (strlen(admin) > (KAS_MAX_NAME_LEN - 1)) {
658 tst = ADMCFGADMINPRINCIPALTOOLONG;
659 } else if (isFirst && (passwd == NULL || *passwd == '\0')) {
660 tst = ADMCFGPASSWDNULL;
661 } else if (!cfgutil_HostHandleBosInit(cfg_host, &tst2)) {
665 /* put admin in host's UserList */
669 /* first server host in cell; create admin principal */
670 kas_identity_t adminIdentity;
671 int adminUid = afsUid;
672 kas_admin_t adminFlag = KAS_ADMIN;
674 strcpy(adminIdentity.principal, admin);
675 adminIdentity.instance[0] = '\0';
677 if (!kas_PrincipalCreate
678 (cfg_host->cellHandle, NULL, &adminIdentity, passwd, &tst2)
679 && tst2 != KAEXIST) {
680 /* failed to create principal (and not because existed) */
684 if (!kas_PrincipalFieldsSet
685 (cfg_host->cellHandle, NULL, &adminIdentity, &adminFlag,
686 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
688 /* failed to set admin attributes */
693 (cfg_host->cellHandle, admin, &adminUid, &tst2)
694 && tst2 != PREXIST) {
695 /* failed to create user (and not because existed) */
699 if (!pts_GroupMemberAdd
700 (cfg_host->cellHandle, admin, "system:administrators",
701 &tst2) && tst2 != PRIDEXIST) {
702 /* failed to add to group (not because already there) */
708 /* add admin to host's UserList */
709 if (!bos_AdminCreate(cfg_host->bosHandle, admin, &tst2)
711 /* failed to add admin (and not because existed) */
712 /* DANGER: platform-specific errno values being returned */
729 * cfg_HostInvalidate() -- Invalidate static server configuration on host.
731 * Server configuration invalidated only if BOS server is not running.
734 cfg_HostInvalidate(void *hostHandle, /* host config handle */
736 { /* completion status */
738 afs_status_t tst2, tst = 0;
739 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
741 /* validate parameters */
743 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
747 /* remote configuration not yet supported in this function */
750 if (!cfg_host->is_local) {
751 tst = ADMCFGNOTSUPPORTED;
755 /* make sure bosserver is not running on host */
758 /* Windows - bosserver is controlled via the BOS control service */
762 if (!cfgutil_WindowsServiceQuery
763 (AFSREG_SVR_SVC_NAME, &svcState, &tst2)) {
765 } else if (svcState != SERVICE_STOPPED) {
766 tst = ADMCFGBOSSERVERACTIVE;
771 /* function not yet implemented for Unix */
772 tst = ADMCFGNOTSUPPORTED;
774 #endif /* AFS_NT40_ENV */
777 /* remove server state files */
781 const char *cfgdir[3];
783 cfgdir[0] = AFSDIR_SERVER_ETC_DIRPATH;
784 cfgdir[1] = AFSDIR_SERVER_DB_DIRPATH;
785 cfgdir[2] = AFSDIR_SERVER_LOCAL_DIRPATH;
787 for (i = 0; i < 3 && tst == 0; i++) {
788 if (!cfgutil_CleanDirectory(cfgdir[i], &tst2)) {
794 /* remove all vice partition table entries */
798 struct vpt_iter vpiter;
799 struct vptab vpentry;
801 /* note: ignore errors except from removal attempts */
803 if (!vpt_Start(&vpiter)) {
804 while (!vpt_NextEntry(&vpiter, &vpentry)) {
805 if (vpt_RemoveEntry(vpentry.vp_name)) {
806 /* ENOENT implies entry does not exist; consider removed */
807 if (errno != ENOENT) {
808 if (errno == EACCES) {
811 tst = ADMCFGVPTABLEWRITEFAILED;
816 (void)vpt_Finish(&vpiter);
820 /* function not yet implemented for unix */
822 tst = ADMCFGNOTSUPPORTED;
824 #endif /* AFS_NT40_ENV */
838 * cfg_HostPartitionTableEnumerate() -- Enumerate AFS partition table entries.
840 * If the partition table is empty (or does not exist) then *tablePP
841 * is set to NULL and *nEntriesP is set to zero (0).
843 * Partitions in table are not necessarily those being exported; a table
844 * entry may have been added or removed since the fileserver last started.
847 cfg_HostPartitionTableEnumerate(void *hostHandle, /* host config handle */
848 cfg_partitionEntry_t ** tablePP, /* table */
849 int *nEntriesP, /* table entry count */
851 { /* completion status */
853 afs_status_t tst2, tst = 0;
854 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
856 /* validate parameters */
858 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
860 } else if (tablePP == NULL) {
861 tst = ADMCFGVPTABLEPNULL;
862 } else if (nEntriesP == NULL) {
863 tst = ADMCFGVPTABLECOUNTPNULL;
866 /* remote configuration not yet supported in this function */
869 if (!cfg_host->is_local) {
870 tst = ADMCFGNOTSUPPORTED;
874 /* enumerate the vice partition table */
878 struct vpt_iter vpiter;
879 struct vptab vpentry;
880 int vpentryCountMax = 0;
882 /* count table entries */
884 if (vpt_Start(&vpiter)) {
885 /* ENOENT implies table does not exist (which is OK) */
886 if (errno != ENOENT) {
887 if (errno == EACCES) {
890 tst = ADMCFGVPTABLEREADFAILED;
894 while (!vpt_NextEntry(&vpiter, &vpentry)) {
897 if (errno != ENOENT) {
898 tst = ADMCFGVPTABLEREADFAILED;
900 (void)vpt_Finish(&vpiter);
903 /* alloc storage for table entries; handle any entry count change */
906 if (vpentryCountMax == 0) {
910 /* return a two-part table; first points into second */
912 size_t metaTableSize;
915 vpentryCountMax * (sizeof(cfg_partitionEntry_t) +
916 sizeof(struct vptab));
918 if ((metaTablep = (void *)malloc(metaTableSize)) == NULL) {
922 cfg_partitionEntry_t *cpePart;
923 struct vptab *vptPart;
924 int vpentryCount = 0;
926 cpePart = (cfg_partitionEntry_t *) metaTablep;
927 vptPart = (struct vptab *)(&cpePart[vpentryCountMax]);
929 for (i = 0; i < vpentryCountMax; i++) {
930 cpePart[i].partitionName = vptPart[i].vp_name;
931 cpePart[i].deviceName = vptPart[i].vp_dev;
934 if (vpt_Start(&vpiter)) {
935 /* ENOENT implies table does not exist (which is OK) */
936 if (errno != ENOENT) {
937 if (errno == EACCES) {
940 tst = ADMCFGVPTABLEREADFAILED;
944 for (i = 0; i < vpentryCountMax; i++) {
945 if (vpt_NextEntry(&vpiter, &vptPart[i])) {
950 if (i < vpentryCountMax && errno != ENOENT) {
951 tst = ADMCFGVPTABLEREADFAILED;
955 (void)vpt_Finish(&vpiter);
959 *nEntriesP = vpentryCount;
961 if (vpentryCount != 0) {
962 *tablePP = (cfg_partitionEntry_t *) metaTablep;
975 /* function not yet implemented for Unix */
977 tst = ADMCFGNOTSUPPORTED;
979 #endif /* AFS_NT40_ENV */
992 * cfg_HostPartitionTableAddEntry() -- Add or update AFS partition table entry.
995 cfg_HostPartitionTableAddEntry(void *hostHandle, /* host config handle */
996 const char *partName, /* partition name */
997 const char *devName, /* device name */
999 { /* completion status */
1001 afs_status_t tst = 0;
1004 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
1008 /* validate parameters */
1010 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
1012 } else if (partName == NULL) {
1013 tst = ADMCFGPARTITIONNAMENULL;
1014 } else if (!vpt_PartitionNameValid(partName)) {
1015 tst = ADMCFGPARTITIONNAMEBAD;
1016 } else if (devName == NULL) {
1017 tst = ADMCFGDEVICENAMENULL;
1018 } else if (!vpt_DeviceNameValid(devName)) {
1019 tst = ADMCFGDEVICENAMEBAD;
1022 /* remote configuration not yet supported in this function */
1025 if (!cfg_host->is_local) {
1026 tst = ADMCFGNOTSUPPORTED;
1030 /* add entry to table */
1033 struct vptab vpentry;
1035 strcpy(vpentry.vp_name, partName);
1036 strcpy(vpentry.vp_dev, devName);
1038 if (vpt_AddEntry(&vpentry)) {
1039 if (errno == EACCES) {
1041 } else if (errno == EINVAL) {
1042 /* shouldn't happen since checked partition/dev names */
1043 tst = ADMCFGVPTABLEENTRYBAD;
1045 tst = ADMCFGVPTABLEWRITEFAILED;
1050 /* function not yet implemented for unix */
1052 tst = ADMCFGNOTSUPPORTED;
1054 #endif /* AFS_NT40_ENV */
1067 * cfg_HostPartitionTableRemoveEntry() -- Remove AFS partition table entry.
1070 cfg_HostPartitionTableRemoveEntry(void *hostHandle, /* host config handle */
1071 const char *partName, /* partition name */
1073 { /* completion status */
1075 afs_status_t tst = 0;
1078 cfg_host_p cfg_host = (cfg_host_p) hostHandle;
1082 /* validate parameters */
1084 if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) {
1086 } else if (partName == NULL) {
1087 tst = ADMCFGPARTITIONNAMENULL;
1088 } else if (!vpt_PartitionNameValid(partName)) {
1089 tst = ADMCFGPARTITIONNAMEBAD;
1092 /* remote configuration not yet supported in this function */
1095 if (!cfg_host->is_local) {
1096 tst = ADMCFGNOTSUPPORTED;
1100 /* remove entry from table */
1103 if (vpt_RemoveEntry(partName)) {
1104 /* ENOENT implies entry does not exist; consider to be removed */
1105 if (errno != ENOENT) {
1106 if (errno == EACCES) {
1108 } else if (errno == EINVAL) {
1109 /* shouldn't happen since checked partition/dev names */
1110 tst = ADMCFGPARTITIONNAMEBAD;
1112 tst = ADMCFGVPTABLEWRITEFAILED;
1118 /* function not yet implemented for unix */
1120 tst = ADMCFGNOTSUPPORTED;
1122 #endif /* AFS_NT40_ENV */
1135 * cfg_HostPartitionNameValid() -- check partition name syntax.
1138 cfg_HostPartitionNameValid(const char *partName, /* partition name */
1139 short *isValidP, /* syntax is valid */
1141 { /* completion status */
1143 afs_status_t tst = 0;
1145 /* validate parameters */
1147 if (partName == NULL) {
1148 tst = ADMCFGPARTITIONNAMENULL;
1149 } else if (isValidP == NULL) {
1150 tst = ADMCFGVALIDFLAGPNULL;
1153 /* check name syntax */
1157 *isValidP = vpt_PartitionNameValid(partName);
1160 /* function not yet implemented for Unix */
1162 tst = ADMCFGNOTSUPPORTED;
1178 * cfg_HostDeviceNameValid() -- check device name syntax.
1181 cfg_HostDeviceNameValid(const char *devName, /* device name */
1182 short *isValidP, /* syntax is valid */
1184 { /* completion status */
1186 afs_status_t tst = 0;
1188 /* validate parameters */
1190 if (devName == NULL) {
1191 tst = ADMCFGDEVICENAMENULL;
1192 } else if (isValidP == NULL) {
1193 tst = ADMCFGVALIDFLAGPNULL;
1196 /* check name syntax */
1200 *isValidP = vpt_DeviceNameValid(devName);
1203 /* function not yet implemented for Unix */
1205 tst = ADMCFGNOTSUPPORTED;
1220 /* ---------------- Exported Utility functions ------------------ */
1224 * cfg_StringDeallocate() -- Deallocate (multi)string returned by library.
1227 cfg_StringDeallocate(char *stringDataP, /* (multi)string to deallocate */
1229 { /* completion status */
1230 free((void *)stringDataP);
1239 * cfg_PartitionListDeallocate() -- Deallocate partition table enumeration
1240 * returned by library.
1243 cfg_PartitionListDeallocate(cfg_partitionEntry_t * partitionListDataP,
1246 free((void *)partitionListDataP);
1256 /* ---------------- Local functions ------------------ */
1260 * KasKeyIsZero() -- determine if kas key is zero
1262 * RETURN CODES: 1 if zero, 0 otherwise
1265 KasKeyIsZero(kas_encryptionKey_t * kasKey)
1267 char *keyp = (char *)kasKey;
1270 for (i = 0; i < sizeof(*kasKey); i++) {
1280 * KasKeyEmbeddedInString() -- determine if kas key is embedded in string
1281 * and return key if extant.
1283 * RETURN CODES: 1 if embedded key found, 0 otherwise
1286 KasKeyEmbeddedInString(const char *keyString, kas_encryptionKey_t * kasKey)
1288 char *octalDigits = "01234567";
1290 /* keyString format is exactly 24 octal digits if embeds kas key */
1291 if (strlen(keyString) == 24 && strspn(keyString, octalDigits) == 24) {
1292 /* kas key is embedded in keyString; extract it */
1295 for (i = 0; i < 24; i += 3) {
1297 unsigned char keyPieceVal;
1299 keyPiece[0] = keyString[i];
1300 keyPiece[1] = keyString[i + 1];
1301 keyPiece[2] = keyString[i + 2];
1304 keyPieceVal = (unsigned char)strtoul(keyPiece, NULL, 8);
1306 *((unsigned char *)kasKey + (i / 3)) = keyPieceVal;
1310 /* key NOT embedded in keyString */