.idl.h:
midl $(MIDL_FLAGS) $(AFSDEV_AUXMIDLFLAGS) $<
+
+AFSD_SDKLIBS =\
+ netapi32.lib \
+ dnsapi.lib \
+ mpr.lib \
+ rpcrt4.lib \
+ user32.lib \
+ Dbghelp.lib \
+ strsafe.lib \
+ mpr.lib \
+ secur32.lib \
+ ole32.lib \
+ oleaut32.lib \
+ iphlpapi.lib \
+ shell32.lib \
+ shlwapi.lib
+
############################################################################
# libafsconf.dll
$(DESTDIR)\lib\afs\afsreg.lib
$(CONF_DLLFILE): $(CONFOBJS) $(OUT)\libafsconf.res $(CONF_DLLLIBS)
- $(DLLGUILINK) -def:libafsconf.def dnsapi.lib mpr.lib shell32.lib Rpcrt4.lib
+ $(DLLGUILINK) -def:libafsconf.def $(AFSD_SDKLIBS)
$(_VC_MANIFEST_EMBED_DLL)
$(DLLPREP)
$(CODESIGN_USERLAND)
# afsd.exe
AFSD_EXEFILE = $(EXEDIR)\afsd.exe
-AFSD_SDKLIBS =\
- netapi32.lib \
- dnsapi.lib \
- mpr.lib \
- rpcrt4.lib \
- user32.lib \
- Dbghelp.lib \
- strsafe.lib \
- mpr.lib \
- secur32.lib \
- ole32.lib \
- oleaut32.lib \
- iphlpapi.lib shell32.lib shlwapi.lib
-
AFSD_EXELIBS =\
$(DESTDIR)\lib\libosi.lib \
$(DESTDIR)\lib\afs\mtafsvldb.lib \
}
}
+long
+cm_CreateCellWithInfo( char * cellname,
+ char * linked_cellname,
+ unsigned short vlport,
+ afs_uint32 host_count,
+ char *hostname[],
+ afs_uint32 flags)
+{
+ afs_uint32 code = 0;
+ cm_cell_rock_t rock;
+ struct hostent *thp;
+ struct sockaddr_in vlSockAddr;
+ afs_uint32 i, j;
+
+ rock.cellp = cm_GetCell(cellname, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
+ rock.flags = 0;
+
+ cm_FreeServerList(&rock.cellp->vlServersp, CM_FREESERVERLIST_DELETE);
+
+ if (!(flags & CM_CELLFLAG_DNS)) {
+ for (i = 0; i < host_count; i++) {
+ thp = gethostbyname(hostname[i]);
+ if (thp) {
+ int foundAddr = 0;
+ for (j=0 ; thp->h_addr_list[j]; j++) {
+ if (thp->h_addrtype != AF_INET)
+ continue;
+ memcpy(&vlSockAddr.sin_addr.s_addr,
+ thp->h_addr_list[j],
+ sizeof(long));
+ vlSockAddr.sin_port = htons(vlport ? vlport : 7003);
+ vlSockAddr.sin_family = AF_INET;
+ cm_AddCellProc(&rock, &vlSockAddr, hostname[i], CM_FLAG_NOPROBE);
+ }
+ }
+ }
+ lock_ObtainMutex(&rock.cellp->mx);
+ rock.cellp->flags &= ~CM_CELLFLAG_DNS;
+ } else if (cm_dnsEnabled) {
+ int ttl;
+
+ code = cm_SearchCellByDNS(rock.cellp->name, NULL, &ttl, cm_AddCellProc, &rock);
+ lock_ObtainMutex(&rock.cellp->mx);
+ if (code == 0) { /* got cell from DNS */
+ rock.cellp->flags |= CM_CELLFLAG_DNS;
+ rock.cellp->timeout = time(0) + ttl;
+#ifdef DEBUG
+ fprintf(stderr, "cell %s: ttl=%d\n", rock.cellp->name, ttl);
+#endif
+ }
+ } else {
+ lock_ObtainMutex(&rock.cellp->mx);
+ rock.cellp->flags &= ~CM_CELLFLAG_DNS;
+ }
+ rock.cellp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
+ StringCbCopy(rock.cellp->linkedName, CELL_MAXNAMELEN, linked_cellname);
+ lock_ReleaseMutex(&rock.cellp->mx);
+
+ if (rock.cellp->vlServersp)
+ cm_RandomizeServer(&rock.cellp->vlServersp);
+
+ return code;
+}
extern cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags);
+extern long cm_CreateCellWithInfo( char * cellname,
+ char * linked_cellname,
+ unsigned short vlport, afs_uint32 host_count,
+ char *hostname[], afs_uint32 flags);
+
#endif /* __CELL_H_ENV_ */
#include <windows.h>
#include <winsock2.h>
+#include <shlwapi.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
return ((dwForceDNS || dwServers == 0) ? CM_ERROR_FORCE_DNS_LOOKUP : 0);
}
-long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellRegistryProc_t *procp, void *rockp)
+/*
+ * Following the registry schema listed above, cm_AddCellToRegistry
+ * will either create or update the registry configuration data for
+ * the specified cellname.
+ */
+long cm_AddCellToRegistry( char * cellname,
+ char * linked_cellname,
+ unsigned short vlport,
+ afs_uint32 host_count,
+ char *hostname[],
+ afs_uint32 flags)
+{
+ HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0;
+ DWORD dwPort, dwDisposition;
+ long code;
+ unsigned int i;
+
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ NULL,
+ &hkCellServDB,
+ &dwDisposition) != ERROR_SUCCESS) {
+ code = CM_ERROR_NOACCESS;
+ goto done;
+ }
+
+ /* Perform a recursive deletion of the cellname key */
+ SHDeleteKey( hkCellServDB, cellname);
+
+ if (RegCreateKeyEx( hkCellServDB,
+ cellname,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ NULL,
+ &hkCellName,
+ &dwDisposition) != ERROR_SUCCESS ||
+ (dwDisposition == REG_OPENED_EXISTING_KEY) ) {
+ code = CM_ERROR_NOACCESS;
+ goto done;
+ }
+
+ /* If we get here, hkCellName is a handle to an empty key */
+
+ if (linked_cellname && linked_cellname[0]) {
+ code = RegSetValueEx( hkCellName, "LinkedCell",
+ 0, REG_SZ,
+ (BYTE *) linked_cellname, CELL_MAXNAMELEN);
+ }
+
+ if (flags & CM_CELLFLAG_DNS) {
+ DWORD dwForceDNS = 1;
+ code = RegSetValueEx( hkCellName, "ForceDNS",
+ 0, REG_DWORD,
+ (BYTE *) &dwForceDNS, sizeof(DWORD));
+ }
+
+ for ( i = 0; i < host_count; i++ ) {
+ if (RegCreateKeyEx( hkCellName,
+ hostname[i],
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ NULL,
+ &hkServerName,
+ &dwDisposition) != ERROR_SUCCESS ||
+ (dwDisposition == REG_OPENED_EXISTING_KEY)) {
+ code = CM_ERROR_NOACCESS;
+ goto done;
+ }
+
+ /* We have a handle to a valid server key. Now we need
+ * to add the server to the cell */
+
+ /* First, see if there is an alternate hostname specified */
+ code = RegSetValueEx( hkServerName, "HostName",
+ 0, REG_SZ,
+ (BYTE *) hostname[i], (DWORD)strlen(hostname[i]) + 1);
+
+ if (vlport) {
+ dwPort = vlport;
+ code = RegSetValueEx( hkServerName, "vlserver",
+ 0, REG_DWORD,
+ (BYTE *) &dwPort, (DWORD)sizeof(DWORD));
+ }
+ RegCloseKey( hkServerName);
+ hkServerName = 0;
+ }
+
+ done:
+ if (hkServerName)
+ RegCloseKey(hkServerName);
+ if (hkCellName)
+ RegCloseKey(hkCellName);
+ if (hkCellServDB)
+ RegCloseKey(hkCellServDB);
+
+ return code;
+}
+
+long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellProc_t *procp, void *rockp)
{
HKEY hkCellServDB = 0;
DWORD dwSize;
extern long cm_CloseCellFile(cm_configFile_t *filep);
+extern long cm_AddCellToRegistry( char * cellname,
+ char * linked_cellname,
+ unsigned short vlport,
+ afs_uint32 host_count,
+ char *hostname[],
+ afs_uint32 flags);
+
extern long cm_GetCellServDB(char *cellNamep, afs_uint32 len);
extern void cm_GetConfigDir(char *dir, afs_uint32 len);
#include <afs/param.h>
#include <afs/stds.h>
#include <afs/cellconfig.h>
+#include <afs/afs_consts.h>
#include <afs/ptserver.h>
#include <ubik.h>
}
/*
+ * VIOCNEWCELL2 internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ *
+ * The pioctl data buffer consists of the following structure:
+ *
+ * afs_uint32 flags
+ * afs_uint32 alternative fs port
+ * afs_uint32 alternative vl port
+ * afs_uint32 count of vldb servers
+ * char[] cellname
+ * char[] linkedcell
+ * n * char[] hostnames
+ */
+afs_int32
+cm_IoctlNewCell2(struct cm_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_uint32 code = 0;
+ afs_uint32 flags = 0;
+ afs_uint32 fsport = 0;
+ afs_uint32 vlport = 0;
+ afs_uint32 i, host_count = 0;
+ char * cellname = NULL;
+ char * linked_cellname = NULL;
+ char *tp;
+ size_t tplen;
+ afs_uint32 *lp;
+ char * hostname[AFS_MAXHOSTS];
+ size_t len;
+
+ memset(hostname, 0, sizeof(hostname));
+
+ tp = ioctlp->inDatap;
+ tplen = ioctlp->inCopied;
+ lp = (afs_uint32 *)tp;
+
+ if (tplen >= 4 * sizeof(afs_uint32)) {
+ flags = *lp++;
+ fsport = *lp++;
+ vlport = *lp++;
+ host_count = *lp++;
+ tp = (char *)lp;
+ tplen -= 4 * sizeof(afs_uint32);
+ }
+
+ if ( FAILED(StringCbLength(tp, tplen, &len)) ||
+ len + 1 > CELL_MAXNAMELEN)
+ return CM_ERROR_INVAL;
+ cellname = tp;
+ tp += len + 1;
+ tplen -= (len + 1);
+
+ if ( FAILED(StringCbLength(tp, tplen, &len)) ||
+ len + 1 > CELL_MAXNAMELEN)
+ return CM_ERROR_INVAL;
+ linked_cellname = tp;
+ tp += len + 1;
+ tplen -= (len + 1);
+
+ if (!(flags & VIOC_NEWCELL2_FLAG_USEDNS)) {
+ for ( i=0; i<host_count; i++) {
+ if ( FAILED(StringCbLength(tp, tplen, &len)) )
+ return CM_ERROR_INVAL;
+ hostname[i] = tp;
+ tp += len + 1;
+ tplen -= (len + 1);
+ }
+ }
+
+ code = cm_CreateCellWithInfo( cellname, linked_cellname,
+ vlport, host_count,
+ hostname,
+ (flags & VIOC_NEWCELL2_FLAG_USEDNS) ? CM_CELLFLAG_DNS : 0);
+
+ if (code == 0 && (flags & VIOC_NEWCELL2_FLAG_USEREG)) {
+ cm_AddCellToRegistry( cellname, linked_cellname,
+ vlport, host_count,
+ hostname,
+ (flags & VIOC_NEWCELL2_FLAG_USEDNS) ? CM_CELLFLAG_DNS : 0);
+ }
+ return code;
+}
+
+/*
* VIOC_GET_WS_CELL internals.
*
* Assumes that pioctl path has been parsed or skipped.
extern afs_int32 cm_IoctlNewCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlNewCell2(cm_ioctl_t *ioctlp, cm_user_t *userp);
+
extern afs_int32 cm_IoctlGetWsCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
extern afs_int32 cm_IoctlSysName(cm_ioctl_t *ioctlp, cm_user_t *userp);
static int
NewCellCmd(struct cmd_syndesc *as, void *arock)
{
-#ifndef WIN32
- afs_int32 code, linkedstate=0, size=0, *lp;
+ afs_uint32 code, linkedstate=0, size=0, count=0, *lp;
+ afs_uint32 usedns=0, useregistry=0;
struct ViceIoctl blob;
struct cmd_item *ti;
- char *destEnd, *tp, *cellname=0;
- struct hostent *thp;
- afs_int32 fsport = 0, vlport = 0;
- errno_t err;
+ char *tp, *cellname=0, *linked_cellname=0;
+ afs_uint32 fsport = 0, vlport = 0;
size_t destRemaining;
- memset(space, 0, AFS_MAXHOSTS * sizeof(afs_int32));
- tp = space;
- lp = (afs_int32 *)tp;
- *lp++ = 0x12345678;
- tp += sizeof(afs_int32);
- for(ti=as->parms[1].items; ti; ti=ti->next) {
- thp = hostutil_GetHostByName(ti->data);
- if (!thp) {
- fprintf(stderr,"%s: Host %s not found in host table, skipping it.\n",
- pn, ti->data);
- }
- else {
-#if _MSC_VER < 1400
- memcpy(tp, thp->h_addr, sizeof(afs_int32));
-#else
- err = memcpy_s(tp, sizeof(space) - (tp - space) * sizeof(char), thp->h_addr, sizeof(afs_int32));
- if ( err ) {
- fprintf (stderr, "memcpy_s failure on tp");
- exit(1);
- }
-#endif
- tp += sizeof(afs_int32);
- }
+ if ( !IsAdmin() ) {
+ fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n");
+ return EACCES;
}
+
+ /* if there is no cell specified, use old Windows behavior */
+ if (as->parms[0].items == NULL) {
+ blob.in_size = 0;
+ blob.in = (char *) 0;
+ blob.out_size = AFS_PIOCTL_MAXSIZE;
+ blob.out = space;
+
+ code = pioctl_utf8((char *) 0, VIOCNEWCELL, &blob, 1);
+
+ if (code) {
+ Die(errno, (char *) 0);
+ return 1;
+ }
+
+ printf("Cell servers information refreshed\n");
+ return 0;
+ } else {
+ cellname = as->parms[0].items->data;
+ }
+
if (as->parms[2].items) {
/*
* Link the cell, for the purposes of volume location, to the specified
* cell.
*/
- cellname = as->parms[2].items->data;
+ linked_cellname = as->parms[2].items->data;
linkedstate = 1;
}
-#ifdef FS_ENABLE_SERVER_DEBUG_PORTS
+
if (as->parms[3].items) {
- code = util_GetInt32(as->parms[3].items->data, &vlport);
+ code = util_GetInt32(as->parms[2].items->data, &vlport);
if (code) {
fprintf(stderr,"fs: bad integer specified for the fileserver port.\n");
return code;
}
}
if (as->parms[4].items) {
- code = util_GetInt32(as->parms[4].items->data, &fsport);
+ code = util_GetInt32(as->parms[3].items->data, &fsport);
if (code) {
fprintf(stderr,"fs: bad integer specified for the vldb server port.\n");
return code;
}
}
-#endif
- tp = (char *)(space + (AFS_MAXHOSTS+1) *sizeof(afs_int32));
- lp = (afs_int32 *)tp;
+
+ if (as->parms[5].items) {
+ useregistry = 1;
+ }
+
+ if (as->parms[6].items) {
+ usedns = 1;
+ }
+
+ /* Count the number of hostnames */
+ for (ti=as->parms[1].items; ti && count < AFS_MAXHOSTS; ti=ti->next, count++);
+
+ if (!usedns && count == 0) {
+ fprintf( stderr, "fs: at least one vldb server must be specified.");
+ exit(1);
+ }
+
+ if (count > AFS_MAXHOSTS) {
+ fprintf( stderr, "fs: at most %u servers may be specified.", AFS_MAXHOSTS);
+ exit(1);
+ }
+
+ /*
+ * The pioctl data buffer consists of the following structure:
+ *
+ * afs_uint32 flags
+ * afs_uint32 alternative fs port
+ * afs_uint32 alternative vl port
+ * afs_uint32 count of vldb servers
+ * char[] cellname
+ * char[] linkedcell
+ * n * char[] hostnames
+ */
+
+ memset(space, 0, sizeof(space));
+ tp = space;
+ lp = (afs_uint32 *)tp;
+
+ /* flags */
+ if (usedns)
+ *lp |= VIOC_NEWCELL2_FLAG_USEDNS;
+
+ if (useregistry)
+ *lp |= VIOC_NEWCELL2_FLAG_USEREG;
+
+ if (linkedstate)
+ *lp |= VIOC_NEWCELL2_FLAG_LINKED;
+ lp++;
+
+ /* alt fs port */
*lp++ = fsport;
+
+ /* alt vl port */
*lp++ = vlport;
- *lp = linkedstate;
- if( FAILED(StringCbCopyEx(space + ((AFS_MAXHOSTS+4) * sizeof(afs_int32)), sizeof(space) - (AFS_MAXHOSTS+4) * sizeof(afs_int32)
- , as->parms[0].items->data, &tp, &destRemaining, STRSAFE_FILL_ON_FAILURE))) {
- fprintf (stderr, "var - not enough space");
+
+ /* count of server names */
+ *lp++ = count;
+
+ /* Switch back to char pointer */
+ tp = (char *)lp;
+
+ /* Add nul-terminated cellname */
+ destRemaining = sizeof(space) - (tp - space);
+ if( FAILED(StringCbCopyEx( tp,
+ destRemaining,
+ as->parms[0].items->data,
+ &tp,
+ &destRemaining,
+ STRSAFE_FILL_ON_FAILURE))) {
+ fprintf (stderr, " not enough space for cellname");
+ exit(1);
+ }
+ /* Move beyond the terminating nul */
+ tp++;
+ destRemaining -= sizeof(char);
+
+ /* Add nul-terminated linkname */
+ if( FAILED(StringCbCopyEx( tp,
+ destRemaining,
+ linkedstate ? linked_cellname : "",
+ &tp,
+ &destRemaining,
+ STRSAFE_FILL_ON_FAILURE))) {
+ fprintf (stderr, " not enough space for linked cellname");
exit(1);
}
- tp++; /* for null */
+ /* Move beyond the terminating nul */
+ tp++;
destRemaining -= sizeof(char);
- if (linkedstate) {
- if( FAILED(StringCbCopyEx(tp, sizeof(space) - size, cellname, &destEnd, &destRemaining, STRSAFE_FILL_ON_FAILURE))) {
- fprintf (tp, "space arr - not enough space");
+
+ /* Add the servers */
+ for (ti=as->parms[1].items; ti; ti=ti->next) {
+ if( FAILED(StringCbCopyEx( tp,
+ destRemaining,
+ ti->data,
+ &tp,
+ &destRemaining,
+ STRSAFE_FILL_ON_FAILURE))) {
+ fprintf (stderr, " not enough space for server %s", ti->data);
exit(1);
- }
- size += destEnd - tp + 1;
+ }
+ /* Move beyond the terminating nul */
+ tp++;
+ destRemaining -= sizeof(char);
}
- blob.in_size = size;
+
+ blob.in_size = (tp - space);
blob.in = space;
blob.out_size = 0;
- code = pioctl_utf8(0, VIOCNEWCELL, &blob, 1);
- if (code < 0)
- Die(errno, 0);
- return 0;
-#else /* WIN32 */
- afs_int32 code;
- struct ViceIoctl blob;
-
- if ( !IsAdmin() ) {
- fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n");
- return EACCES;
- }
-
- blob.in_size = 0;
- blob.in = (char *) 0;
- blob.out_size = AFS_PIOCTL_MAXSIZE;
blob.out = space;
-
- code = pioctl_utf8((char *) 0, VIOCNEWCELL, &blob, 1);
+ code = pioctl_utf8(NULL, VIOCNEWCELL2, &blob, 1);
if (code) {
- Die(errno, (char *) 0);
+ Die(errno, as->parms[0].items->data);
return 1;
}
- printf("Cell servers information refreshed\n");
+ printf("Cell servers information for %s added or updated.\n",
+ as->parms[0].items->data);
return 0;
-#endif /* WIN32 */
}
#ifndef WIN32
cmd_CreateAlias(ts, "sq");
ts = cmd_CreateSyntax("newcell", NewCellCmd, NULL, "configure new cell");
-#ifndef WIN32
- cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "cell name");
- cmd_AddParm(ts, "-servers", CMD_LIST, CMD_REQUIRED, "primary servers");
+ cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "cell name");
+ cmd_AddParm(ts, "-servers", CMD_LIST, CMD_OPTIONAL, "primary servers");
cmd_AddParm(ts, "-linkedcell", CMD_SINGLE, CMD_OPTIONAL, "linked cell name");
-#ifdef FS_ENABLE_SERVER_DEBUG_PORTS
/*
* Turn this on only if you wish to be able to talk to a server which is listening
* on alternative ports. This is not intended for general use and may not be
*/
cmd_AddParm(ts, "-fsport", CMD_SINGLE, CMD_OPTIONAL, "cell's fileserver port");
cmd_AddParm(ts, "-vlport", CMD_SINGLE, CMD_OPTIONAL, "cell's vldb server port");
-#endif
+ cmd_AddParm(ts, "-registry", CMD_FLAG, CMD_OPTIONAL, "add cell info to registry cellservdb");
+ cmd_AddParm(ts, "-dns", CMD_FLAG, CMD_OPTIONAL, "force use of dns");
+#ifndef WIN32
ts = cmd_CreateSyntax("newalias", NewAliasCmd, NULL,
"configure new cell alias");
cmd_AddParm(ts, "-alias", CMD_SINGLE, 0, "alias name");
#define VIOC_SETOWNER 0x34
#define VIOC_SETGROUP 0x35
#define VIOC_FS_CMD 0x36
+#define VIOCNEWCELL2 0x37
#define VIOC_VOLSTAT_TEST 0x3F
+#define VIOC_NEWCELL2_FLAG_LINKED 0x1
+#define VIOC_NEWCELL2_FLAG_USEDNS 0x2
+#define VIOC_NEWCELL2_FLAG_USEREG 0x4
+
/* magic file name for ioctl opens */
#define CM_IOCTL_FILENAME "\\_._AFS_IOCTL_._" /* double backslashes for C compiler */
#define CM_IOCTL_FILENAME_NOSLASH "_._AFS_IOCTL_._"
smb_ioctlProcsp[VIOC_UNICODECTL] = smb_IoctlUnicodeControl;
smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner;
smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup;
+ smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2;
}
/* called to make a fid structure into an IOCTL fid structure */
}
afs_int32
+smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlNewCell2(&ioctlp->ioctl, userp);
+}
+
+afs_int32
smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
{
cm_SkipIoctlPath(&ioctlp->ioctl);
extern afs_int32 smb_IoctlNewCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 smb_IoctlNewCell2(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
extern afs_int32 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
extern afs_int32 smb_IoctlSysName(smb_ioctl_t *ioctlp, cm_user_t *userp);