#define PIOCTL_LOGON 0x1
#define MAX_PATH 260
-static const char utf8_prefix[] = UTF8_PREFIX;
-static const int utf8_prefix_size = sizeof(utf8_prefix) - sizeof(char);
+const char utf8_prefix[] = UTF8_PREFIX;
+const int utf8_prefix_size = sizeof(utf8_prefix) - sizeof(char);
osi_mutex_t cm_Afsdsbmt_Lock;
lock_InitializeMutex(&cm_Afsdsbmt_Lock, "AFSDSBMT.INI Access Lock");
}
-long cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
+/*
+ * Utility function. (Not currently in use.)
+ * This function forces all dirty buffers to the file server and
+ * then discards the status info.
+ */
+afs_int32
+cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
{
long code;
code = buf_CleanVnode(scp, userp, reqp);
-
- lock_ObtainWrite(&scp->rw);
- cm_DiscardSCache(scp);
- lock_ReleaseWrite(&scp->rw);
-
+ if (!code) {
+ lock_ObtainWrite(&scp->rw);
+ cm_DiscardSCache(scp);
+ lock_ReleaseWrite(&scp->rw);
+ }
osi_Log2(afsd_logp,"cm_CleanFile scp 0x%x returns error: [%x]",scp, code);
return code;
}
-long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
+/*
+ * Utility function. Used within this file.
+ * scp must be held but not locked.
+ */
+afs_int32
+cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
{
- long code;
+ afs_int32 code;
#ifdef AFS_FREELANCE_CLIENT
if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) {
lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
-
lock_ReleaseWrite(&scp->rw);
osi_Log2(afsd_logp,"cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
return code;
}
-long cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
+/*
+ * Utility function. (Not currently in use)
+ * IoctlPath must be parsed or skipped prior to calling.
+ * scp must be held but not locked.
+ */
+afs_int32
+cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
{
- long code = 0;
+ afs_int32 code = 0;
cm_scache_t * pscp;
pscp = cm_FindSCacheParent(scp);
return code;
}
-
-long cm_FlushVolume(cm_user_t *userp, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume)
+/*
+ * Utility function. Used within this function.
+ */
+afs_int32
+cm_FlushVolume(cm_user_t *userp, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume)
{
- long code = 0;
+ afs_int32 code = 0;
cm_scache_t *scp;
int i;
}
/*
- * cm_ResetACLCache -- invalidate ACL info for a user that has just
- * obtained or lost tokens
+ * Utility function. Used within this file.
+ * Invalidate ACL info for a user that has just obtained or lost tokens.
*/
-void cm_ResetACLCache(cm_user_t *userp)
+void
+cm_ResetACLCache(cm_user_t *userp)
{
cm_scache_t *scp;
int hash;
*
* If an extended character (80 - FF) is entered into a file
* or directory name in Windows, the character is translated
- * into the OEM character map before being passed to us. Why
- * this occurs is unknown. Our pioctl functions must match
+ * into the OEM character map before being passed to us.
+ * The pioctl functions must match
* this translation for paths given via our own commands (like
* fs). If we do not do this, then we will try to perform an
* operation on a non-translated path, which we will fail to
* find, since the path was created with the translated chars.
* This function performs the required translation.
+ *
+ * OEM character code pages are used by the non-Unicode SMB
+ * mode. Do not use if the CM_IOCTLFLAG_USEUTF8 is set.
*/
-void TranslateExtendedChars(char *str)
+void
+TranslateExtendedChars(char *str)
{
if (!str || !*str)
return;
CharToOem(str, str);
}
-
-/* parse the passed-in file name and do a namei on it. If we fail,
- * return an error code, otherwise return the vnode located in *scpp.
- */
-#define CM_PARSE_FLAG_LITERAL 1
-
-long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
- cm_scache_t **scpp, afs_uint32 flags)
-{
- long code;
- cm_scache_t *substRootp = NULL;
- cm_scache_t *iscp = NULL;
- char * relativePath;
- char * lastComponent = NULL;
- afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
- int free_path = FALSE;
-
- relativePath = ioctlp->inDatap;
- /* setup the next data value for the caller to use */
- ioctlp->inDatap += (long)strlen(ioctlp->inDatap) + 1;;
-
- osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,relativePath));
-
- /* This is usually the file name, but for StatMountPoint it is the path. */
- /* ioctlp->inDatap can be either of the form:
- * \path\.
- * \path\file
- * \\netbios-name\submount\path\.
- * \\netbios-name\submount\path\file
- */
-
- /* We do not perform path name translation on the ioctl path data
- * because these paths were not translated by Windows through the
- * file system API. Therefore, they are not OEM characters but
- * whatever the display character set is.
- */
-
- // TranslateExtendedChars(relativePath);
-
- /* This is usually nothing, but for StatMountPoint it is the file name. */
- // TranslateExtendedChars(ioctlp->inDatap);
-
- /* If the string starts with our UTF-8 prefix (which is the
- sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
- strings), we assume that the provided path is UTF-8. Otherwise
- we have to convert the string to UTF-8, since that is what we
- want to use everywhere else.*/
-
- if (memcmp(relativePath, utf8_prefix, utf8_prefix_size) == 0) {
- int len, normalized_len;
- char * normalized_path;
-
- /* String is UTF-8 */
- relativePath += utf8_prefix_size;
- ioctlp->flags |= SMB_IOCTLFLAG_USEUTF8;
-
- len = (ioctlp->inDatap - relativePath);
-
- normalized_len = cm_NormalizeUtf8String(relativePath, len, NULL, 0);
-
- if (normalized_len > len) {
- normalized_path = malloc(normalized_len);
- free_path = TRUE;
- } else {
- normalized_path = relativePath;
- }
-
- cm_NormalizeUtf8String(relativePath, len, normalized_path, normalized_len);
-
- if (normalized_path != relativePath)
- relativePath = normalized_path;
- } else {
- /* Not a UTF-8 string */
- /* TODO: If this is an OEM string, we should convert it to
- UTF-8. */
- }
-
- if (relativePath[0] == relativePath[1] &&
- relativePath[1] == '\\' &&
- !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName)))
- {
- char shareName[256];
- char *sharePath;
- int shareFound, i;
-
- /* We may have found a UNC path.
- * If the first component is the NetbiosName,
- * then throw out the second component (the submount)
- * since it had better expand into the value of ioctl->tidPathp
- */
- char * p;
- p = relativePath + 2 + strlen(cm_NetbiosName) + 1; /* buffer overflow vuln.? */
- if ( !_strnicmp("all", p, 3) )
- p += 4;
- for (i = 0; *p && *p != '\\'; i++,p++ ) {
- shareName[i] = *p;
- }
- p++; /* skip past trailing slash */
- shareName[i] = 0; /* terminate string */
-
- shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
- if ( shareFound ) {
- /* we found a sharename, therefore use the resulting path */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
- CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, sharePath, reqp, &substRootp);
- free(sharePath);
- if (code) {
- osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code);
- if (free_path)
- free(relativePath);
- return code;
- }
-
- lastComponent = strrchr(p, '\\');
- if (lastComponent && (lastComponent - p) > 1 &&strlen(lastComponent) > 1) {
- *lastComponent = '\0';
- lastComponent++;
-
- code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, NULL, reqp, &iscp);
- if (code == 0)
- code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
- userp, NULL, reqp, scpp);
- if (iscp)
- cm_ReleaseSCache(iscp);
- } else {
- code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
- userp, NULL, reqp, scpp);
- }
- cm_ReleaseSCache(substRootp);
- if (code) {
- osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code);
- if (free_path)
- free(relativePath);
- return code;
- }
- } else {
- /* otherwise, treat the name as a cellname mounted off the afs root.
- * This requires that we reconstruct the shareName string with
- * leading and trailing slashes.
- */
- p = relativePath + 2 + strlen(cm_NetbiosName) + 1;
- if ( !_strnicmp("all", p, 3) )
- p += 4;
-
- shareName[0] = '/';
- for (i = 1; *p && *p != '\\'; i++,p++ ) {
- shareName[i] = *p;
- }
- p++; /* skip past trailing slash */
- shareName[i++] = '/'; /* add trailing slash */
- shareName[i] = 0; /* terminate string */
-
-
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
- CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, shareName, reqp, &substRootp);
- if (code) {
- osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code);
- if (free_path)
- free(relativePath);
- return code;
- }
-
- lastComponent = strrchr(p, '\\');
- if (lastComponent && (lastComponent - p) > 1 &&strlen(lastComponent) > 1) {
- *lastComponent = '\0';
- lastComponent++;
-
- code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, NULL, reqp, &iscp);
- if (code == 0)
- code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
- userp, NULL, reqp, scpp);
- if (iscp)
- cm_ReleaseSCache(iscp);
- } else {
- code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
- userp, NULL, reqp, scpp);
- }
-
- if (code) {
- cm_ReleaseSCache(substRootp);
- osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code);
- if (free_path)
- free(relativePath);
- return code;
- }
- }
- } else {
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
- CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, ioctlp->tidPathp, reqp, &substRootp);
- if (code) {
- osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code);
- if (free_path)
- free(relativePath);
- return code;
- }
-
- lastComponent = strrchr(relativePath, '\\');
- if (lastComponent && (lastComponent - relativePath) > 1 && strlen(lastComponent) > 1) {
- *lastComponent = '\0';
- lastComponent++;
-
- code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, NULL, reqp, &iscp);
- if (code == 0)
- code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
- userp, NULL, reqp, scpp);
- if (iscp)
- cm_ReleaseSCache(iscp);
- } else {
- code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | follow,
- userp, NULL, reqp, scpp);
- }
- if (code) {
- cm_ReleaseSCache(substRootp);
- osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code);
- if (free_path)
- free(relativePath);
- return code;
- }
- }
- if (substRootp)
- cm_ReleaseSCache(substRootp);
-
- /* and return success */
- osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
-
- if (free_path)
- free(relativePath);
- return 0;
-}
-
-void cm_SkipIoctlPath(smb_ioctl_t *ioctlp)
+/*
+ * Utility function.
+ * If the IoctlPath is not parsed then it must be skipped.
+ */
+void
+cm_SkipIoctlPath(cm_ioctl_t *ioctlp)
{
size_t temp;
}
/*
- * Must be called before cm_ParseIoctlPath or cm_SkipIoctlPath
+ * Must be called before XXX_ParseIoctlPath or cm_SkipIoctlPath
*/
-static cm_ioctlQueryOptions_t *
-cm_IoctlGetQueryOptions(struct smb_ioctl *ioctlp, struct cm_user *userp)
+cm_ioctlQueryOptions_t *
+cm_IoctlGetQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
afs_uint32 pathlen = strlen(ioctlp->inDatap) + 1;
char *p = ioctlp->inDatap + pathlen;
}
/*
- * Must be called after cm_ParseIoctlPath or cm_SkipIoctlPath
+ * Must be called after smb_ParseIoctlPath or cm_SkipIoctlPath
* or any other time that ioctlp->inDatap points at the
* cm_ioctlQueryOptions_t object.
*/
-static void
-cm_IoctlSkipQueryOptions(struct smb_ioctl *ioctlp, struct cm_user *userp)
+void
+cm_IoctlSkipQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
cm_ioctlQueryOptions_t * optionsp = (cm_ioctlQueryOptions_t *)ioctlp->inDatap;
ioctlp->inDatap += optionsp->size;
* easier (because we can always jump past the initial "/afs" to find
* the AFS path that should be written into afsdsbmt.ini).
*/
-void cm_NormalizeAfsPath(char *outpathp, long outlen, char *inpathp)
+void
+cm_NormalizeAfsPath(char *outpathp, long outlen, char *inpathp)
{
char *cp;
char bslash_mountRoot[256];
}
}
-#define LEAF_SIZE 256
-/* parse the passed-in file name and do a namei on its parent. If we fail,
- * return an error code, otherwise return the vnode located in *scpp.
- */
-long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
- cm_scache_t **scpp, char *leafp)
-{
- long code;
- char tbuffer[1024];
- char *tp, *jp;
- cm_scache_t *substRootp = NULL;
- char *inpathp;
- int free_path = FALSE;
-
- inpathp = ioctlp->inDatap;
-
- /* If the string starts with our UTF-8 prefix (which is the
- sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
- strings), we assume that the provided path is UTF-8. Otherwise
- we have to convert the string to UTF-8, since that is what we
- want to use everywhere else.*/
-
- if (memcmp(inpathp, utf8_prefix, utf8_prefix_size) == 0) {
- int len, normalized_len;
- char * normalized_path;
-
- /* String is UTF-8 */
- inpathp += utf8_prefix_size;
- ioctlp->flags |= SMB_IOCTLFLAG_USEUTF8;
-
- len = strlen(inpathp) + 1;
-
- normalized_len = cm_NormalizeUtf8String(inpathp, len, NULL, 0);
-
- if (normalized_len > len) {
- normalized_path = malloc(normalized_len);
- free_path = TRUE;
- } else {
- normalized_path = inpathp;
- }
- cm_NormalizeUtf8String(inpathp, len, normalized_path, normalized_len);
-
- if (normalized_path != inpathp)
- inpathp = normalized_path;
- } else {
- /* Not a UTF-8 string */
- /* TODO: If this is an OEM string, we should convert it to
- UTF-8. */
- }
-
- StringCbCopyA(tbuffer, sizeof(tbuffer), inpathp);
- tp = strrchr(tbuffer, '\\');
- jp = strrchr(tbuffer, '/');
- if (!tp)
- tp = jp;
- else if (jp && (tp - tbuffer) < (jp - tbuffer))
- tp = jp;
- if (!tp) {
- StringCbCopyA(tbuffer, sizeof(tbuffer), "\\");
- if (leafp)
- StringCbCopyA(leafp, LEAF_SIZE, inpathp);
- }
- else {
- *tp = 0;
- if (leafp)
- StringCbCopyA(leafp, LEAF_SIZE, tp+1);
- }
-
- if (free_path)
- free(inpathp);
- inpathp = NULL; /* We don't need this from this point on */
-
- if (free_path)
- free(inpathp);
- inpathp = NULL; /* We don't need this from this point on */
-
- if (tbuffer[0] == tbuffer[1] &&
- tbuffer[1] == '\\' &&
- !_strnicmp(cm_NetbiosName,tbuffer+2,strlen(cm_NetbiosName)))
- {
- char shareName[256];
- char *sharePath;
- int shareFound, i;
-
- /* We may have found a UNC path.
- * If the first component is the NetbiosName,
- * then throw out the second component (the submount)
- * since it had better expand into the value of ioctl->tidPathp
- */
- char * p;
- p = tbuffer + 2 + strlen(cm_NetbiosName) + 1;
- if ( !_strnicmp("all", p, 3) )
- p += 4;
-
- for (i = 0; *p && *p != '\\'; i++,p++ ) {
- shareName[i] = *p;
- }
- p++; /* skip past trailing slash */
- shareName[i] = 0; /* terminate string */
-
- shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
- if ( shareFound ) {
- /* we found a sharename, therefore use the resulting path */
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
- CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, sharePath, reqp, &substRootp);
- free(sharePath);
- if (code) return code;
-
- code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, NULL, reqp, scpp);
- cm_ReleaseSCache(substRootp);
- if (code) return code;
- } else {
- /* otherwise, treat the name as a cellname mounted off the afs root.
- * This requires that we reconstruct the shareName string with
- * leading and trailing slashes.
- */
- p = tbuffer + 2 + strlen(cm_NetbiosName) + 1;
- if ( !_strnicmp("all", p, 3) )
- p += 4;
-
- shareName[0] = '/';
- for (i = 1; *p && *p != '\\'; i++,p++ ) {
- shareName[i] = *p;
- }
- p++; /* skip past trailing slash */
- shareName[i++] = '/'; /* add trailing slash */
- shareName[i] = 0; /* terminate string */
-
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
- CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, shareName, reqp, &substRootp);
- if (code) return code;
-
- code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, NULL, reqp, scpp);
- cm_ReleaseSCache(substRootp);
- if (code) return code;
- }
- } else {
- code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
- CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, ioctlp->tidPathp, reqp, &substRootp);
- if (code) return code;
-
- code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
- userp, NULL, reqp, scpp);
- cm_ReleaseSCache(substRootp);
- if (code) return code;
- }
-
- /* # of bytes of path */
- code = (long)strlen(ioctlp->inDatap) + 1;
- ioctlp->inDatap += code;
-
- /* and return success */
- return 0;
-}
-
-long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
+/*
+ * VIOCGETAL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlGetACL(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp)
{
+ afs_int32 code;
cm_conn_t *connp;
- cm_scache_t *scp;
AFSOpaque acl;
AFSFetchStatus fileStatus;
AFSVolSync volSync;
- long code;
AFSFid afid;
int tlen;
- cm_req_t req;
struct rx_connection * callp;
- cm_ioctlQueryOptions_t *optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
-
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- }
- if (code)
- return code;
/* now make the get acl call */
#ifdef AFS_FREELANCE_CLIENT
do {
acl.AFSOpaque_val = ioctlp->outDatap;
acl.AFSOpaque_len = 0;
- code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
- if (code) continue;
+ code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp);
+ if (code)
+ continue;
callp = cm_GetRxConn(connp);
code = RXAFS_FetchACL(callp, &afid, &acl, &fileStatus, &volSync);
rx_PutConnection(callp);
- } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code));
- code = cm_MapRPCError(code, &req);
- cm_ReleaseSCache(scp);
+ } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code));
+ code = cm_MapRPCError(code, reqp);
- if (code) return code;
+ if (code)
+ return code;
}
/* skip over return data */
tlen = (int)strlen(ioctlp->outDatap) + 1;
return 0;
}
-long cm_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
+
+/*
+ * VIOC_FILE_CELL_NAME internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlGetFileCellName(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *scp;
+ afs_int32 code;
cm_cell_t *cellp;
- cm_req_t req;
- cm_ioctlQueryOptions_t *optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
-
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- }
- if (code)
- return code;
#ifdef AFS_FREELANCE_CLIENT
if ( cm_freelanceEnabled &&
code = CM_ERROR_NOSUCHCELL;
}
- cm_ReleaseSCache(scp);
return code;
}
-long cm_IoctlSetACL(struct smb_ioctl *ioctlp, struct cm_user *userp)
+
+/*
+ * VIOCSETAL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlSetACL(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
+ afs_int32 code;
cm_conn_t *connp;
- cm_scache_t *scp;
AFSOpaque acl;
AFSFetchStatus fileStatus;
AFSVolSync volSync;
- long code;
AFSFid fid;
- cm_req_t req;
struct rx_connection * callp;
- cm_InitReq(&req);
-
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, 0);
- if (code) return code;
-
#ifdef AFS_FREELANCE_CLIENT
if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) {
code = CM_ERROR_NOACCESS;
do {
acl.AFSOpaque_val = ioctlp->inDatap;
acl.AFSOpaque_len = (u_int)strlen(ioctlp->inDatap)+1;
- code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
- if (code) continue;
+ code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp);
+ if (code)
+ continue;
callp = cm_GetRxConn(connp);
code = RXAFS_StoreACL(callp, &fid, &acl, &fileStatus, &volSync);
rx_PutConnection(callp);
- } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code));
- code = cm_MapRPCError(code, &req);
+ } while (cm_Analyze(connp, userp, reqp, &scp->fid, &volSync, NULL, NULL, code));
+ code = cm_MapRPCError(code, reqp);
/* invalidate cache info, since we just trashed the ACL cache */
lock_ObtainWrite(&scp->rw);
cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw);
}
- cm_ReleaseSCache(scp);
return code;
}
-
-
-long cm_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_FLUSHALL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlFlushAllVolumes(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
- long code;
+ afs_int32 code;
cm_scache_t *scp;
int i;
cm_req_t req;
cm_InitReq(&req);
- cm_SkipIoctlPath(ioctlp); /* we don't care about the path */
-
lock_ObtainWrite(&cm_scacheLock);
for (i=0; i<cm_data.scacheHashTableSize; i++) {
for (scp = cm_data.scacheHashTablep[i]; scp; scp = scp->nextp) {
return code;
}
-long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_FLUSHVOLUME internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlFlushVolume(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *scp;
- unsigned long volume;
- unsigned long cell;
- cm_req_t req;
- cm_ioctlQueryOptions_t *optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
-
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- }
- if (code)
- return code;
+ afs_int32 code;
+ afs_uint32 volume;
+ afs_uint32 cell;
#ifdef AFS_FREELANCE_CLIENT
if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) {
{
volume = scp->fid.volume;
cell = scp->fid.cell;
- cm_ReleaseSCache(scp);
-
- code = cm_FlushVolume(userp, &req, cell, volume);
+ code = cm_FlushVolume(userp, reqp, cell, volume);
}
return code;
}
-long cm_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCFLUSH internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlFlushFile(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *scp;
- cm_req_t req;
- cm_ioctlQueryOptions_t *optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
-
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- }
- if (code)
- return code;
+ afs_int32 code;
#ifdef AFS_FREELANCE_CLIENT
if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) {
} else
#endif
{
- cm_FlushFile(scp, userp, &req);
+ cm_FlushFile(scp, userp, reqp);
}
- cm_ReleaseSCache(scp);
-
return 0;
}
-long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+
+/*
+ * VIOCSETVOLSTAT internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlSetVolumeStatus(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- cm_scache_t *scp;
+ afs_int32 code;
char volName[32];
char offLineMsg[256];
char motd[256];
cm_conn_t *tcp;
- long code;
AFSFetchVolumeStatus volStat;
AFSStoreVolumeStatus storeStat;
cm_volume_t *tvp;
char *cp;
cm_cell_t *cellp;
- cm_req_t req;
struct rx_connection * callp;
int len;
- cm_InitReq(&req);
-
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, 0);
- if (code) return code;
-
#ifdef AFS_FREELANCE_CLIENT
if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) {
code = CM_ERROR_NOACCESS;
cellp = cm_FindCellByID(scp->fid.cell, 0);
osi_assertx(cellp, "null cm_cell_t");
- if (scp->flags & CM_SCACHEFLAG_RO) {
- cm_ReleaseSCache(scp);
+ if (scp->flags & CM_SCACHEFLAG_RO)
return CM_ERROR_READONLY;
- }
- code = cm_FindVolumeByID(cellp, scp->fid.volume, userp, &req,
+ code = cm_FindVolumeByID(cellp, scp->fid.volume, userp, reqp,
CM_GETVOL_FLAG_CREATE, &tvp);
- if (code) {
- cm_ReleaseSCache(scp);
+ if (code)
return code;
- }
+
cm_PutVolume(tvp);
/* Copy the junk out, using cp as a roving pointer. */
}
do {
- code = cm_ConnFromFID(&scp->fid, userp, &req, &tcp);
- if (code) continue;
+ code = cm_ConnFromFID(&scp->fid, userp, reqp, &tcp);
+ if (code)
+ continue;
callp = cm_GetRxConn(tcp);
code = RXAFS_SetVolumeStatus(callp, scp->fid.volume,
&storeStat, volName, offLineMsg, motd);
rx_PutConnection(callp);
- } while (cm_Analyze(tcp, userp, &req, &scp->fid, NULL, NULL, NULL, code));
- code = cm_MapRPCError(code, &req);
+ } while (cm_Analyze(tcp, userp, reqp, &scp->fid, NULL, NULL, NULL, code));
+ code = cm_MapRPCError(code, reqp);
}
/* return on failure */
- cm_ReleaseSCache(scp);
- if (code) {
+ if (code)
return code;
- }
/* we are sending parms back to make compat. with prev system. should
* change interface later to not ask for current status, just set
return 0;
}
-long cm_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+
+/*
+ * VIOCGETVOLSTAT internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlGetVolumeStatus(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- char volName[32];
- cm_scache_t *scp;
- char offLineMsg[256];
- char motd[256];
+ afs_int32 code;
+ char volName[32]="(unknown)";
+ char offLineMsg[256]="server temporarily inaccessible";
+ char motd[256]="server temporarily inaccessible";
cm_conn_t *connp;
- register long code;
AFSFetchVolumeStatus volStat;
- register char *cp;
+ char *cp;
char *Name;
char *OfflineMsg;
char *MOTD;
- cm_req_t req;
struct rx_connection * callp;
- cm_ioctlQueryOptions_t *optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
-
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- }
- if (code)
- return code;
#ifdef AFS_FREELANCE_CLIENT
if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) {
OfflineMsg = offLineMsg;
MOTD = motd;
do {
- code = cm_ConnFromFID(&scp->fid, userp, &req, &connp);
+ code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp);
if (code) continue;
callp = cm_GetRxConn(connp);
&volStat, &Name, &OfflineMsg, &MOTD);
rx_PutConnection(callp);
- } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, NULL, NULL, code));
- code = cm_MapRPCError(code, &req);
+ } while (cm_Analyze(connp, userp, reqp, &scp->fid, NULL, NULL, NULL, code));
+ code = cm_MapRPCError(code, reqp);
}
- cm_ReleaseSCache(scp);
- if (code) return code;
+ if (code)
+ return code;
/* Copy all this junk into msg->im_data, keeping track of the lengths. */
cp = ioctlp->outDatap;
return 0;
}
-long cm_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCGETFID internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlGetFid(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- cm_scache_t *scp;
- register long code;
- register char *cp;
+ char *cp;
cm_fid_t fid;
- cm_req_t req;
- cm_ioctlQueryOptions_t * optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
-
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- if (code) return code;
memset(&fid, 0, sizeof(cm_fid_t));
fid.cell = scp->fid.cell;
fid.vnode = scp->fid.vnode;
fid.unique = scp->fid.unique;
- cm_ReleaseSCache(scp);
-
/* Copy all this junk into msg->im_data, keeping track of the lengths. */
cp = ioctlp->outDatap;
memcpy(cp, (char *)&fid, sizeof(cm_fid_t));
return 0;
}
-long cm_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_GETFILETYPE internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlGetFileType(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- cm_scache_t *scp;
- register long code;
- register char *cp;
+ afs_int32 code = 0;
+ char *cp;
afs_uint32 fileType = 0;
- cm_req_t req;
- cm_ioctlQueryOptions_t * optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ if (scp->fileType == 0) {
+ lock_ObtainWrite(&scp->rw);
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code == 0)
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ReleaseWrite(&scp->rw);
}
- if (code)
- return code;
-
- fileType = scp->fileType;
- cm_ReleaseSCache(scp);
- /* Copy all this junk into msg->im_data, keeping track of the lengths. */
- cp = ioctlp->outDatap;
- memcpy(cp, (char *)&fileType, sizeof(fileType));
- cp += sizeof(fileType);
+ if (code == 0) {
+ fileType = scp->fileType;
- /* return new size */
- ioctlp->outDatap = cp;
+ /* Copy all this junk into msg->im_data, keeping track of the lengths. */
+ cp = ioctlp->outDatap;
+ memcpy(cp, (char *)&fileType, sizeof(fileType));
+ cp += sizeof(fileType);
- return 0;
+ /* return new size */
+ ioctlp->outDatap = cp;
+ }
+ return code;
}
-long cm_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCGETOWNER internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlGetOwner(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- cm_scache_t *scp;
- register long code;
- register char *cp;
- cm_req_t req;
- cm_ioctlQueryOptions_t *optionsp;
- afs_uint32 flags = 0;
+ afs_int32 code = 0;
+ char *cp;
- cm_InitReq(&req);
+ lock_ObtainWrite(&scp->rw);
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code == 0)
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ lock_ReleaseWrite(&scp->rw);
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+ if (code == 0) {
+ /* Copy all this junk into msg->im_data, keeping track of the lengths. */
+ cp = ioctlp->outDatap;
+ memcpy(cp, (char *)&scp->owner, sizeof(afs_uint32));
+ cp += sizeof(afs_uint32);
+ memcpy(cp, (char *)&scp->group, sizeof(afs_uint32));
+ cp += sizeof(afs_uint32);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ /* return new size */
+ ioctlp->outDatap = cp;
}
- if (code)
- return code;
-
- /* Copy all this junk into msg->im_data, keeping track of the lengths. */
- cp = ioctlp->outDatap;
- memcpy(cp, (char *)&scp->owner, sizeof(afs_uint32));
- cp += sizeof(afs_uint32);
- memcpy(cp, (char *)&scp->group, sizeof(afs_uint32));
- cp += sizeof(afs_uint32);
-
- /* return new size */
- ioctlp->outDatap = cp;
-
- cm_ReleaseSCache(scp);
-
- return 0;
+ return code;
}
-long cm_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+
+/*
+ * VIOCWHEREIS internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlWhereIs(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *scp;
+ afs_int32 code;
cm_cell_t *cellp;
cm_volume_t *tvp;
cm_serverRef_t **tsrpp, *current;
cm_server_t *tsp;
- unsigned long volume;
+ afs_uint32 volume;
char *cp;
- cm_req_t req;
- cm_ioctlQueryOptions_t *optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
-
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- }
- if (code)
- return code;
volume = scp->fid.volume;
cellp = cm_FindCellByID(scp->fid.cell, 0);
- cm_ReleaseSCache(scp);
-
if (!cellp)
return CM_ERROR_NOSUCHCELL;
} else
#endif
{
- code = cm_FindVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp);
+ code = cm_FindVolumeByID(cellp, volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &tvp);
if (code)
return code;
return 0;
}
-long cm_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_AFS_STAT_MT_PT internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlStatMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *dscp;
+ afs_int32 code;
cm_scache_t *scp;
char *cp;
- cm_req_t req;
-
- cm_InitReq(&req);
-
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
- if (code) return code;
cp = ioctlp->inDatap;
- code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
- cm_ReleaseSCache(dscp);
- if (code) return code;
-
+ code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp);
+ if (code)
+ return code;
+
lock_ObtainWrite(&scp->rw);
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
+ CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ if (code == 0)
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+ else
+ goto done;
/* now check that this is a real mount point */
if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) {
- lock_ReleaseWrite(&scp->rw);
- cm_ReleaseSCache(scp);
- return CM_ERROR_INVAL;
+ code = CM_ERROR_INVAL;
+ goto done;
}
- code = cm_ReadMountPoint(scp, userp, &req);
+ code = cm_ReadMountPoint(scp, userp, reqp);
if (code == 0) {
cp = ioctlp->outDatap;
StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), scp->mountPointStringp);
cp += strlen(cp) + 1;
ioctlp->outDatap = cp;
}
+
+ done:
lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
return code;
}
-long cm_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_AFS_DELETE_MT_PT internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlDeleteMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *dscp;
+ afs_int32 code;
cm_scache_t *scp;
char *cp;
char *originalName = NULL;
- cm_req_t req;
cm_dirOp_t dirop;
- cm_InitReq(&req);
-
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
- if (code) return code;
-
cp = ioctlp->inDatap;
- code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
+ code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp);
/* if something went wrong, bail out now */
if (code)
goto done3;
lock_ObtainWrite(&scp->rw);
- code = cm_SyncOp(scp, NULL, userp, &req, 0,
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
goto done2;
lock_ReleaseWrite(&scp->rw);
#ifdef USE_BPLUS
- code = cm_BeginDirOp(dscp, userp, &req, CM_DIRLOCK_READ, &dirop);
+ code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ, &dirop);
if (code == 0) {
code = cm_BPlusDirLookupOriginalName(&dirop, cp, &originalName);
/* The cm_Dir* functions can't be used to lookup the
#endif
{
/* easier to do it this way */
- code = cm_Unlink(dscp, originalName, cp, userp, &req);
+ code = cm_Unlink(dscp, originalName, cp, userp, reqp);
}
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
smb_NotifyChange(FILE_ACTION_REMOVED,
cm_ReleaseSCache(scp);
done3:
- cm_ReleaseSCache(dscp);
return code;
}
-long cm_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCCKSERV internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlCheckServers(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
cm_cell_t *cellp;
chservinfo_t csi;
cm_server_t *tsp;
int haveCell;
- cm_SkipIoctlPath(ioctlp); /* we don't care about the path */
tp = ioctlp->inDatap;
haveCell = 0;
else cellp = (cm_cell_t *) 0;
if (!cellp && (temp & 2)) {
/* use local cell */
- cellp = cm_FindCellByID(1, 0);
+ char wscell[CELL_MAXNAMELEN+1];
+ cm_GetRootCellName(wscell);
+ cellp = cm_GetCell(wscell, 0);
}
if (!(temp & 1)) { /* if not fast, call server checker routine */
/* check down servers */
cp = ioctlp->outDatap;
lock_ObtainRead(&cm_serverLock);
for (tsp = cm_allServersp; tsp; tsp=tsp->allNextp) {
- if (cellp && tsp->cellp != cellp) continue; /* cell spec'd and wrong */
+ if (cellp && tsp->cellp != cellp)
+ continue; /* cell spec'd and wrong */
if ((tsp->flags & CM_SERVERFLAG_DOWN)
&& tsp->type == CM_SERVER_FILE) {
memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long));
return 0;
}
-long cm_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp)
-{
- /* we don't print anything superfluous, so we don't support the gag call */
- return CM_ERROR_INVAL;
-}
-
-long cm_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCCKBACK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlCheckVolumes(cm_ioctl_t *ioctlp, cm_user_t *userp)
{
cm_RefreshVolumes();
return 0;
}
-long cm_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCSETCACHESIZE internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ *
+ * This function is no longer meaningful in the current day world
+ * of persistent caches. The buf_SetNBuffers() function will
+ * inevitably fail.
+ */
+afs_int32
+cm_IoctlSetCacheSize(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
+ afs_int32 code;
afs_uint64 temp;
- long code;
-
- cm_SkipIoctlPath(ioctlp);
memcpy(&temp, ioctlp->inDatap, sizeof(temp));
if (temp == 0)
return code;
}
-long cm_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_TRACECTL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlTraceControl(cm_ioctl_t *ioctlp, cm_user_t *userp)
{
- long inValue;
-
- cm_SkipIoctlPath(ioctlp);
-
- memcpy(&inValue, ioctlp->inDatap, sizeof(long));
+ afs_uint32 inValue;
+
+ memcpy(&inValue, ioctlp->inDatap, sizeof(afs_uint32));
/* print trace */
if (inValue & 8) {
/* and copy out tracing flag */
inValue = afsd_logp->enabled; /* use as a temp vbl */
- memcpy(ioctlp->outDatap, &inValue, sizeof(long));
- ioctlp->outDatap += sizeof(long);
+ memcpy(ioctlp->outDatap, &inValue, sizeof(afs_uint32));
+ ioctlp->outDatap += sizeof(afs_uint32);
return 0;
}
-long cm_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCGETCACHEPARMS internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetCacheParms(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
cm_cacheParms_t parms;
return 0;
}
-long cm_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCGETCELL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
long whichCell;
long magic = 0;
char *tp;
char *basep;
- cm_SkipIoctlPath(ioctlp);
-
tp = ioctlp->inDatap;
memcpy((char *)&whichCell, tp, sizeof(long));
tp += sizeof(long);
/* see if more than one long passed in, ignoring the null pathname (the -1) */
- if (ioctlp->inCopied-1 > sizeof(long)) {
- memcpy((char *)&magic, tp, sizeof(long));
+ if (ioctlp->inCopied-1 > sizeof(afs_uint32)) {
+ memcpy((char *)&magic, tp, sizeof(afs_uint32));
}
lock_ObtainRead(&cm_cellLock);
for (tcellp = cm_data.allCellsp; tcellp; tcellp = tcellp->allNextp) {
- if (whichCell == 0) break;
+ if (whichCell == 0)
+ break;
whichCell--;
}
lock_ReleaseRead(&cm_cellLock);
memset(cp, 0, max * sizeof(long));
basep = cp;
lock_ObtainRead(&cm_serverLock); /* for going down server list */
- /* jaltman - do the reference counts to serverRefp contents need to be increased? */
- serverRefp = tcellp->vlServersp;
- for (i=0; i<max; i++) {
- if (!serverRefp) break;
+ for (i=0, serverRefp = tcellp->vlServersp;
+ serverRefp && i<max;
+ i++, serverRefp = serverRefp->next) {
serverp = serverRefp->server;
memcpy(cp, &serverp->addr.sin_addr.s_addr, sizeof(long));
cp += sizeof(long);
- serverRefp = serverRefp->next;
}
lock_ReleaseRead(&cm_serverLock);
cp = basep + max * sizeof(afs_int32);
return CM_ERROR_NOMORETOKENS; /* mapped to EDOM */
}
-long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
+
+/*
+ * VIOCNEWCELL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
- /* NT cache manager will read cell information from CellServDB each time
- * cell is accessed. So, this call is necessary only if list of server for a cell
- * changes (or IP addresses of cell servers changes).
+ /*
* All that needs to be done is to refresh server information for all cells that
* are already loaded.
cm_cell_t *cp;
cm_cell_rock_t rock;
-
- cm_SkipIoctlPath(ioctlp);
lock_ObtainWrite(&cm_cellLock);
for (cp = cm_data.allCellsp; cp; cp=cp->allNextp)
{
- long code;
+ afs_int32 code;
lock_ObtainMutex(&cp->mx);
/* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/
cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE);
return 0;
}
-long cm_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
-{
- long code = 0;
-
- if (cm_freelanceEnabled) {
- if (cm_GetRootCellName(ioctlp->outDatap))
- StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), "Freelance.Local.Root");
- ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
- } else if (cm_data.rootCellp) {
- /* return the default cellname to the caller */
- StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), cm_data.rootCellp->name);
- ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
- } else {
- /* if we don't know our default cell, return failure */
- code = CM_ERROR_NOSUCHCELL;
- }
+/*
+ * VIOC_GET_WS_CELL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetWsCell(cm_ioctl_t *ioctlp, cm_user_t *userp)
+{
+ afs_int32 code = 0;
+
+ if (cm_freelanceEnabled) {
+ if (cm_GetRootCellName(ioctlp->outDatap))
+ StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), "Freelance.Local.Root");
+ ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
+ } else if (cm_data.rootCellp) {
+ /* return the default cellname to the caller */
+ StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), cm_data.rootCellp->name);
+ ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
+ } else {
+ /* if we don't know our default cell, return failure */
+ code = CM_ERROR_NOSUCHCELL;
+ }
return code;
}
-long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_AFS_SYSNAME internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
- long setSysName, foundname = 0;
+ afs_uint32 setSysName, foundname = 0;
char *cp, *cp2, inname[MAXSYSNAME], outname[MAXSYSNAME];
int t, count, num = 0;
char **sysnamelist[MAXSYSNAME];
- cm_SkipIoctlPath(ioctlp);
-
- memcpy(&setSysName, ioctlp->inDatap, sizeof(long));
- ioctlp->inDatap += sizeof(long);
+ memcpy(&setSysName, ioctlp->inDatap, sizeof(afs_uint32));
+ ioctlp->inDatap += sizeof(afs_uint32);
if (setSysName) {
/* check my args */
return 0;
}
-long cm_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_GETCELLSTATUS internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetCellStatus(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
- long temp;
+ afs_uint32 temp;
cm_cell_t *cellp;
- cm_SkipIoctlPath(ioctlp);
-
cellp = cm_GetCell(ioctlp->inDatap, 0);
if (!cellp)
return CM_ERROR_NOSUCHCELL;
lock_ReleaseMutex(&cellp->mx);
/* now copy out parm */
- memcpy(ioctlp->outDatap, &temp, sizeof(long));
- ioctlp->outDatap += sizeof(long);
+ memcpy(ioctlp->outDatap, &temp, sizeof(afs_uint32));
+ ioctlp->outDatap += sizeof(afs_uint32);
return 0;
}
-long cm_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_SETCELLSTATUS internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlSetCellStatus(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
- long temp;
+ afs_uint32 temp;
cm_cell_t *cellp;
- cm_SkipIoctlPath(ioctlp);
-
- cellp = cm_GetCell(ioctlp->inDatap + 2*sizeof(long), 0);
+ cellp = cm_GetCell(ioctlp->inDatap + 2*sizeof(afs_uint32), 0);
if (!cellp)
return CM_ERROR_NOSUCHCELL;
- memcpy((char *)&temp, ioctlp->inDatap, sizeof(long));
+ memcpy((char *)&temp, ioctlp->inDatap, sizeof(afs_uint32));
lock_ObtainMutex(&cellp->mx);
if (temp & CM_SETCELLFLAG_SUID)
return 0;
}
-long cm_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_SETSPREFS internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlSetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
- cm_SSetPref_t *spin; /* input */
+ cm_SSetPref_t *spin; /* input */
cm_SPref_t *srvin; /* one input component */
cm_server_t *tsp;
- int i, vlonly, noServers, type;
- struct sockaddr_in tmp;
- unsigned short rank;
-
- cm_SkipIoctlPath(ioctlp); /* we don't care about the path */
+ int i, vlonly, noServers, type;
+ struct sockaddr_in tmp;
+ unsigned short rank;
spin = (cm_SSetPref_t *)ioctlp->inDatap;
noServers = spin->num_servers;
return 0;
}
-long cm_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_GETSPREFS internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
cm_SPrefRequest_t *spin; /* input */
cm_SPrefInfo_t *spout; /* output */
cm_server_t *tsp;
int i, vlonly, noServers;
- cm_SkipIoctlPath(ioctlp); /* we don't care about the path */
-
spin = (cm_SPrefRequest_t *)ioctlp->inDatap;
spout = (cm_SPrefInfo_t *) ioctlp->outDatap;
srvout = spout->servers;
return 0;
}
-long cm_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp)
-{
- /* we ignore default asynchrony since we only have one way
- * of doing this today.
- */
- return 0;
-}
-long cm_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_AFS_CREATE_MT_PT internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * dscp is held but not locked.
+ */
+afs_int32
+cm_IoctlCreateMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp, char *leaf)
{
- char leaf[LEAF_SIZE];
- long code;
- cm_scache_t *dscp;
+ afs_int32 code;
cm_attr_t tattr;
char *cp;
- cm_req_t req;
char mpInfo[256];
char fullCell[256];
char volume[256];
char cell[256];
int ttl;
- cm_InitReq(&req);
-
- code = cm_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
- if (code)
- return code;
-
/* Translate chars for the mount point name */
- if (!(ioctlp->flags & SMB_IOCTLFLAG_USEUTF8)) {
- TranslateExtendedChars(leaf);
+ if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) {
+ TranslateExtendedChars(leaf);
}
- /*
+ /*
* The fs command allows the user to specify partial cell names on NT. These must
* be expanded to the full cell name for mount points so that the mount points will
* work on UNIX clients.
code = cm_SearchCellByDNS(cell, fullCell, &ttl, 0, 0);
#endif
if (code) {
- cm_ReleaseSCache(dscp);
return CM_ERROR_NOSUCHCELL;
}
tattr.unixModeBits = 0644;
tattr.clientModTime = time(NULL);
- code = cm_SymLink(dscp, leaf, mpInfo, 0, &tattr, userp, &req);
+ code = cm_SymLink(dscp, leaf, mpInfo, 0, &tattr, userp, reqp);
}
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
FILE_NOTIFY_CHANGE_DIR_NAME,
dscp, leaf, NULL, TRUE);
- cm_ReleaseSCache(dscp);
return code;
}
-long cm_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_SYMLINK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * dscp is held but not locked.
+ */
+afs_int32
+cm_IoctlSymlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp, char *leaf)
{
- char leaf[LEAF_SIZE];
- long code;
- cm_scache_t *dscp;
+ afs_int32 code;
cm_attr_t tattr;
char *cp;
- cm_req_t req;
char *symlp;
int free_syml = FALSE;
- cm_InitReq(&req);
-
- code = cm_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
- if (code) return code;
-
- if (!(ioctlp->flags & SMB_IOCTLFLAG_USEUTF8)) {
- /* Translate chars for the link name */
- TranslateExtendedChars(leaf);
+ if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) {
+ /* Translate chars for the link name */
+ TranslateExtendedChars(leaf);
- /* Translate chars for the linked to name */
- TranslateExtendedChars(ioctlp->inDatap);
+ /* Translate chars for the linked to name */
+ TranslateExtendedChars(ioctlp->inDatap);
}
symlp = ioctlp->inDatap; /* contents of link */
tattr.mask = CM_ATTRMASK_UNIXMODEBITS;
tattr.unixModeBits = 0755;
- code = cm_SymLink(dscp, leaf, cp, 0, &tattr, userp, &req);
+ code = cm_SymLink(dscp, leaf, cp, 0, &tattr, userp, reqp);
}
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
| FILE_NOTIFY_CHANGE_DIR_NAME,
dscp, leaf, NULL, TRUE);
- cm_ReleaseSCache(dscp);
-
if (free_syml)
free(symlp);
}
-long cm_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_LISTSYMLINK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * dscp is held but not locked.
+ */
+afs_int32
+cm_IoctlListlink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *dscp;
+ afs_int32 code;
cm_scache_t *scp;
char *cp;
cm_space_t *spacep;
cm_scache_t *newRootScp;
- cm_req_t req;
-
- cm_InitReq(&req);
-
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
- if (code) return code;
+ if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) {
+ /* Translate chars for the link name */
+ TranslateExtendedChars(ioctlp->inDatap);
+ }
cp = ioctlp->inDatap;
- code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
- cm_ReleaseSCache(dscp);
- if (code) return code;
+ code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp);
+ if (code)
+ return code;
/* Check that it's a real symlink */
if (scp->fileType != CM_SCACHETYPE_SYMLINK &&
return CM_ERROR_INVAL;
}
- code = cm_AssembleLink(scp, "", &newRootScp, &spacep, userp, &req);
+ code = cm_AssembleLink(scp, "", &newRootScp, &spacep, userp, reqp);
cm_ReleaseSCache(scp);
if (code == 0) {
cp = ioctlp->outDatap;
return code;
}
-long cm_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_ISSYMLINK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * dscp is held but not locked.
+ */
+afs_int32
+cm_IoctlIslink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp)
{/*CHECK FOR VALID SYMLINK*/
- long code;
- cm_scache_t *dscp;
+ afs_int32 code;
cm_scache_t *scp;
char *cp;
- cm_req_t req;
-
- cm_InitReq(&req);
-
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
- if (code) return code;
+ if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) {
+ /* Translate chars for the link name */
+ TranslateExtendedChars(ioctlp->inDatap);
+ }
cp = ioctlp->inDatap;
osi_LogEvent("cm_IoctlListlink",NULL," name[%s]",cp);
- code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
- cm_ReleaseSCache(dscp);
- if (code) return code;
+ code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp);
+ if (code)
+ return code;
/* Check that it's a real symlink */
if (scp->fileType != CM_SCACHETYPE_SYMLINK &&
return code;
}
-long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_DELSYMLINK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * dscp is held but not locked.
+ */
+afs_int32
+cm_IoctlDeletelink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *dscp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *dscp;
+ afs_int32 code;
cm_scache_t *scp;
char *cp;
char * originalName = NULL;
- cm_req_t req;
cm_dirOp_t dirop;
- cm_InitReq(&req);
-
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
- if (code) return code;
-
+ if (!(ioctlp->flags & CM_IOCTLFLAG_USEUTF8)) {
+ /* Translate chars for the link name */
+ TranslateExtendedChars(ioctlp->inDatap);
+ }
cp = ioctlp->inDatap;
- code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
+ code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp);
/* if something went wrong, bail out now */
if (code)
goto done3;
lock_ObtainWrite(&scp->rw);
- code = cm_SyncOp(scp, NULL, userp, &req, 0,
+ code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code)
goto done2;
lock_ReleaseWrite(&scp->rw);
#ifdef USE_BPLUS
- code = cm_BeginDirOp(dscp, userp, &req, CM_DIRLOCK_READ, &dirop);
+ code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ, &dirop);
if (code == 0) {
code = cm_BPlusDirLookupOriginalName(&dirop, cp, &originalName);
/* cm_Dir*() functions can't be used to lookup the original
#endif
{
/* easier to do it this way */
- code = cm_Unlink(dscp, originalName, cp, userp, &req);
+ code = cm_Unlink(dscp, originalName, cp, userp, reqp);
}
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
smb_NotifyChange(FILE_ACTION_REMOVED,
cm_ReleaseSCache(scp);
done3:
- cm_ReleaseSCache(dscp);
return code;
}
#ifdef QUERY_AFSID
-long cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
+/* Utility function. Not currently used.
+ * This function performs a PTS lookup which has traditionally
+ * not been performed by the cache manager.
+ */
+afs_int32
+cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
{
afs_int32 code;
namelist lnames;
}
#endif /* QUERY_AFSID */
-long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+#if 0
+/* This has been copied to smb_IoctlSetToken in its entirety.
+ * An equivalent version will need to be produced for the
+ * redirector and some extensive refactoring might be required.
+ */
+afs_int32
+cm_IoctlSetToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
char *saveDataPtr;
char *tp;
lock_ReleaseMutex(&userp->mx);
if (flags & PIOCTL_LOGON) {
- ioctlp->flags |= SMB_IOCTLFLAG_LOGON;
+ ioctlp->flags |= CM_IOCTLFLAG_LOGON;
}
cm_ResetACLCache(userp);
return 0;
}
+#endif
-long cm_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_GETTOK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetTokenIter(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
char *tp, *cp;
int iterator;
cm_ucell_t *ucellp;
struct ClearToken ct;
- cm_SkipIoctlPath(ioctlp);
-
tp = ioctlp->inDatap;
cp = ioctlp->outDatap;
/* clear token */
ct.AuthHandle = ucellp->kvno;
+
/*
- * Don't give out a real session key here
+ * This field is supposed to hold the session key
+ * but we don't want to make it easier for someone
+ * to attack the cache. The user gave us the session
+ * key in the first place.
*/
- /*
- memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey));
- */
memset(ct.HandShakeKey, 0, sizeof(ct.HandShakeKey));
ct.ViceId = 37; /* XXX */
ct.BeginTimestamp = 0; /* XXX */
return 0;
}
-long cm_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_NEWGETTOK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
char *cp;
int temp;
struct ClearToken ct;
char *tp;
afs_uuid_t uuid;
- cm_SkipIoctlPath(ioctlp);
tp = ioctlp->inDatap;
/* clear token */
ct.AuthHandle = ucellp->kvno;
- /*
- * Don't give out a real session key here
- */
- /*
- memcpy(ct.HandShakeKey, &ucellp->sessionKey, sizeof(ct.HandShakeKey));
- */
+
+ /* do not give out the session key */
memset(ct.HandShakeKey, 0, sizeof(ct.HandShakeKey));
ct.ViceId = 37; /* XXX */
ct.BeginTimestamp = 0; /* XXX */
return 0;
}
-long cm_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCDELTOK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlDelToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
char *cp;
cm_cell_t *cellp;
cm_ucell_t *ucellp;
- cm_SkipIoctlPath(ioctlp);
-
cp = ioctlp->outDatap;
/* cell name is right here */
return 0;
}
-long cm_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOCDELALLTOK internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlDelAllToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
cm_ucell_t *ucellp;
return 0;
}
-long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp)
+/*
+ * VIOC_MAKESUBMOUNT internals. (This function should be deprecated)
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlMakeSubmount(cm_ioctl_t *ioctlp, cm_user_t *userp)
{
char afspath[MAX_PATH];
char *submountreqp;
DWORD dwIndex;
DWORD dwSubmounts;
- cm_SkipIoctlPath(ioctlp);
-
/* Serialize this one, to prevent simultaneous mods
* to afsdsbmt.ini
*/
return 0;
}
-long cm_IoctlGetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp)
+/*
+ * VIOC_GETRXKCRYPT internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetRxkcrypt(cm_ioctl_t *ioctlp, cm_user_t *userp)
{
memcpy(ioctlp->outDatap, &cryptall, sizeof(cryptall));
ioctlp->outDatap += sizeof(cryptall);
return 0;
}
-long cm_IoctlSetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp)
+/*
+ * VIOC_SETRXKCRYPT internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlSetRxkcrypt(cm_ioctl_t *ioctlp, cm_user_t *userp)
{
afs_int32 c = cryptall;
- cm_SkipIoctlPath(ioctlp);
-
memcpy(&cryptall, ioctlp->inDatap, sizeof(cryptall));
if (c != cryptall) {
return 0;
}
-long cm_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_RXSTAT_PROC internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlRxStatProcess(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
afs_int32 flags;
int code = 0;
- cm_SkipIoctlPath(ioctlp);
-
memcpy((char *)&flags, ioctlp->inDatap, sizeof(afs_int32));
if (!(flags & AFSCALL_RXSTATS_MASK) || (flags & ~AFSCALL_RXSTATS_MASK)) {
return -1;
return 0;
}
-long cm_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_RXSTAT_PEER internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlRxStatPeer(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
afs_int32 flags;
int code = 0;
- cm_SkipIoctlPath(ioctlp);
-
memcpy((char *)&flags, ioctlp->inDatap, sizeof(afs_int32));
if (!(flags & AFSCALL_RXSTATS_MASK) || (flags & ~AFSCALL_RXSTATS_MASK)) {
return -1;
return 0;
}
-long cm_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
-{
- smb_user_t *uidp = ioctlp->uidp;
-
- if (uidp && uidp->unp) {
- memcpy(ioctlp->outDatap, uidp->unp->name, strlen(uidp->unp->name));
- ioctlp->outDatap += strlen(uidp->unp->name);
- }
-
- return 0;
-}
-
-long cm_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user * userp)
+/*
+ * VIOC_UNICODECTL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlUnicodeControl(struct cm_ioctl *ioctlp, struct cm_user * userp)
{
- long result = 0;
+ afs_int32 result = 0;
#ifdef SMB_UNICODE
- long cmd;
-
- cm_SkipIoctlPath(ioctlp);
+ afs_uint32 cmd;
- memcpy(&cmd, ioctlp->inDatap, sizeof(long));
+ memcpy(&cmd, ioctlp->inDatap, sizeof(afs_uint32));
if (cmd & 2) {
/* Setting the Unicode flag */
return 0;
}
-long cm_IoctlUUIDControl(struct smb_ioctl * ioctlp, struct cm_user *userp)
+/*
+ * VIOC_UUIDCTL internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlUUIDControl(struct cm_ioctl * ioctlp, struct cm_user *userp)
{
- long cmd;
+ afs_uint32 cmd;
afsUUID uuid;
- cm_SkipIoctlPath(ioctlp);
-
- memcpy(&cmd, ioctlp->inDatap, sizeof(long));
+ memcpy(&cmd, ioctlp->inDatap, sizeof(afs_uint32));
if (cmd) { /* generate a new UUID */
UuidCreate((UUID *) &uuid);
extern int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock);
extern int smb_DumpVCP(FILE *outputFile, char *cookie, int lock);
-long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_TRACEMEMDUMP internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * dscp is held but not locked.
+ */
+afs_int32
+cm_IoctlMemoryDump(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
- long inValue = 0;
+ afs_int32 inValue = 0;
HANDLE hLogFile;
char logfileName[MAX_PATH+1];
char *cookie;
static _CrtMemState memstate;
#endif
- cm_SkipIoctlPath(ioctlp);
- memcpy(&inValue, ioctlp->inDatap, sizeof(long));
+ memcpy(&inValue, ioctlp->inDatap, sizeof(afs_int32));
dwSize = GetEnvironmentVariable("TEMP", logfileName, sizeof(logfileName));
if ( dwSize == 0 || dwSize > sizeof(logfileName) )
{
/* error */
inValue = -1;
- memcpy(ioctlp->outDatap, &inValue, sizeof(long));
- ioctlp->outDatap += sizeof(long);
+ memcpy(ioctlp->outDatap, &inValue, sizeof(afs_int32));
+ ioctlp->outDatap += sizeof(afs_int32);
return 0;
}
return 0;
}
-
-static long
+/* Utility functon. Not currently used. */
+static afs_int32
cm_CheckServersStatus(cm_serverRef_t *serversp)
{
- long code = 0;
+ afs_int32 code = 0;
cm_serverRef_t *tsrp;
cm_server_t *tsp;
int someBusy = 0, someOffline = 0, allOffline = 1, allBusy = 1, allDown = 1;
return code;
}
-
-long cm_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_PATH_AVAILABILITY internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ * scp is held but not locked.
+ */
+afs_int32
+cm_IoctlPathAvailability(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
{
- long code;
- cm_scache_t *scp;
+ afs_int32 code;
cm_cell_t *cellp;
cm_volume_t *tvp;
cm_vol_state_t *statep;
afs_uint32 volume;
- cm_req_t req;
- cm_ioctlQueryOptions_t *optionsp;
- afs_uint32 flags = 0;
-
- cm_InitReq(&req);
-
- optionsp = cm_IoctlGetQueryOptions(ioctlp, userp);
- if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
- flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
-
- if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
- cm_fid_t fid;
- cm_SkipIoctlPath(ioctlp);
- cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
- optionsp->fid.vnode, optionsp->fid.unique);
- code = cm_GetSCache(&fid, &scp, userp, &req);
- } else {
- code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
- }
- if (code)
- return code;
#ifdef AFS_FREELANCE_CLIENT
if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) {
code = 0;
- cm_ReleaseSCache(scp);
} else
#endif
{
cellp = cm_FindCellByID(scp->fid.cell, 0);
- cm_ReleaseSCache(scp);
-
if (!cellp)
return CM_ERROR_NOSUCHCELL;
- code = cm_FindVolumeByID(cellp, volume, userp, &req, CM_GETVOL_FLAG_CREATE, &tvp);
+ code = cm_FindVolumeByID(cellp, volume, userp, reqp, CM_GETVOL_FLAG_CREATE, &tvp);
if (code)
return code;
return code;
}
-
-long cm_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp)
+/*
+ * VIOC_VOLSTAT_TEST internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlVolStatTest(struct cm_ioctl *ioctlp, struct cm_user *userp)
{
- long code;
+ afs_int32 code;
cm_cell_t *cellp = NULL;
cm_volume_t *volp;
cm_vol_state_t *statep;
struct VolStatTest * testp;
- cm_req_t req;
afs_uint32 n;
+ cm_req_t req;
cm_InitReq(&req);
- cm_SkipIoctlPath(ioctlp); /* we don't care about the path */
testp = (struct VolStatTest *)ioctlp->inDatap;
#ifdef AFS_FREELANCE_CLIENT
#define __CM_IOCTL_H_ENV__ 1
#ifndef __CM_IOCTL_INTERFACES_ONLY__
-#include "smb.h"
#include "cm_user.h"
#else
typedef struct cm_fid {
afs_uint64 parms[CM_IOCTLCACHEPARMS];
} cm_cacheParms_t;
+typedef struct cm_ioctl {
+ /* input side */
+ char *inDatap; /* ioctl func's current position
+ * in input parameter block */
+ char *inAllocp; /* allocated input parameter block */
+ afs_uint32 inCopied; /* # of input bytes copied in so far
+ * by write calls */
+ /* output side */
+ char *outDatap; /* output results assembled so far */
+ char *outAllocp; /* output results assembled so far */
+ afs_uint32 outCopied; /* # of output bytes copied back so far
+
+ /* flags */
+ afs_uint32 flags;
+} cm_ioctl_t;
+
+/* flags for smb_ioctl_t */
+#define CM_IOCTLFLAG_DATAIN 1 /* reading data from client to server */
+#define CM_IOCTLFLAG_LOGON 2 /* got tokens from integrated logon */
+#define CM_IOCTLFLAG_USEUTF8 4 /* this request is using UTF-8 strings */
+
+
/*
* The cm_IoctlQueryOptions structure is designed to be extendible.
* None of the fields are required but when specified
strings. */
#define UTF8_PREFIX "\33%G"
+extern const char utf8_prefix[];
+extern const int utf8_prefix_size;
+
/* flags for rxstats pioctl */
#define AFSCALL_RXSTATS_MASK 0x7 /* Valid flag bits */
#ifndef __CM_IOCTL_INTERFACES_ONLY__
-void cm_InitIoctl(void);
+extern void cm_InitIoctl(void);
+
+extern void cm_ResetACLCache(cm_user_t *userp);
+
+extern cm_ioctlQueryOptions_t * cm_IoctlGetQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp);
+
+extern void cm_IoctlSkipQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp);
+
+extern void cm_NormalizeAfsPath(char *outpathp, long outlen, char *inpathp);
-void cm_ResetACLCache(cm_user_t *userp);
+extern void cm_SkipIoctlPath(cm_ioctl_t *ioctlp);
-extern long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetACL(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlGetFileCellName(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetFileCellName(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSetACL(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlFlushAllVolumes(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlFlushAllVolumes(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlFlushVolume(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlFlushVolume(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlFlushFile(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlFlushFile(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlSetVolumeStatus(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSetVolumeStatus(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlGetVolumeStatus(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetVolumeStatus(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlGetFid(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetFid(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlGetOwner(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetOwner(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlWhereIs(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlWhereIs(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlStatMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlStatMountPoint(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlDeleteMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlDeleteMountPoint(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlCheckServers(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlCheckServers(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGag(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGag(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlCheckVolumes(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlCheckVolumes(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlSetCacheSize(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSetCacheSize(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGetCacheParms(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetCacheParms(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGetCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlNewCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlNewCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetWsCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlSysName(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSysName(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGetCellStatus(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetCellStatus(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlSetCellStatus(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSetCellStatus(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlSetSPrefs(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSetSPrefs(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGetSPrefs(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetSPrefs(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlStoreBehind(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlStoreBehind(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlCreateMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlCreateMountPoint(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *dscp, cm_req_t *reqp, char *leaf);
-extern long cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+extern afs_int32 cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
-extern long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+extern afs_int32 cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
-extern long cm_FlushVolume(cm_user_t *, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume);
+extern afs_int32 cm_FlushVolume(cm_user_t *, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume);
-extern long cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+extern afs_int32 cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
-extern long cm_IoctlTraceControl(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlTraceControl(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlSetToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSetToken(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGetTokenIter(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetTokenIter(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGetToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetToken(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlDelToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlDelToken(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlDelAllToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlDelAllToken(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlSymlink(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSymlink(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *dscp, cm_req_t *reqp, char *leaf);
-extern long cm_IoctlIslink(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlIslink(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlListlink(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlListlink(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
-extern long cm_IoctlDeletelink(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlDeletelink(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *dscp, cm_req_t *reqp);
-extern long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlMakeSubmount(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlGetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetRxkcrypt(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlSetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlSetRxkcrypt(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlShutdown(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlShutdown(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlFreemountAddCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlFreemountAddCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlFreemountRemoveCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlFreemountRemoveCell(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlMemoryDump(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlMemoryDump(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlRxStatProcess(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlRxStatProcess(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlRxStatPeer(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlRxStatPeer(cm_ioctl_t *ioctlp, cm_user_t *userp);
-extern long cm_IoctlUUIDControl(struct smb_ioctl * ioctlp, struct cm_user *userp);
+extern afs_int32 cm_IoctlUUIDControl(struct cm_ioctl * ioctlp, struct cm_user *userp);
-extern long cm_IoctlPathAvailability(struct smb_ioctl * ioctlp, struct cm_user *userp);
+extern afs_int32 cm_IoctlPathAvailability(struct cm_ioctl * ioctlp, struct cm_user *userp, struct cm_scache *scp, struct cm_req *reqp);
-extern long cm_IoctlGetFileType(smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 cm_IoctlGetFileType(cm_ioctl_t *ioctlp, cm_user_t *userp, struct cm_scache *scp, struct cm_req *reqp);
-extern long cm_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp);
+extern afs_int32 cm_IoctlVolStatTest(struct cm_ioctl *ioctlp, struct cm_user *userp);
-extern long cm_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user * userp);
+extern afs_int32 cm_IoctlUnicodeControl(struct cm_ioctl *ioctlp, struct cm_user * userp);
#endif /* __CM_IOCTL_INTERFACES_ONLY__ */
#include <string.h>
#include "afsd.h"
+#include "smb.h"
#include <osi.h>
#include <rx/rx.h>
#include <osi.h>
#include "afsd.h"
+#include "smb.h"
#include "cm_btree.h"
#ifdef DEBUG
if (ioctlp) {
if (ioctlp->prefix)
cm_FreeSpace(ioctlp->prefix);
- if (ioctlp->inAllocp)
- free(ioctlp->inAllocp);
- if (ioctlp->outAllocp)
- free(ioctlp->outAllocp);
+ if (ioctlp->ioctl.inAllocp)
+ free(ioctlp->ioctl.inAllocp);
+ if (ioctlp->ioctl.outAllocp)
+ free(ioctlp->ioctl.outAllocp);
free(ioctlp);
}
lock_ReleaseMutex(&fidp->mx);
struct smb_tid *tidp; /* back ptr */
} smb_pid_t;
-/* ioctl parameter, while being assembled and/or processed */
-typedef struct smb_ioctl {
- /* input side */
- char *inDatap; /* ioctl func's current position
- * in input parameter block */
- char *inAllocp; /* allocated input parameter block */
- afs_uint32 inCopied; /* # of input bytes copied in so far
- * by write calls */
- cm_space_t *prefix; /* prefix for subst drives */
- char *tidPathp; /* Pathname associated with Tree ID */
-
- /* output side */
- char *outDatap; /* output results assembled so far */
- char *outAllocp; /* output results assembled so far */
- afs_uint32 outCopied; /* # of output bytes copied back so far
- * by read calls */
-
- /* flags */
- afs_uint32 flags;
-
- /* fid pointer */
- struct smb_fid *fidp;
-
- /* uid pointer */
- smb_user_t *uidp;
-
-} smb_ioctl_t;
-
-/* flags for smb_ioctl_t */
-#define SMB_IOCTLFLAG_DATAIN 1 /* reading data from client to server */
-#define SMB_IOCTLFLAG_LOGON 2 /* got tokens from integrated logon */
-#define SMB_IOCTLFLAG_USEUTF8 4 /* this request is using UTF-8 strings */
+
+/* Defined in smb_ioctl.h */
+struct smb_ioctl;
/* one per file ID; these are really file descriptors */
typedef struct smb_fid {
the file if session is
terminated) */
osi_hyper_t offset; /* our file pointer */
- smb_ioctl_t *ioctlp; /* ptr to ioctl structure */
+ struct smb_ioctl *ioctlp; /* ptr to ioctl structure */
/* Under NT, we may need to know the
* parent directory and pathname used
* to open the file, either to delete
extern smb_username_t *smb_FindUserByName(char *usern, char *machine, afs_uint32 flags);
+extern cm_user_t *smb_FindCMUserByName(char *usern, char *machine, afs_uint32 flags);
+
extern smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern);
extern void smb_ReleaseUsername(smb_username_t *unp);
} chservinfo_t;
struct gaginfo {
- unsigned long showflags, logflags, logwritethruflag, spare[3];
+ afs_uint32 showflags, logflags, logwritethruflag, spare[3];
unsigned char spare2[128];
};
#define VIOC_UNICODECTL 0x33
#define VIOC_VOLSTAT_TEST 0x3F
-/* Not to exceed SMB_IOCTL_MAXPROCS from smb_ioctl.h */
+
+/* magic file name for ioctl opens */
+#define CM_IOCTL_FILENAME "\\_._AFS_IOCTL_._" /* double backslashes for C compiler */
+#define CM_IOCTL_FILENAME_NOSLASH "_._AFS_IOCTL_._"
+
+/* max parms for ioctl, in either direction */
+#define CM_IOCTL_MAXDATA 8192*2
+#define CM_IOCTL_MAXPROCS 64
+
#endif /* __SMB_IOCONS_H_ENV_ */
#include <string.h>
#include <stdio.h>
#include <time.h>
+#include <strsafe.h>
#include <osi.h>
#include "smb.h"
+#include "cm_rpc.h"
+#include "afs/afsrpc.h"
+#include "afs/auth.h"
+
smb_ioctlProc_t *smb_ioctlProcsp[SMB_IOCTL_MAXPROCS];
-/*extern unsigned char smb_LANadapter;*/
-
-void smb_InitIoctl(void)
-{
- int i;
- for (i=0; i<SMB_IOCTL_MAXPROCS; i++)
- smb_ioctlProcsp[i] = NULL;
-
- smb_ioctlProcsp[VIOCGETAL] = cm_IoctlGetACL;
- smb_ioctlProcsp[VIOC_FILE_CELL_NAME] = cm_IoctlGetFileCellName;
- smb_ioctlProcsp[VIOCSETAL] = cm_IoctlSetACL;
- smb_ioctlProcsp[VIOC_FLUSHVOLUME] = cm_IoctlFlushVolume;
- smb_ioctlProcsp[VIOCFLUSH] = cm_IoctlFlushFile;
- smb_ioctlProcsp[VIOCSETVOLSTAT] = cm_IoctlSetVolumeStatus;
- smb_ioctlProcsp[VIOCGETVOLSTAT] = cm_IoctlGetVolumeStatus;
- smb_ioctlProcsp[VIOCWHEREIS] = cm_IoctlWhereIs;
- smb_ioctlProcsp[VIOC_AFS_STAT_MT_PT] = cm_IoctlStatMountPoint;
- smb_ioctlProcsp[VIOC_AFS_DELETE_MT_PT] = cm_IoctlDeleteMountPoint;
- smb_ioctlProcsp[VIOCCKSERV] = cm_IoctlCheckServers;
- smb_ioctlProcsp[VIOC_GAG] = cm_IoctlGag;
- smb_ioctlProcsp[VIOCCKBACK] = cm_IoctlCheckVolumes;
- smb_ioctlProcsp[VIOCSETCACHESIZE] = cm_IoctlSetCacheSize;
- smb_ioctlProcsp[VIOCGETCACHEPARMS] = cm_IoctlGetCacheParms;
- smb_ioctlProcsp[VIOCGETCELL] = cm_IoctlGetCell;
- smb_ioctlProcsp[VIOCNEWCELL] = cm_IoctlNewCell;
- smb_ioctlProcsp[VIOC_GET_WS_CELL] = cm_IoctlGetWsCell;
- smb_ioctlProcsp[VIOC_AFS_SYSNAME] = cm_IoctlSysName;
- smb_ioctlProcsp[VIOC_GETCELLSTATUS] = cm_IoctlGetCellStatus;
- smb_ioctlProcsp[VIOC_SETCELLSTATUS] = cm_IoctlSetCellStatus;
- smb_ioctlProcsp[VIOC_SETSPREFS] = cm_IoctlSetSPrefs;
- smb_ioctlProcsp[VIOC_GETSPREFS] = cm_IoctlGetSPrefs;
- smb_ioctlProcsp[VIOC_STOREBEHIND] = cm_IoctlStoreBehind;
- smb_ioctlProcsp[VIOC_AFS_CREATE_MT_PT] = cm_IoctlCreateMountPoint;
- smb_ioctlProcsp[VIOC_TRACECTL] = cm_IoctlTraceControl;
- smb_ioctlProcsp[VIOCSETTOK] = cm_IoctlSetToken;
- smb_ioctlProcsp[VIOCGETTOK] = cm_IoctlGetTokenIter;
- smb_ioctlProcsp[VIOCNEWGETTOK] = cm_IoctlGetToken;
- smb_ioctlProcsp[VIOCDELTOK] = cm_IoctlDelToken;
- smb_ioctlProcsp[VIOCDELALLTOK] = cm_IoctlDelAllToken;
- smb_ioctlProcsp[VIOC_SYMLINK] = cm_IoctlSymlink;
- smb_ioctlProcsp[VIOC_LISTSYMLINK] = cm_IoctlListlink;
- smb_ioctlProcsp[VIOC_DELSYMLINK] = cm_IoctlDeletelink;
- smb_ioctlProcsp[VIOC_MAKESUBMOUNT] = cm_IoctlMakeSubmount;
- smb_ioctlProcsp[VIOC_GETRXKCRYPT] = cm_IoctlGetRxkcrypt;
- smb_ioctlProcsp[VIOC_SETRXKCRYPT] = cm_IoctlSetRxkcrypt;
- smb_ioctlProcsp[VIOC_ISSYMLINK] = cm_IoctlIslink;
- smb_ioctlProcsp[VIOC_TRACEMEMDUMP] = cm_IoctlMemoryDump;
- smb_ioctlProcsp[VIOC_ISSYMLINK] = cm_IoctlIslink;
- smb_ioctlProcsp[VIOC_FLUSHALL] = cm_IoctlFlushAllVolumes;
- smb_ioctlProcsp[VIOCGETFID] = cm_IoctlGetFid;
- smb_ioctlProcsp[VIOCGETOWNER] = cm_IoctlGetOwner;
- smb_ioctlProcsp[VIOC_RXSTAT_PROC] = cm_IoctlRxStatProcess;
- smb_ioctlProcsp[VIOC_RXSTAT_PEER] = cm_IoctlRxStatPeer;
- smb_ioctlProcsp[VIOC_UUIDCTL] = cm_IoctlUUIDControl;
- smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = cm_IoctlPathAvailability;
- smb_ioctlProcsp[VIOC_GETFILETYPE] = cm_IoctlGetFileType;
- smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = cm_IoctlVolStatTest;
- smb_ioctlProcsp[VIOC_UNICODECTL] = cm_IoctlUnicodeControl;
-}
+void
+smb_InitIoctl(void)
+{
+ int i;
+ for (i=0; i<SMB_IOCTL_MAXPROCS; i++)
+ smb_ioctlProcsp[i] = NULL;
+
+ smb_ioctlProcsp[VIOCGETAL] = smb_IoctlGetACL;
+ smb_ioctlProcsp[VIOC_FILE_CELL_NAME] = smb_IoctlGetFileCellName;
+ smb_ioctlProcsp[VIOCSETAL] = smb_IoctlSetACL;
+ smb_ioctlProcsp[VIOC_FLUSHVOLUME] = smb_IoctlFlushVolume;
+ smb_ioctlProcsp[VIOCFLUSH] = smb_IoctlFlushFile;
+ smb_ioctlProcsp[VIOCSETVOLSTAT] = smb_IoctlSetVolumeStatus;
+ smb_ioctlProcsp[VIOCGETVOLSTAT] = smb_IoctlGetVolumeStatus;
+ smb_ioctlProcsp[VIOCWHEREIS] = smb_IoctlWhereIs;
+ smb_ioctlProcsp[VIOC_AFS_STAT_MT_PT] = smb_IoctlStatMountPoint;
+ smb_ioctlProcsp[VIOC_AFS_DELETE_MT_PT] = smb_IoctlDeleteMountPoint;
+ smb_ioctlProcsp[VIOCCKSERV] = smb_IoctlCheckServers;
+ smb_ioctlProcsp[VIOC_GAG] = smb_IoctlGag;
+ smb_ioctlProcsp[VIOCCKBACK] = smb_IoctlCheckVolumes;
+ smb_ioctlProcsp[VIOCSETCACHESIZE] = smb_IoctlSetCacheSize;
+ smb_ioctlProcsp[VIOCGETCACHEPARMS] = smb_IoctlGetCacheParms;
+ smb_ioctlProcsp[VIOCGETCELL] = smb_IoctlGetCell;
+ smb_ioctlProcsp[VIOCNEWCELL] = smb_IoctlNewCell;
+ smb_ioctlProcsp[VIOC_GET_WS_CELL] = smb_IoctlGetWsCell;
+ smb_ioctlProcsp[VIOC_AFS_SYSNAME] = smb_IoctlSysName;
+ smb_ioctlProcsp[VIOC_GETCELLSTATUS] = smb_IoctlGetCellStatus;
+ smb_ioctlProcsp[VIOC_SETCELLSTATUS] = smb_IoctlSetCellStatus;
+ smb_ioctlProcsp[VIOC_SETSPREFS] = smb_IoctlSetSPrefs;
+ smb_ioctlProcsp[VIOC_GETSPREFS] = smb_IoctlGetSPrefs;
+ smb_ioctlProcsp[VIOC_STOREBEHIND] = smb_IoctlStoreBehind;
+ smb_ioctlProcsp[VIOC_AFS_CREATE_MT_PT] = smb_IoctlCreateMountPoint;
+ smb_ioctlProcsp[VIOC_TRACECTL] = smb_IoctlTraceControl;
+ smb_ioctlProcsp[VIOCSETTOK] = smb_IoctlSetToken;
+ smb_ioctlProcsp[VIOCGETTOK] = smb_IoctlGetTokenIter;
+ smb_ioctlProcsp[VIOCNEWGETTOK] = smb_IoctlGetToken;
+ smb_ioctlProcsp[VIOCDELTOK] = smb_IoctlDelToken;
+ smb_ioctlProcsp[VIOCDELALLTOK] = smb_IoctlDelAllToken;
+ smb_ioctlProcsp[VIOC_SYMLINK] = smb_IoctlSymlink;
+ smb_ioctlProcsp[VIOC_LISTSYMLINK] = smb_IoctlListlink;
+ smb_ioctlProcsp[VIOC_DELSYMLINK] = smb_IoctlDeletelink;
+ smb_ioctlProcsp[VIOC_MAKESUBMOUNT] = smb_IoctlMakeSubmount;
+ smb_ioctlProcsp[VIOC_GETRXKCRYPT] = smb_IoctlGetRxkcrypt;
+ smb_ioctlProcsp[VIOC_SETRXKCRYPT] = smb_IoctlSetRxkcrypt;
+ smb_ioctlProcsp[VIOC_ISSYMLINK] = smb_IoctlIslink;
+ smb_ioctlProcsp[VIOC_TRACEMEMDUMP] = smb_IoctlMemoryDump;
+ smb_ioctlProcsp[VIOC_ISSYMLINK] = smb_IoctlIslink;
+ smb_ioctlProcsp[VIOC_FLUSHALL] = smb_IoctlFlushAllVolumes;
+ smb_ioctlProcsp[VIOCGETFID] = smb_IoctlGetFid;
+ smb_ioctlProcsp[VIOCGETOWNER] = smb_IoctlGetOwner;
+ smb_ioctlProcsp[VIOC_RXSTAT_PROC] = smb_IoctlRxStatProcess;
+ smb_ioctlProcsp[VIOC_RXSTAT_PEER] = smb_IoctlRxStatPeer;
+ smb_ioctlProcsp[VIOC_UUIDCTL] = smb_IoctlUUIDControl;
+ smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = smb_IoctlPathAvailability;
+ smb_ioctlProcsp[VIOC_GETFILETYPE] = smb_IoctlGetFileType;
+ smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = smb_IoctlVolStatTest;
+ smb_ioctlProcsp[VIOC_UNICODECTL] = smb_IoctlUnicodeControl;
+}
/* called to make a fid structure into an IOCTL fid structure */
-void smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
+void
+smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
{
smb_ioctl_t *iop;
cm_space_t *copyPrefix;
}
if (prefix) {
copyPrefix = cm_GetSpace();
- strcpy(copyPrefix->data, prefix->data);
+ StringCbCopy(copyPrefix->data, CM_UTILS_SPACESIZE, prefix->data);
fidp->ioctlp->prefix = copyPrefix;
}
lock_ReleaseMutex(&fidp->mx);
* this is the first read call. This is the function that actually makes the
* call to the ioctl code.
*/
-long smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
+afs_int32
+smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
{
- long opcode;
+ afs_int32 opcode;
smb_ioctlProc_t *procp = NULL;
- long code;
+ afs_int32 code;
- if (ioctlp->flags & SMB_IOCTLFLAG_DATAIN) {
- ioctlp->flags &= ~SMB_IOCTLFLAG_DATAIN;
+ if (ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN) {
+ ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAIN;
/* do the call now, or fail if we didn't get an opcode, or
* enough of an opcode.
*/
- if (ioctlp->inCopied < sizeof(long))
+ if (ioctlp->ioctl.inCopied < sizeof(afs_int32))
return CM_ERROR_INVAL;
- memcpy(&opcode, ioctlp->inDatap, sizeof(long));
- ioctlp->inDatap += sizeof(long);
+ memcpy(&opcode, ioctlp->ioctl.inDatap, sizeof(afs_int32));
+ ioctlp->ioctl.inDatap += sizeof(afs_int32);
osi_Log1(afsd_logp, "Ioctl opcode 0x%x", opcode);
return CM_ERROR_BADOP;
/* otherwise, make the call */
- ioctlp->outDatap += sizeof(long); /* reserve room for return code */
+ ioctlp->ioctl.outDatap += sizeof(afs_int32); /* reserve room for return code */
code = (*procp)(ioctlp, userp);
osi_Log1(afsd_logp, "Ioctl return code 0x%x", code);
/* copy in return code */
- memcpy(ioctlp->outAllocp, &code, sizeof(long));
+ memcpy(ioctlp->ioctl.outAllocp, &code, sizeof(afs_int32));
}
return 0;
}
* a series of reads (or the very first call), then we start a new call.
* We also ensure that things are properly initialized for the start of a call.
*/
-void smb_IoctlPrepareWrite(smb_fid_t *fidp, smb_ioctl_t *ioctlp)
-{
- /* make sure the buffer(s) are allocated */
- if (!ioctlp->inAllocp) ioctlp->inAllocp = malloc(SMB_IOCTL_MAXDATA);
- if (!ioctlp->outAllocp) ioctlp->outAllocp = malloc(SMB_IOCTL_MAXDATA);
-
- /* Fixes fs la problem. We do a StrToOEM later and if this data isn't initialized we get memory issues. */
- (void) memset(ioctlp->inAllocp, 0, SMB_IOCTL_MAXDATA);
- (void) memset(ioctlp->outAllocp, 0, SMB_IOCTL_MAXDATA);
-
- /* and make sure that we've reset our state for the new incoming request */
- if (!(ioctlp->flags & SMB_IOCTLFLAG_DATAIN)) {
- ioctlp->inCopied = 0;
- ioctlp->outCopied = 0;
- ioctlp->inDatap = ioctlp->inAllocp;
- ioctlp->outDatap = ioctlp->outAllocp;
- ioctlp->flags |= SMB_IOCTLFLAG_DATAIN;
- }
-}
+void
+smb_IoctlPrepareWrite(smb_fid_t *fidp, smb_ioctl_t *ioctlp)
+{
+ /* make sure the buffer(s) are allocated */
+ if (!ioctlp->ioctl.inAllocp)
+ ioctlp->ioctl.inAllocp = malloc(SMB_IOCTL_MAXDATA);
+ if (!ioctlp->ioctl.outAllocp)
+ ioctlp->ioctl.outAllocp = malloc(SMB_IOCTL_MAXDATA);
+
+ /* Fixes fs la problem. We do a StrToOEM later and if this data isn't initialized we get memory issues. */
+ (void) memset(ioctlp->ioctl.inAllocp, 0, SMB_IOCTL_MAXDATA);
+ (void) memset(ioctlp->ioctl.outAllocp, 0, SMB_IOCTL_MAXDATA);
+
+ /* and make sure that we've reset our state for the new incoming request */
+ if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN)) {
+ ioctlp->ioctl.inCopied = 0;
+ ioctlp->ioctl.outCopied = 0;
+ ioctlp->ioctl.inDatap = ioctlp->ioctl.inAllocp;
+ ioctlp->ioctl.outDatap = ioctlp->ioctl.outAllocp;
+ ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAIN;
+ }
+}
/* called from smb_ReceiveCoreRead when we receive a read on the ioctl fid */
-long smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
- smb_packet_t *outp)
+afs_int32
+smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- smb_ioctl_t *iop;
- long count;
- long leftToCopy;
- char *op;
- long code;
- cm_user_t *userp;
+ smb_ioctl_t *iop;
+ long count;
+ afs_int32 leftToCopy;
+ char *op;
+ afs_int32 code;
+ cm_user_t *userp;
- iop = fidp->ioctlp;
- count = smb_GetSMBParm(inp, 1);
- userp = smb_GetUserFromVCP(vcp, inp);
+ iop = fidp->ioctlp;
+ count = smb_GetSMBParm(inp, 1);
+ userp = smb_GetUserFromVCP(vcp, inp);
- /* Identify tree */
+ /* Identify tree */
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
if(code) {
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
- /* turn the connection around, if required */
- code = smb_IoctlPrepareRead(fidp, iop, userp);
+ /* turn the connection around, if required */
+ code = smb_IoctlPrepareRead(fidp, iop, userp);
+
+ if (code) {
+ cm_ReleaseUser(userp);
+ return code;
+ }
+
+ leftToCopy = (afs_int32)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
+ if (count > leftToCopy)
+ count = leftToCopy;
- if (code) {
- cm_ReleaseUser(userp);
- return code;
- }
+ /* now set the parms for a read of count bytes */
+ smb_SetSMBParm(outp, 0, count);
+ smb_SetSMBParm(outp, 1, 0);
+ smb_SetSMBParm(outp, 2, 0);
+ smb_SetSMBParm(outp, 3, 0);
+ smb_SetSMBParm(outp, 4, 0);
- leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
- if (count > leftToCopy) count = leftToCopy;
-
- /* now set the parms for a read of count bytes */
- smb_SetSMBParm(outp, 0, count);
- smb_SetSMBParm(outp, 1, 0);
- smb_SetSMBParm(outp, 2, 0);
- smb_SetSMBParm(outp, 3, 0);
- smb_SetSMBParm(outp, 4, 0);
+ smb_SetSMBDataLength(outp, count+3);
- smb_SetSMBDataLength(outp, count+3);
+ op = smb_GetSMBData(outp, NULL);
+ *op++ = 1;
+ *op++ = (char)(count & 0xff);
+ *op++ = (char)((count >> 8) & 0xff);
- op = smb_GetSMBData(outp, NULL);
- *op++ = 1;
- *op++ = (char)(count & 0xff);
- *op++ = (char)((count >> 8) & 0xff);
-
- /* now copy the data into the response packet */
- memcpy(op, iop->outCopied + iop->outAllocp, count);
+ /* now copy the data into the response packet */
+ memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
- /* and adjust the counters */
- iop->outCopied += count;
-
- cm_ReleaseUser(userp);
+ /* and adjust the counters */
+ iop->ioctl.outCopied += count;
+
+ cm_ReleaseUser(userp);
- return 0;
+ return 0;
}
/* called from smb_ReceiveCoreWrite when we receive a write call on the IOCTL
* file descriptor.
*/
-long smb_IoctlWrite(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+afs_int32
+smb_IoctlWrite(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- smb_ioctl_t *iop;
- long count;
- long code;
- char *op;
- int inDataBlockCount;
+ smb_ioctl_t *iop;
+ long count;
+ afs_int32 code;
+ char *op;
+ int inDataBlockCount;
- code = 0;
- count = smb_GetSMBParm(inp, 1);
- iop = fidp->ioctlp;
+ code = 0;
+ count = smb_GetSMBParm(inp, 1);
+ iop = fidp->ioctlp;
- smb_IoctlPrepareWrite(fidp, iop);
+ smb_IoctlPrepareWrite(fidp, iop);
- op = smb_GetSMBData(inp, NULL);
- op = smb_ParseDataBlock(op, NULL, &inDataBlockCount);
+ op = smb_GetSMBData(inp, NULL);
+ op = smb_ParseDataBlock(op, NULL, &inDataBlockCount);
- if (count + iop->inCopied > SMB_IOCTL_MAXDATA) {
- code = CM_ERROR_TOOBIG;
- goto done;
- }
+ if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
+ code = CM_ERROR_TOOBIG;
+ goto done;
+ }
- /* copy data */
- memcpy(iop->inDatap + iop->inCopied, op, count);
+ /* copy data */
+ memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
- /* adjust counts */
- iop->inCopied += count;
-
-done:
- /* return # of bytes written */
- if (code == 0) {
- smb_SetSMBParm(outp, 0, count);
- smb_SetSMBDataLength(outp, 0);
- }
+ /* adjust counts */
+ iop->ioctl.inCopied += count;
- return code;
-}
+ done:
+ /* return # of bytes written */
+ if (code == 0) {
+ smb_SetSMBParm(outp, 0, count);
+ smb_SetSMBDataLength(outp, 0);
+ }
+
+ return code;
+}
/* called from smb_ReceiveV3WriteX when we receive a write call on the IOCTL
* file descriptor.
*/
-long smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+afs_int32
+smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- smb_ioctl_t *iop;
- long count;
- long code;
- char *op;
- int inDataBlockCount;
+ smb_ioctl_t *iop;
+ long count;
+ afs_int32 code;
+ char *op;
+ int inDataBlockCount;
- code = 0;
- count = smb_GetSMBParm(inp, 10);
- iop = fidp->ioctlp;
-
- smb_IoctlPrepareWrite(fidp, iop);
+ code = 0;
+ count = smb_GetSMBParm(inp, 10);
+ iop = fidp->ioctlp;
- op = inp->data + smb_GetSMBParm(inp, 11);
- inDataBlockCount = count;
-
- if (count + iop->inCopied > SMB_IOCTL_MAXDATA) {
- code = CM_ERROR_TOOBIG;
- goto done;
- }
-
- /* copy data */
- memcpy(iop->inDatap + iop->inCopied, op, count);
+ smb_IoctlPrepareWrite(fidp, iop);
+
+ op = inp->data + smb_GetSMBParm(inp, 11);
+ inDataBlockCount = count;
+
+ if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
+ code = CM_ERROR_TOOBIG;
+ goto done;
+ }
- /* adjust counts */
- iop->inCopied += count;
-
-done:
- /* return # of bytes written */
- if (code == 0) {
- smb_SetSMBParm(outp, 2, count);
- smb_SetSMBParm(outp, 3, 0); /* reserved */
- smb_SetSMBParm(outp, 4, 0); /* reserved */
- smb_SetSMBParm(outp, 5, 0); /* reserved */
- smb_SetSMBDataLength(outp, 0);
- }
+ /* copy data */
+ memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
+
+ /* adjust counts */
+ iop->ioctl.inCopied += count;
+
+ done:
+ /* return # of bytes written */
+ if (code == 0) {
+ smb_SetSMBParm(outp, 2, count);
+ smb_SetSMBParm(outp, 3, 0); /* reserved */
+ smb_SetSMBParm(outp, 4, 0); /* reserved */
+ smb_SetSMBParm(outp, 5, 0); /* reserved */
+ smb_SetSMBDataLength(outp, 0);
+ }
- return code;
-}
+ return code;
+}
/* called from V3 read to handle IOCTL descriptor reads */
-long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+afs_int32
+smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_ioctl_t *iop;
long count;
- long code;
+ afs_int32 code;
long leftToCopy;
char *op;
cm_user_t *userp;
iop->uidp = uidp;
if (uidp && uidp->unp) {
osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
- uidp->userID, userp,
- osi_LogSaveString(afsd_logp, uidp->unp->name));
+ uidp->userID, userp,
+ osi_LogSaveString(afsd_logp, uidp->unp->name));
} else {
if (uidp)
osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
return code;
}
- leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
- if (count > leftToCopy) count = leftToCopy;
+ leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
+ if (count > leftToCopy)
+ count = leftToCopy;
/* 0 and 1 are reserved for request chaining, were setup by our caller,
* and will be further filled in after we return.
smb_SetSMBDataLength(outp, count);
/* now copy the data into the response packet */
- memcpy(op, iop->outCopied + iop->outAllocp, count);
+ memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
/* and adjust the counters */
- iop->outCopied += count;
+ iop->ioctl.outCopied += count;
/* and cleanup things */
cm_ReleaseUser(userp);
}
/* called from Read Raw to handle IOCTL descriptor reads */
-long smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
- smb_packet_t *outp
- )
+afs_int32
+smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
+ smb_packet_t *outp)
{
smb_ioctl_t *iop;
long leftToCopy;
NCB *ncbp;
- long code;
+ afs_int32 code;
cm_user_t *userp;
+ smb_user_t *uidp;
iop = fidp->ioctlp;
userp = smb_GetUserFromVCP(vcp, inp);
/* Log the user */
- {
- smb_user_t *uidp;
-
- uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
- if (uidp && uidp->unp) {
- osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
- uidp->userID, userp,
- osi_LogSaveString(afsd_logp, uidp->unp->name));
- } else if (uidp) {
- osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
- uidp->userID, userp);
- } else {
- osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
- userp);
- }
- if (uidp)
- smb_ReleaseUID(uidp);
- }
+ uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ if (uidp && uidp->unp) {
+ osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
+ uidp->userID, userp,
+ osi_LogSaveString(afsd_logp, uidp->unp->name));
+ } else if (uidp) {
+ osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
+ uidp->userID, userp);
+ } else {
+ osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
+ userp);
+ }
+ if (uidp)
+ smb_ReleaseUID(uidp);
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
if (code) {
- cm_ReleaseUser(userp);
- return CM_ERROR_NOSUCHPATH;
+ code = CM_ERROR_NOSUCHPATH;
+ goto done;
}
code = smb_IoctlPrepareRead(fidp, iop, userp);
if (code) {
- cm_ReleaseUser(userp);
- return code;
+ goto done;
}
- leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
+ leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
ncbp = outp->ncbp;
memset((char *)ncbp, 0, sizeof(NCB));
/*ncbp->ncb_lana_num = smb_LANadapter;*/
ncbp->ncb_lana_num = vcp->lana;
- ncbp->ncb_buffer = iop->outCopied + iop->outAllocp;
+ ncbp->ncb_buffer = iop->ioctl.outCopied + iop->ioctl.outAllocp;
code = Netbios(ncbp);
if (code != 0)
osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
+ done:
cm_ReleaseUser(userp);
+ return code;
+}
+
+/* parse the passed-in file name and do a namei on it. If we fail,
+ * return an error code, otherwise return the vnode located in *scpp.
+ */
+#define CM_PARSE_FLAG_LITERAL 1
+
+afs_int32
+smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
+ cm_scache_t **scpp, afs_uint32 flags)
+{
+ afs_int32 code;
+ cm_scache_t *substRootp = NULL;
+ cm_scache_t *iscp = NULL;
+ char * relativePath;
+ char * lastComponent = NULL;
+ afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
+ int free_path = FALSE;
+
+ relativePath = ioctlp->ioctl.inDatap;
+ /* setup the next data value for the caller to use */
+ ioctlp->ioctl.inDatap += (long)strlen(ioctlp->ioctl.inDatap) + 1;;
+
+ osi_Log1(afsd_logp, "smb_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,relativePath));
+
+ /* This is usually the file name, but for StatMountPoint it is the path. */
+ /* ioctlp->inDatap can be either of the form:
+ * \path\.
+ * \path\file
+ * \\netbios-name\submount\path\.
+ * \\netbios-name\submount\path\file
+ */
+
+ /* We do not perform path name translation on the ioctl path data
+ * because these paths were not translated by Windows through the
+ * file system API. Therefore, they are not OEM characters but
+ * whatever the display character set is.
+ */
+
+ // TranslateExtendedChars(relativePath);
+
+ /* This is usually nothing, but for StatMountPoint it is the file name. */
+ // TranslateExtendedChars(ioctlp->ioctl.inDatap);
+
+ /* If the string starts with our UTF-8 prefix (which is the
+ sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
+ strings), we assume that the provided path is UTF-8. Otherwise
+ we have to convert the string to UTF-8, since that is what we
+ want to use everywhere else.*/
+
+ if (memcmp(relativePath, utf8_prefix, utf8_prefix_size) == 0) {
+ int len, normalized_len;
+ char * normalized_path;
+
+ /* String is UTF-8 */
+ relativePath += utf8_prefix_size;
+ ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
+
+ len = (ioctlp->ioctl.inDatap - relativePath);
+
+ normalized_len = cm_NormalizeUtf8String(relativePath, len, NULL, 0);
+
+ if (normalized_len > len) {
+ normalized_path = malloc(normalized_len);
+ free_path = TRUE;
+ } else {
+ normalized_path = relativePath;
+ }
+
+ cm_NormalizeUtf8String(relativePath, len, normalized_path, normalized_len);
+
+ if (normalized_path != relativePath)
+ relativePath = normalized_path;
+ } else {
+ /* Not a UTF-8 string */
+ /* TODO: If this is an OEM string, we should convert it to
+ UTF-8. */
+ }
+
+ if (relativePath[0] == relativePath[1] &&
+ relativePath[1] == '\\' &&
+ !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName)))
+ {
+ char shareName[256];
+ char *sharePath;
+ int shareFound, i;
+
+ /* We may have found a UNC path.
+ * If the first component is the NetbiosName,
+ * then throw out the second component (the submount)
+ * since it had better expand into the value of ioctl->tidPathp
+ */
+ char * p;
+ p = relativePath + 2 + strlen(cm_NetbiosName) + 1; /* buffer overflow vuln.? */
+ if ( !_strnicmp("all", p, 3) )
+ p += 4;
+
+ for (i = 0; *p && *p != '\\'; i++,p++ ) {
+ shareName[i] = *p;
+ }
+ p++; /* skip past trailing slash */
+ shareName[i] = 0; /* terminate string */
+
+ shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
+ if ( shareFound ) {
+ /* we found a sharename, therefore use the resulting path */
+ code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, sharePath, reqp, &substRootp);
+ free(sharePath);
+ if (code) {
+ osi_Log1(afsd_logp,"smb_ParseIoctlPath [1] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
+ return code;
+ }
+
+ lastComponent = strrchr(p, '\\');
+ if (lastComponent && (lastComponent - p) > 1 &&strlen(lastComponent) > 1) {
+ *lastComponent = '\0';
+ lastComponent++;
+
+ code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, NULL, reqp, &iscp);
+ if (code == 0)
+ code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
+ userp, NULL, reqp, scpp);
+ if (iscp)
+ cm_ReleaseSCache(iscp);
+ } else {
+ code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
+ userp, NULL, reqp, scpp);
+ }
+ cm_ReleaseSCache(substRootp);
+ if (code) {
+ osi_Log1(afsd_logp,"smb_ParseIoctlPath [2] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
+ return code;
+ }
+ } else {
+ /* otherwise, treat the name as a cellname mounted off the afs root.
+ * This requires that we reconstruct the shareName string with
+ * leading and trailing slashes.
+ */
+ p = relativePath + 2 + strlen(cm_NetbiosName) + 1;
+ if ( !_strnicmp("all", p, 3) )
+ p += 4;
+
+ shareName[0] = '/';
+ for (i = 1; *p && *p != '\\'; i++,p++ ) {
+ shareName[i] = *p;
+ }
+ p++; /* skip past trailing slash */
+ shareName[i++] = '/'; /* add trailing slash */
+ shareName[i] = 0; /* terminate string */
+
+
+ code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, shareName, reqp, &substRootp);
+ if (code) {
+ osi_Log1(afsd_logp,"smb_ParseIoctlPath [3] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
+ return code;
+ }
+
+ lastComponent = strrchr(p, '\\');
+ if (lastComponent && (lastComponent - p) > 1 &&strlen(lastComponent) > 1) {
+ *lastComponent = '\0';
+ lastComponent++;
+
+ code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, NULL, reqp, &iscp);
+ if (code == 0)
+ code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
+ userp, NULL, reqp, scpp);
+ if (iscp)
+ cm_ReleaseSCache(iscp);
+ } else {
+ code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
+ userp, NULL, reqp, scpp);
+ }
+
+ if (code) {
+ cm_ReleaseSCache(substRootp);
+ osi_Log1(afsd_logp,"smb_ParseIoctlPath code [4] 0x%x", code);
+ if (free_path)
+ free(relativePath);
+ return code;
+ }
+ }
+ } else {
+ code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, ioctlp->tidPathp, reqp, &substRootp);
+ if (code) {
+ osi_Log1(afsd_logp,"smb_ParseIoctlPath [6] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
+ return code;
+ }
+
+ lastComponent = strrchr(relativePath, '\\');
+ if (lastComponent && (lastComponent - relativePath) > 1 && strlen(lastComponent) > 1) {
+ *lastComponent = '\0';
+ lastComponent++;
+
+ code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, NULL, reqp, &iscp);
+ if (code == 0)
+ code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
+ userp, NULL, reqp, scpp);
+ if (iscp)
+ cm_ReleaseSCache(iscp);
+ } else {
+ code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | follow,
+ userp, NULL, reqp, scpp);
+ }
+ if (code) {
+ cm_ReleaseSCache(substRootp);
+ osi_Log1(afsd_logp,"smb_ParseIoctlPath [7] code 0x%x", code);
+ if (free_path)
+ free(relativePath);
+ return code;
+ }
+ }
+
+ if (substRootp)
+ cm_ReleaseSCache(substRootp);
+
+ /* and return success */
+ osi_Log1(afsd_logp,"smb_ParseIoctlPath [8] code 0x%x", code);
+
+ if (free_path)
+ free(relativePath);
+ return 0;
+}
+
+
+
+#define LEAF_SIZE 256
+/* parse the passed-in file name and do a namei on its parent. If we fail,
+ * return an error code, otherwise return the vnode located in *scpp.
+ */
+afs_int32
+smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
+ cm_scache_t **scpp, char *leafp)
+{
+ afs_int32 code;
+ char tbuffer[1024];
+ char *tp, *jp;
+ cm_scache_t *substRootp = NULL;
+ char *inpathp;
+ int free_path = FALSE;
+
+ inpathp = ioctlp->ioctl.inDatap;
+
+ /* If the string starts with our UTF-8 prefix (which is the
+ sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
+ strings), we assume that the provided path is UTF-8. Otherwise
+ we have to convert the string to UTF-8, since that is what we
+ want to use everywhere else.*/
+
+ if (memcmp(inpathp, utf8_prefix, utf8_prefix_size) == 0) {
+ int len, normalized_len;
+ char * normalized_path;
+
+ /* String is UTF-8 */
+ inpathp += utf8_prefix_size;
+ ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
+
+ len = strlen(inpathp) + 1;
+
+ normalized_len = cm_NormalizeUtf8String(inpathp, len, NULL, 0);
+
+ if (normalized_len > len) {
+ normalized_path = malloc(normalized_len);
+ free_path = TRUE;
+ } else {
+ normalized_path = inpathp;
+ }
+
+ cm_NormalizeUtf8String(inpathp, len, normalized_path, normalized_len);
+
+ if (normalized_path != inpathp)
+ inpathp = normalized_path;
+ } else {
+ /* Not a UTF-8 string */
+ /* TODO: If this is an OEM string, we should convert it to
+ UTF-8. */
+ }
+
+ StringCbCopyA(tbuffer, sizeof(tbuffer), inpathp);
+ tp = strrchr(tbuffer, '\\');
+ jp = strrchr(tbuffer, '/');
+ if (!tp)
+ tp = jp;
+ else if (jp && (tp - tbuffer) < (jp - tbuffer))
+ tp = jp;
+ if (!tp) {
+ StringCbCopyA(tbuffer, sizeof(tbuffer), "\\");
+ if (leafp)
+ StringCbCopyA(leafp, LEAF_SIZE, inpathp);
+ }
+ else {
+ *tp = 0;
+ if (leafp)
+ StringCbCopyA(leafp, LEAF_SIZE, tp+1);
+ }
+
+ if (free_path)
+ free(inpathp);
+ inpathp = NULL; /* We don't need this from this point on */
+
+ if (free_path)
+ free(inpathp);
+ inpathp = NULL; /* We don't need this from this point on */
+
+ if (tbuffer[0] == tbuffer[1] &&
+ tbuffer[1] == '\\' &&
+ !_strnicmp(cm_NetbiosName,tbuffer+2,strlen(cm_NetbiosName)))
+ {
+ char shareName[256];
+ char *sharePath;
+ int shareFound, i;
+
+ /* We may have found a UNC path.
+ * If the first component is the NetbiosName,
+ * then throw out the second component (the submount)
+ * since it had better expand into the value of ioctl->tidPathp
+ */
+ char * p;
+ p = tbuffer + 2 + strlen(cm_NetbiosName) + 1;
+ if ( !_strnicmp("all", p, 3) )
+ p += 4;
+
+ for (i = 0; *p && *p != '\\'; i++,p++ ) {
+ shareName[i] = *p;
+ }
+ p++; /* skip past trailing slash */
+ shareName[i] = 0; /* terminate string */
+
+ shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
+ if ( shareFound ) {
+ /* we found a sharename, therefore use the resulting path */
+ code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, sharePath, reqp, &substRootp);
+ free(sharePath);
+ if (code) return code;
+
+ code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, NULL, reqp, scpp);
+ cm_ReleaseSCache(substRootp);
+ if (code) return code;
+ } else {
+ /* otherwise, treat the name as a cellname mounted off the afs root.
+ * This requires that we reconstruct the shareName string with
+ * leading and trailing slashes.
+ */
+ p = tbuffer + 2 + strlen(cm_NetbiosName) + 1;
+ if ( !_strnicmp("all", p, 3) )
+ p += 4;
+
+ shareName[0] = '/';
+ for (i = 1; *p && *p != '\\'; i++,p++ ) {
+ shareName[i] = *p;
+ }
+ p++; /* skip past trailing slash */
+ shareName[i++] = '/'; /* add trailing slash */
+ shareName[i] = 0; /* terminate string */
+
+ code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, shareName, reqp, &substRootp);
+ if (code) return code;
+
+ code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, NULL, reqp, scpp);
+ cm_ReleaseSCache(substRootp);
+ if (code) return code;
+ }
+ } else {
+ code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
+ CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, ioctlp->tidPathp, reqp, &substRootp);
+ if (code) return code;
+
+ code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+ userp, NULL, reqp, scpp);
+ cm_ReleaseSCache(substRootp);
+ if (code) return code;
+ }
+
+ /* # of bytes of path */
+ code = (long)strlen(ioctlp->ioctl.inDatap) + 1;
+ ioctlp->ioctl.inDatap += code;
+
+ /* and return success */
+ return 0;
+}
+
+afs_int32
+smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ char *saveDataPtr;
+ char *tp;
+ int ticketLen;
+ char *ticket;
+ int ctSize;
+ struct ClearToken ct;
+ cm_cell_t *cellp;
+ cm_ucell_t *ucellp;
+ char *uname = NULL;
+ afs_uuid_t uuid;
+ int flags;
+ char sessionKey[8];
+ char *smbname;
+ int release_userp = 0;
+ char * wdir = NULL;
+
+ saveDataPtr = ioctlp->ioctl.inDatap;
+
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ tp = ioctlp->ioctl.inDatap;
+
+ /* ticket length */
+ memcpy(&ticketLen, tp, sizeof(ticketLen));
+ tp += sizeof(ticketLen);
+ if (ticketLen < MINKTCTICKETLEN || ticketLen > MAXKTCTICKETLEN)
+ return CM_ERROR_INVAL;
+
+ /* remember ticket and skip over it for now */
+ ticket = tp;
+ tp += ticketLen;
+
+ /* clear token size */
+ memcpy(&ctSize, tp, sizeof(ctSize));
+ tp += sizeof(ctSize);
+ if (ctSize != sizeof(struct ClearToken))
+ return CM_ERROR_INVAL;
+
+ /* clear token */
+ memcpy(&ct, tp, ctSize);
+ tp += ctSize;
+ if (ct.AuthHandle == -1)
+ ct.AuthHandle = 999; /* more rxvab compat stuff */
+
+ /* more stuff, if any */
+ if (ioctlp->ioctl.inCopied > tp - saveDataPtr) {
+ /* flags: logon flag */
+ memcpy(&flags, tp, sizeof(int));
+ tp += sizeof(int);
+
+ /* cell name */
+ cellp = cm_GetCell(tp, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
+ if (!cellp)
+ return CM_ERROR_NOSUCHCELL;
+ tp += strlen(tp) + 1;
+
+ /* user name */
+ uname = tp;
+ tp += strlen(tp) + 1;
+
+ if (flags & PIOCTL_LOGON) {
+ /* SMB user name with which to associate tokens */
+ smbname = tp;
+ osi_Log2(smb_logp,"cm_IoctlSetToken for user [%s] smbname [%s]",
+ osi_LogSaveString(smb_logp,uname), osi_LogSaveString(smb_logp,smbname));
+ fprintf(stderr, "SMB name = %s\n", smbname);
+ tp += strlen(tp) + 1;
+ } else {
+ osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]",
+ osi_LogSaveString(smb_logp, uname));
+ }
+
+ /* uuid */
+ memcpy(&uuid, tp, sizeof(uuid));
+ if (!cm_FindTokenEvent(uuid, sessionKey))
+ return CM_ERROR_INVAL;
+ } else {
+ cellp = cm_data.rootCellp;
+ osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified");
+ }
+
+ if (flags & PIOCTL_LOGON) {
+ userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname,
+ SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
+ release_userp = 1;
+ }
+
+ /* store the token */
+ lock_ObtainMutex(&userp->mx);
+ ucellp = cm_GetUCell(userp, cellp);
+ osi_Log1(smb_logp,"cm_IoctlSetToken ucellp %lx", ucellp);
+ ucellp->ticketLen = ticketLen;
+ if (ucellp->ticketp)
+ free(ucellp->ticketp); /* Discard old token if any */
+ ucellp->ticketp = malloc(ticketLen);
+ memcpy(ucellp->ticketp, ticket, ticketLen);
+ /*
+ * Get the session key from the RPC, rather than from the pioctl.
+ */
+ /*
+ memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey));
+ */
+ memcpy(ucellp->sessionKey.data, sessionKey, sizeof(sessionKey));
+ ucellp->kvno = ct.AuthHandle;
+ ucellp->expirationTime = ct.EndTimestamp;
+ ucellp->gen++;
+#ifdef QUERY_AFSID
+ ucellp->uid = ANONYMOUSID;
+#endif
+ if (uname) {
+ StringCbCopyA(ucellp->userName, MAXKTCNAMELEN, uname);
+#ifdef QUERY_AFSID
+ cm_UsernameToId(uname, ucellp, &ucellp->uid);
+#endif
+ }
+ ucellp->flags |= CM_UCELLFLAG_RXKAD;
+ lock_ReleaseMutex(&userp->mx);
+
+ if (flags & PIOCTL_LOGON) {
+ ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
+ }
+
+ cm_ResetACLCache(userp);
+
+ if (release_userp)
+ cm_ReleaseUser(userp);
+
+ return 0;
+}
+
+
+
+afs_int32
+smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
+{
+ smb_user_t *uidp = ioctlp->uidp;
+
+ if (uidp && uidp->unp) {
+ memcpy(ioctlp->ioctl.outDatap, uidp->unp->name, strlen(uidp->unp->name));
+ ioctlp->ioctl.outDatap += strlen(uidp->unp->name);
+ }
+
+ return 0;
+}
+
+afs_int32
+smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
+{
+ cm_scache_t *scp;
+ afs_int32 code;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlGetACL(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+ return code;
+}
+
+afs_int32
+smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
+{
+ cm_scache_t *scp;
+ afs_int32 code;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlSetACL(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+ return code;
+}
+
+afs_int32
+smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlGetFileCellName(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
+
+ return cm_IoctlFlushAllVolumes(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlFlushVolume(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlFlushFile(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+ return code;
+}
+
+afs_int32
+smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, 0);
+ if (code) return code;
+
+ code = cm_IoctlSetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlGetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t * optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ if (code)
+ return code;
+
+ code = cm_IoctlGetFid(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t * optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlGetFileType(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlGetOwner(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlWhereIs(&ioctlp->ioctl, userp, scp, &req);
+
+ cm_ReleaseSCache(scp);
+
+ return code;
+}
+
+
+afs_int32
+smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *dscp;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+ if (code)
+ return code;
+
+ code = cm_IoctlStatMountPoint(&ioctlp->ioctl, userp, dscp, &req);
+
+ cm_ReleaseSCache(dscp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *dscp;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+ if (code)
+ return code;
+
+ code = cm_IoctlDeleteMountPoint(&ioctlp->ioctl, userp, dscp, &req);
+
+ cm_ReleaseSCache(dscp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
+
+ return cm_IoctlCheckServers(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ /* we don't print anything superfluous, so we don't support the gag call */
+ return CM_ERROR_INVAL;
+}
+
+afs_int32
+smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlCheckVolumes(&ioctlp->ioctl, userp);
+}
+
+afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlSetCacheSize(&ioctlp->ioctl, userp);
+}
+
+
+afs_int32
+smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlTraceControl(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlGetCacheParms(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlGetCell(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlNewCell(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlGetWsCell(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlSysName(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlGetCellStatus(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlSetCellStatus(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlSetSPrefs(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlGetSPrefs(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ /* we ignore default asynchrony since we only have one way
+ * of doing this today.
+ */
return 0;
+}
+
+afs_int32
+smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *dscp;
+ char leaf[LEAF_SIZE];
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
+ if (code)
+ return code;
+
+ code = cm_IoctlCreateMountPoint(&ioctlp->ioctl, userp, dscp, &req, leaf);
+
+ cm_ReleaseSCache(dscp);
+ return code;
+}
+
+afs_int32
+smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *dscp;
+ char leaf[LEAF_SIZE];
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
+ if (code) return code;
+
+ code = cm_IoctlSymlink(&ioctlp->ioctl, userp, dscp, &req, leaf);
+
+ cm_ReleaseSCache(dscp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *dscp;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+ if (code) return code;
+
+ code = cm_IoctlListlink(&ioctlp->ioctl, userp, dscp, &req);
+
+ cm_ReleaseSCache(dscp);
+ return code;
+}
+
+afs_int32
+smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{/*CHECK FOR VALID SYMLINK*/
+ afs_int32 code;
+ cm_scache_t *dscp;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+ if (code) return code;
+
+ code = cm_IoctlIslink(&ioctlp->ioctl, userp, dscp, &req);
+
+ cm_ReleaseSCache(dscp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *dscp;
+ cm_req_t req;
+
+ cm_InitReq(&req);
+
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
+ if (code) return code;
+
+ code = cm_IoctlDeletelink(&ioctlp->ioctl, userp, dscp, &req);
+
+ cm_ReleaseSCache(dscp);
+
+ return code;
+}
+
+afs_int32
+smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlGetTokenIter(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlGetToken(&ioctlp->ioctl, userp);
+}
+
+
+afs_int32
+smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlDelToken(&ioctlp->ioctl, userp);
+}
+
+
+afs_int32
+smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlDelAllToken(&ioctlp->ioctl, userp);
+}
+
+
+afs_int32
+smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlMakeSubmount(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlGetRxkcrypt(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlSetRxkcrypt(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlRxStatProcess(&ioctlp->ioctl, userp);
+}
+
+
+afs_int32
+smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlRxStatPeer(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlUnicodeControl(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlUUIDControl(&ioctlp->ioctl, userp);
+}
+
+
+afs_int32
+smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlMemoryDump(&ioctlp->ioctl, userp);
+}
+
+afs_int32
+smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ afs_int32 code;
+ cm_scache_t *scp;
+ cm_req_t req;
+ cm_ioctlQueryOptions_t *optionsp;
+ afs_uint32 flags = 0;
+
+ cm_InitReq(&req);
+
+ optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
+ flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
+
+ if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
+ cm_fid_t fid;
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+ cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
+ optionsp->fid.vnode, optionsp->fid.unique);
+ code = cm_GetSCache(&fid, &scp, userp, &req);
+ } else {
+ code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
+ }
+ if (code)
+ return code;
+
+ code = cm_IoctlPathAvailability(&ioctlp->ioctl, userp, scp, &req);
+ cm_ReleaseSCache(scp);
+ return code;
+}
+
+afs_int32
+smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+ cm_SkipIoctlPath(&ioctlp->ioctl);
+
+ return cm_IoctlVolStatTest(&ioctlp->ioctl, userp);
}
#ifndef __SMB_IOCTL_H_ENV__
#define __SMB_IOCTL_H_ENV__ 1
+#include <cm_ioctl.h>
+
/* magic file name for ioctl opens */
-#define SMB_IOCTL_FILENAME "\\_._AFS_IOCTL_._" /* double backslashes for C compiler */
-#define SMB_IOCTL_FILENAME_NOSLASH "_._AFS_IOCTL_._"
+#define SMB_IOCTL_FILENAME CM_IOCTL_FILENAME
+#define SMB_IOCTL_FILENAME_NOSLASH CM_IOCTL_FILENAME_NOSLASH
/* max parms for ioctl, in either direction */
-#define SMB_IOCTL_MAXDATA 8192*2
+#define SMB_IOCTL_MAXDATA CM_IOCTL_MAXDATA
+#define SMB_IOCTL_MAXPROCS CM_IOCTL_MAXPROCS
+
+struct smb_fid;
+struct smb_user;
+struct smb_vc;
+
+/* ioctl parameter, while being assembled and/or processed */
+typedef struct smb_ioctl {
+ /* fid pointer */
+ struct smb_fid *fidp;
+
+ /* uid pointer */
+ struct smb_user *uidp;
+
+ /* pathname associated with the Tree ID */
+ char *tidPathp;
-#define SMB_IOCTL_MAXPROCS 64 /* max # of calls */
+ /* prefix for subst drives */
+ cm_space_t *prefix;
+
+ cm_ioctl_t ioctl;
+} smb_ioctl_t;
/* procedure implementing an ioctl */
typedef long (smb_ioctlProc_t)(smb_ioctl_t *, struct cm_user *userp);
extern void smb_InitIoctl(void);
-extern void smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix);
+extern void smb_SetupIoctlFid(struct smb_fid *fidp, cm_space_t *prefix);
+
+extern afs_int32 smb_IoctlRead(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, struct smb_packet *outp);
+
+extern afs_int32 smb_IoctlWrite(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, struct smb_packet *outp);
+
+extern afs_int32 smb_IoctlV3Write(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, struct smb_packet *outp);
+
+extern afs_int32 smb_IoctlV3Read(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp, struct smb_packet *outp);
+
+extern afs_int32 smb_IoctlReadRaw(struct smb_fid *fidp, struct smb_vc *vcp, struct smb_packet *inp,
+ struct smb_packet *outp);
+
+extern long smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32
+smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **scpp, afs_uint32 flags);
+
+extern afs_int32
+smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp, cm_scache_t **scpp, char *leafp);
+
+extern afs_int32
+smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp);
+
+extern afs_int32
+smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetFileCellName(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlFlushAllVolumes(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlFlushVolume(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlFlushFile(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlSetVolumeStatus(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetVolumeStatus(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetFid(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetOwner(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlWhereIs(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlStatMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlDeleteMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlCheckServers(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGag(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlCheckVolumes(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlSetCacheSize(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetCacheParms(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlNewCell(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);
+
+extern afs_int32 smb_IoctlGetCellStatus(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlSetCellStatus(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlSetSPrefs(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetSPrefs(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlStoreBehind(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlCreateMountPoint(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+
+extern afs_int32 cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+
+extern afs_int32 cm_FlushVolume(cm_user_t *, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume);
+
+extern afs_int32 cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+
+extern afs_int32 smb_IoctlTraceControl(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlSetToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetTokenIter(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlDelToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlDelAllToken(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlSymlink(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlIslink(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlListlink(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlDeletelink(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlGetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlSetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlShutdown(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlFreemountAddCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlFreemountRemoveCell(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlMemoryDump(smb_ioctl_t *ioctlp, cm_user_t *userp);
+
+extern afs_int32 smb_IoctlRxStatProcess(smb_ioctl_t *ioctlp, cm_user_t *userp);
-extern long smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp);
+extern afs_int32 smb_IoctlRxStatPeer(smb_ioctl_t *ioctlp, cm_user_t *userp);
-extern long smb_IoctlWrite(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp);
+extern afs_int32 smb_IoctlUUIDControl(struct smb_ioctl * ioctlp, struct cm_user *userp);
-extern long smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp);
+extern afs_int32 smb_IoctlPathAvailability(struct smb_ioctl * ioctlp, struct cm_user *userp);
-extern long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp);
+extern afs_int32 smb_IoctlGetFileType(smb_ioctl_t *ioctlp, cm_user_t *userp);
-extern long smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
- smb_packet_t *outp);
+extern afs_int32 smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp);
-extern long smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp);
+extern afs_int32 smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user * userp);
#endif /* __SMB_IOCTL_H_ENV__ */