2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
32 #include "afs/afsrpc.h"
35 smb_ioctlProc_t *smb_ioctlProcsp[SMB_IOCTL_MAXPROCS];
41 for (i=0; i<SMB_IOCTL_MAXPROCS; i++)
42 smb_ioctlProcsp[i] = NULL;
44 smb_ioctlProcsp[VIOCGETAL] = smb_IoctlGetACL;
45 smb_ioctlProcsp[VIOC_FILE_CELL_NAME] = smb_IoctlGetFileCellName;
46 smb_ioctlProcsp[VIOCSETAL] = smb_IoctlSetACL;
47 smb_ioctlProcsp[VIOC_FLUSHVOLUME] = smb_IoctlFlushVolume;
48 smb_ioctlProcsp[VIOCFLUSH] = smb_IoctlFlushFile;
49 smb_ioctlProcsp[VIOCSETVOLSTAT] = smb_IoctlSetVolumeStatus;
50 smb_ioctlProcsp[VIOCGETVOLSTAT] = smb_IoctlGetVolumeStatus;
51 smb_ioctlProcsp[VIOCWHEREIS] = smb_IoctlWhereIs;
52 smb_ioctlProcsp[VIOC_AFS_STAT_MT_PT] = smb_IoctlStatMountPoint;
53 smb_ioctlProcsp[VIOC_AFS_DELETE_MT_PT] = smb_IoctlDeleteMountPoint;
54 smb_ioctlProcsp[VIOCCKSERV] = smb_IoctlCheckServers;
55 smb_ioctlProcsp[VIOC_GAG] = smb_IoctlGag;
56 smb_ioctlProcsp[VIOCCKBACK] = smb_IoctlCheckVolumes;
57 smb_ioctlProcsp[VIOCSETCACHESIZE] = smb_IoctlSetCacheSize;
58 smb_ioctlProcsp[VIOCGETCACHEPARMS] = smb_IoctlGetCacheParms;
59 smb_ioctlProcsp[VIOCGETCELL] = smb_IoctlGetCell;
60 smb_ioctlProcsp[VIOCNEWCELL] = smb_IoctlNewCell;
61 smb_ioctlProcsp[VIOC_GET_WS_CELL] = smb_IoctlGetWsCell;
62 smb_ioctlProcsp[VIOC_AFS_SYSNAME] = smb_IoctlSysName;
63 smb_ioctlProcsp[VIOC_GETCELLSTATUS] = smb_IoctlGetCellStatus;
64 smb_ioctlProcsp[VIOC_SETCELLSTATUS] = smb_IoctlSetCellStatus;
65 smb_ioctlProcsp[VIOC_SETSPREFS] = smb_IoctlSetSPrefs;
66 smb_ioctlProcsp[VIOC_GETSPREFS] = smb_IoctlGetSPrefs;
67 smb_ioctlProcsp[VIOC_STOREBEHIND] = smb_IoctlStoreBehind;
68 smb_ioctlProcsp[VIOC_AFS_CREATE_MT_PT] = smb_IoctlCreateMountPoint;
69 smb_ioctlProcsp[VIOC_TRACECTL] = smb_IoctlTraceControl;
70 smb_ioctlProcsp[VIOCSETTOK] = smb_IoctlSetToken;
71 smb_ioctlProcsp[VIOCGETTOK] = smb_IoctlGetTokenIter;
72 smb_ioctlProcsp[VIOCNEWGETTOK] = smb_IoctlGetToken;
73 smb_ioctlProcsp[VIOCDELTOK] = smb_IoctlDelToken;
74 smb_ioctlProcsp[VIOCDELALLTOK] = smb_IoctlDelAllToken;
75 smb_ioctlProcsp[VIOC_SYMLINK] = smb_IoctlSymlink;
76 smb_ioctlProcsp[VIOC_LISTSYMLINK] = smb_IoctlListlink;
77 smb_ioctlProcsp[VIOC_DELSYMLINK] = smb_IoctlDeletelink;
78 smb_ioctlProcsp[VIOC_MAKESUBMOUNT] = smb_IoctlMakeSubmount;
79 smb_ioctlProcsp[VIOC_GETRXKCRYPT] = smb_IoctlGetRxkcrypt;
80 smb_ioctlProcsp[VIOC_SETRXKCRYPT] = smb_IoctlSetRxkcrypt;
81 smb_ioctlProcsp[VIOC_ISSYMLINK] = smb_IoctlIslink;
82 smb_ioctlProcsp[VIOC_TRACEMEMDUMP] = smb_IoctlMemoryDump;
83 smb_ioctlProcsp[VIOC_ISSYMLINK] = smb_IoctlIslink;
84 smb_ioctlProcsp[VIOC_FLUSHALL] = smb_IoctlFlushAllVolumes;
85 smb_ioctlProcsp[VIOCGETFID] = smb_IoctlGetFid;
86 smb_ioctlProcsp[VIOCGETOWNER] = smb_IoctlGetOwner;
87 smb_ioctlProcsp[VIOC_RXSTAT_PROC] = smb_IoctlRxStatProcess;
88 smb_ioctlProcsp[VIOC_RXSTAT_PEER] = smb_IoctlRxStatPeer;
89 smb_ioctlProcsp[VIOC_UUIDCTL] = smb_IoctlUUIDControl;
90 smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = smb_IoctlPathAvailability;
91 smb_ioctlProcsp[VIOC_GETFILETYPE] = smb_IoctlGetFileType;
92 smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = smb_IoctlVolStatTest;
93 smb_ioctlProcsp[VIOC_UNICODECTL] = smb_IoctlUnicodeControl;
94 smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner;
95 smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup;
96 smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2;
97 smb_ioctlProcsp[VIOC_SETUNIXMODE] = smb_IoctlSetUnixMode;
98 smb_ioctlProcsp[VIOC_GETUNIXMODE] = smb_IoctlGetUnixMode;
99 smb_ioctlProcsp[VIOC_SETVERIFYDATA] = smb_IoctlSetVerifyData;
100 smb_ioctlProcsp[VIOC_GETVERIFYDATA] = smb_IoctlGetVerifyData;
101 smb_ioctlProcsp[VIOC_GETCALLERACCESS] = smb_IoctlGetCallerAccess;
104 /* called to make a fid structure into an IOCTL fid structure */
106 smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
109 cm_space_t *copyPrefix;
111 lock_ObtainMutex(&fidp->mx);
112 fidp->flags |= SMB_FID_IOCTL;
113 fidp->scp = &cm_data.fakeSCache;
114 cm_HoldSCache(fidp->scp);
115 if (fidp->ioctlp == NULL) {
116 iop = malloc(sizeof(*iop));
117 memset(iop, 0, sizeof(*iop));
122 copyPrefix = cm_GetSpace();
123 memcpy(copyPrefix->data, prefix->data, CM_UTILS_SPACESIZE);
124 fidp->ioctlp->prefix = copyPrefix;
126 lock_ReleaseMutex(&fidp->mx);
129 /* called when we receive a read call, does the send of the received data if
130 * this is the first read call. This is the function that actually makes the
131 * call to the ioctl code.
134 smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
137 smb_ioctlProc_t *procp = NULL;
140 if (ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN) {
141 ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAIN;
142 ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAOUT;
144 /* do the call now, or fail if we didn't get an opcode, or
145 * enough of an opcode.
147 if (ioctlp->ioctl.inCopied < sizeof(afs_int32))
148 return CM_ERROR_INVAL;
149 memcpy(&opcode, ioctlp->ioctl.inDatap, sizeof(afs_int32));
150 ioctlp->ioctl.inDatap += sizeof(afs_int32);
152 osi_Log1(afsd_logp, "smb_IoctlPrepareRead opcode 0x%x", opcode);
153 /* check for opcode out of bounds */
154 if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS) {
155 osi_Log0(afsd_logp, "smb_IoctlPrepareRead - invalid opcode");
156 return CM_ERROR_TOOBIG;
159 /* check for no such proc */
160 procp = smb_ioctlProcsp[opcode];
162 osi_Log0(afsd_logp, "smb_IoctlPrepareRead - unassigned opcode");
163 return CM_ERROR_INVAL;
165 /* otherwise, make the call */
166 ioctlp->ioctl.outDatap += sizeof(afs_int32); /* reserve room for return code */
167 code = (*procp)(ioctlp, userp, pflags);
168 osi_Log1(afsd_logp, "smb_IoctlPrepareRead operation returns code 0x%x", code);
170 /* copy in return code */
171 memcpy(ioctlp->ioctl.outAllocp, &code, sizeof(afs_int32));
172 } else if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAOUT)) {
173 osi_Log0(afsd_logp, "Ioctl invalid state - dataout expected");
174 return CM_ERROR_INVAL;
180 /* called when we receive a write call. If this is the first write call after
181 * a series of reads (or the very first call), then we start a new call.
182 * We also ensure that things are properly initialized for the start of a call.
185 smb_IoctlPrepareWrite(smb_fid_t *fidp, smb_ioctl_t *ioctlp)
187 /* make sure the buffer(s) are allocated */
188 if (!ioctlp->ioctl.inAllocp)
189 ioctlp->ioctl.inAllocp = malloc(SMB_IOCTL_MAXDATA);
190 if (!ioctlp->ioctl.outAllocp)
191 ioctlp->ioctl.outAllocp = malloc(SMB_IOCTL_MAXDATA);
193 /* Fixes fs la problem. We do a StrToOEM later and if this data isn't initialized we get memory issues. */
194 (void) memset(ioctlp->ioctl.inAllocp, 0, SMB_IOCTL_MAXDATA);
195 (void) memset(ioctlp->ioctl.outAllocp, 0, SMB_IOCTL_MAXDATA);
197 /* and make sure that we've reset our state for the new incoming request */
198 if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN)) {
199 ioctlp->ioctl.inCopied = 0;
200 ioctlp->ioctl.outCopied = 0;
201 ioctlp->ioctl.inDatap = ioctlp->ioctl.inAllocp;
202 ioctlp->ioctl.outDatap = ioctlp->ioctl.outAllocp;
203 ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAIN;
204 ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAOUT;
208 /* called from smb_ReceiveCoreRead when we receive a read on the ioctl fid */
210 smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
214 afs_int32 leftToCopy;
218 cm_user_t *userp = NULL;
223 count = smb_GetSMBParm(inp, 1);
225 /* Get the user and determine if it is the local machine account */
226 smbp = (smb_t *) inp;
227 uidp = smb_FindUID(vcp, smbp->uid, 0);
230 osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
232 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
234 osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
235 uidp->userID, userp);
237 isSystem = smb_userIsLocalSystem(uidp);
238 userp = smb_GetUserFromUID(uidp);
240 osi_Log3(afsd_logp, "smb_IoctlRead uid %d user %x name %s",
242 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
244 osi_Log2(afsd_logp, "smb_IoctlRead uid %d user %x no name",
245 uidp->userID, userp);
247 smb_ReleaseUID(uidp);
249 osi_Log1(afsd_logp, "smb_IoctlRead no uid user %x no name", userp);
250 return CM_ERROR_BADSMB;
254 userp = cm_rootUserp;
259 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
261 cm_ReleaseUser(userp);
262 return CM_ERROR_NOSUCHPATH;
265 /* turn the connection around, if required */
266 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
269 cm_ReleaseUser(userp);
273 leftToCopy = (afs_int32)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
274 if (leftToCopy < 0) {
275 osi_Log0(afsd_logp, "smb_IoctlRead leftToCopy went negative");
276 cm_ReleaseUser(userp);
277 return CM_ERROR_INVAL;
279 if (count > leftToCopy)
282 /* now set the parms for a read of count bytes */
283 smb_SetSMBParm(outp, 0, count);
284 smb_SetSMBParm(outp, 1, 0);
285 smb_SetSMBParm(outp, 2, 0);
286 smb_SetSMBParm(outp, 3, 0);
287 smb_SetSMBParm(outp, 4, 0);
289 smb_SetSMBDataLength(outp, count+3);
291 op = smb_GetSMBData(outp, NULL);
293 *op++ = (char)(count & 0xff);
294 *op++ = (char)((count >> 8) & 0xff);
296 /* now copy the data into the response packet */
297 memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
299 /* and adjust the counters */
300 iop->ioctl.outCopied += count;
302 cm_ReleaseUser(userp);
307 /* called from smb_ReceiveCoreWrite when we receive a write call on the IOCTL
311 smb_IoctlWrite(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
317 int inDataBlockCount;
320 count = smb_GetSMBParm(inp, 1);
323 smb_IoctlPrepareWrite(fidp, iop);
325 op = smb_GetSMBData(inp, NULL);
326 op = smb_ParseDataBlock(op, NULL, &inDataBlockCount);
328 if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
329 code = CM_ERROR_TOOBIG;
334 memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
337 iop->ioctl.inCopied += count;
340 /* return # of bytes written */
342 smb_SetSMBParm(outp, 0, count);
343 smb_SetSMBDataLength(outp, 0);
349 /* called from smb_ReceiveV3WriteX when we receive a write call on the IOCTL
353 smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
359 int inDataBlockCount;
362 count = smb_GetSMBParm(inp, 10);
365 smb_IoctlPrepareWrite(fidp, iop);
367 op = inp->data + smb_GetSMBParm(inp, 11);
368 inDataBlockCount = count;
370 if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
371 code = CM_ERROR_TOOBIG;
376 memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
379 iop->ioctl.inCopied += count;
382 /* return # of bytes written */
384 smb_SetSMBParm(outp, 2, count);
385 smb_SetSMBParm(outp, 3, 0); /* reserved */
386 smb_SetSMBParm(outp, 4, 0); /* reserved */
387 smb_SetSMBParm(outp, 5, 0); /* reserved */
388 smb_SetSMBDataLength(outp, 0);
395 /* called from V3 read to handle IOCTL descriptor reads */
397 smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
400 unsigned short count;
409 count = smb_GetSMBParm(inp, 5);
411 /* Get the user and determine if it is the local machine account */
412 uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
414 isSystem = smb_userIsLocalSystem(uidp);
415 userp = smb_GetUserFromUID(uidp);
417 osi_Log3(afsd_logp, "smb_IoctlV3Read uid %d user %x name %s",
419 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
421 osi_Log2(afsd_logp, "smb_IoctlV3Read uid %d user %x no name",
422 uidp->userID, userp);
425 osi_Log0(afsd_logp, "smb_IoctlV3Read no uid");
426 return CM_ERROR_BADSMB;
430 userp = cm_rootUserp;
436 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
439 smb_ReleaseUID(uidp);
440 cm_ReleaseUser(userp);
441 return CM_ERROR_NOSUCHPATH;
444 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
447 smb_ReleaseUID(uidp);
450 cm_ReleaseUser(userp);
454 leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
455 if (leftToCopy < 0) {
456 osi_Log0(afsd_logp, "smb_IoctlV3Read leftToCopy went negative");
457 cm_ReleaseUser(userp);
458 return CM_ERROR_INVAL;
460 if (count > leftToCopy)
461 count = (unsigned short)leftToCopy;
463 /* 0 and 1 are reserved for request chaining, were setup by our caller,
464 * and will be further filled in after we return.
466 smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */
467 smb_SetSMBParm(outp, 3, 0); /* resvd */
468 smb_SetSMBParm(outp, 4, 0); /* resvd */
469 smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */
470 /* fill in #6 when we have all the parameters' space reserved */
471 smb_SetSMBParm(outp, 7, 0); /* resv'd */
472 smb_SetSMBParm(outp, 8, 0); /* resv'd */
473 smb_SetSMBParm(outp, 9, 0); /* resv'd */
474 smb_SetSMBParm(outp, 10, 0); /* resv'd */
475 smb_SetSMBParm(outp, 11, 0); /* reserved */
477 /* get op ptr after putting in the last parm, since otherwise we don't
478 * know where the data really is.
480 op = smb_GetSMBData(outp, NULL);
482 /* now fill in offset from start of SMB header to first data byte (to op) */
483 smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
485 /* set the packet data length the count of the # of bytes */
486 smb_SetSMBDataLength(outp, count);
488 /* now copy the data into the response packet */
489 memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
491 /* and adjust the counters */
492 iop->ioctl.outCopied += count;
494 /* and cleanup things */
495 cm_ReleaseUser(userp);
500 /* called from Read Raw to handle IOCTL descriptor reads */
502 smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
515 /* Get the user and determine if it is the local machine account */
516 uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
518 isSystem = smb_userIsLocalSystem(uidp);
519 userp = smb_GetUserFromUID(uidp);
521 osi_Log3(afsd_logp, "smb_IoctlRawRead uid %d user %x name %s",
523 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
525 osi_Log2(afsd_logp, "smb_IoctlRawRead uid %d user %x no name",
526 uidp->userID, userp);
528 smb_ReleaseUID(uidp);
530 osi_Log0(afsd_logp, "smb_IoctlRawRead no uid");
534 userp = cm_rootUserp;
538 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
540 code = CM_ERROR_NOSUCHPATH;
544 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
549 leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
550 if (leftToCopy < 0) {
551 osi_Log0(afsd_logp, "smb_IoctlReadRaw leftToCopy went negative");
552 code = CM_ERROR_INVAL;
557 memset(ncbp, 0, sizeof(NCB));
559 ncbp->ncb_length = (unsigned short) leftToCopy;
560 ncbp->ncb_lsn = (unsigned char) vcp->lsn;
561 ncbp->ncb_command = NCBSEND;
562 /*ncbp->ncb_lana_num = smb_LANadapter;*/
563 ncbp->ncb_lana_num = vcp->lana;
565 ncbp->ncb_buffer = iop->ioctl.outCopied + iop->ioctl.outAllocp;
566 code = Netbios(ncbp);
569 osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
572 cm_ReleaseUser(userp);
577 /* parse the passed-in file name and do a namei on it. If we fail,
578 * return an error code, otherwise return the vnode located in *scpp.
580 #define CM_PARSE_FLAG_LITERAL 1
583 smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
584 cm_scache_t **scpp, afs_uint32 flags)
587 cm_scache_t *substRootp = NULL;
588 cm_scache_t *iscp = NULL;
590 clientchar_t *relativePath = NULL;
591 clientchar_t *lastComponent = NULL;
592 afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
594 inPath = ioctlp->ioctl.inDatap;
595 /* setup the next data value for the caller to use */
596 ioctlp->ioctl.inDatap += (long)strlen(ioctlp->ioctl.inDatap) + 1;
598 osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,inPath));
600 /* This is usually the file name, but for StatMountPoint it is the path. */
601 /* ioctlp->ioctl.inDatap can be either of the form:
604 * \\netbios-name\submount\path\.
605 * \\netbios-name\submount\path\file
608 /* We do not perform path name translation on the ioctl path data
609 * because these paths were not translated by Windows through the
610 * file system API. Therefore, they are not OEM characters but
611 * whatever the display character set is.
614 // TranslateExtendedChars(relativePath);
616 /* This is usually nothing, but for StatMountPoint it is the file name. */
617 // TranslateExtendedChars(ioctlp->ioctl.inDatap);
619 /* If the string starts with our UTF-8 prefix (which is the
620 sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
621 strings), we assume that the provided path is UTF-8. Otherwise
622 we have to convert the string to UTF-8, since that is what we
623 want to use everywhere else.*/
625 if (memcmp(inPath, utf8_prefix, utf8_prefix_size) == 0) {
626 /* String is UTF-8 */
627 inPath += utf8_prefix_size;
628 ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
630 relativePath = cm_Utf8ToClientStringAlloc(inPath, -1, NULL);
634 /* Not a UTF-8 string */
635 /* TODO: If this is an OEM string, we should convert it to
637 if (smb_StoreAnsiFilenames) {
638 cch = cm_AnsiToClientString(inPath, -1, NULL, 0);
642 relativePath = malloc(cch * sizeof(clientchar_t));
643 cm_AnsiToClientString(inPath, -1, relativePath, cch);
645 TranslateExtendedChars(inPath);
647 cch = cm_OemToClientString(inPath, -1, NULL, 0);
651 relativePath = malloc(cch * sizeof(clientchar_t));
652 cm_OemToClientString(inPath, -1, relativePath, cch);
656 if (relativePath[0] == relativePath[1] &&
657 relativePath[1] == '\\' &&
658 !cm_ClientStrCmpNI(cm_NetbiosNameC, relativePath+2,
659 (int)cm_ClientStrLen(cm_NetbiosNameC)))
661 clientchar_t shareName[256];
662 clientchar_t *sharePath;
665 /* We may have found a UNC path.
666 * If the first component is the NetbiosName,
667 * then throw out the second component (the submount)
668 * since it had better expand into the value of ioctl->tidPathp
671 p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1; /* buffer overflow vuln.? */
672 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
675 for (i = 0; *p && *p != '\\'; i++,p++ ) {
678 p++; /* skip past trailing slash */
679 shareName[i] = 0; /* terminate string */
681 shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
683 /* we found a sharename, therefore use the resulting path */
684 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
685 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
686 userp, sharePath, reqp, &substRootp);
689 osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code);
695 lastComponent = cm_ClientStrRChr(p, '\\');
696 if (lastComponent && (lastComponent - p) > 1 &&
697 cm_ClientStrLen(lastComponent) > 1) {
698 *lastComponent = '\0';
701 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
702 userp, NULL, reqp, &iscp);
704 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
705 userp, NULL, reqp, scpp);
707 cm_ReleaseSCache(iscp);
709 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
710 userp, NULL, reqp, scpp);
712 cm_ReleaseSCache(substRootp);
714 osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code);
720 /* otherwise, treat the name as a cellname mounted off the afs root.
721 * This requires that we reconstruct the shareName string with
722 * leading and trailing slashes.
724 p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
725 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
729 for (i = 1; *p && *p != '\\'; i++,p++ ) {
732 p++; /* skip past trailing slash */
733 shareName[i++] = '/'; /* add trailing slash */
734 shareName[i] = 0; /* terminate string */
737 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
738 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
739 userp, shareName, reqp, &substRootp);
741 osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code);
747 lastComponent = cm_ClientStrRChr(p, L'\\');
748 if (lastComponent && (lastComponent - p) > 1) {
750 if (cm_ClientStrLen(lastComponent) == 1) {
751 *lastComponent = '\0';
752 lastComponent = L".";
754 *lastComponent = L'\0';
758 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
759 userp, NULL, reqp, &iscp);
761 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
762 userp, NULL, reqp, scpp);
764 cm_ReleaseSCache(iscp);
766 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
767 userp, NULL, reqp, scpp);
771 cm_ReleaseSCache(substRootp);
772 osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code);
779 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
780 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
781 userp, ioctlp->tidPathp, reqp, &substRootp);
783 osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code);
789 lastComponent = cm_ClientStrRChr(relativePath, '\\');
790 if (lastComponent && (lastComponent - relativePath) > 1 &&
791 cm_ClientStrLen(lastComponent) > 1) {
792 *lastComponent = '\0';
795 code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
796 userp, NULL, reqp, &iscp);
798 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
799 userp, NULL, reqp, scpp);
801 cm_ReleaseSCache(iscp);
803 code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | follow,
804 userp, NULL, reqp, scpp);
807 cm_ReleaseSCache(substRootp);
808 osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code);
816 cm_ReleaseSCache(substRootp);
821 /* Ensure that the status object is up to date */
822 lock_ObtainWrite(&(*scpp)->rw);
823 code = cm_SyncOp( *scpp, NULL, userp, reqp, 0,
824 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
826 cm_SyncOpDone( *scpp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
827 lock_ReleaseWrite(&(*scpp)->rw);
829 /* and return success */
830 osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
836 #define LEAF_SIZE 256
837 /* parse the passed-in file name and do a namei on its parent. If we fail,
838 * return an error code, otherwise return the vnode located in *scpp.
841 smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
842 cm_scache_t **scpp, clientchar_t *leafp)
845 clientchar_t tbuffer[1024];
846 clientchar_t *tp, *jp;
847 cm_scache_t *substRootp = NULL;
848 clientchar_t *inpathp = NULL;
851 inpathdatap = ioctlp->ioctl.inDatap;
853 /* If the string starts with our UTF-8 prefix (which is the
854 sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
855 strings), we assume that the provided path is UTF-8. Otherwise
856 we have to convert the string to UTF-8, since that is what we
857 want to use everywhere else.*/
859 if (memcmp(inpathdatap, utf8_prefix, utf8_prefix_size) == 0) {
861 /* String is UTF-8 */
862 inpathdatap += utf8_prefix_size;
863 ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
865 inpathp = cm_Utf8ToClientStringAlloc(inpathdatap, -1, NULL);
869 /* Not a UTF-8 string */
870 /* TODO: If this is an OEM string, we should convert it to
872 if (smb_StoreAnsiFilenames) {
873 cch = cm_AnsiToClientString(inpathdatap, -1, NULL, 0);
877 inpathp = malloc(cch * sizeof(clientchar_t));
878 cm_AnsiToClientString(inpathdatap, -1, inpathp, cch);
880 TranslateExtendedChars(inpathdatap);
882 cch = cm_OemToClientString(inpathdatap, -1, NULL, 0);
886 inpathp = malloc(cch * sizeof(clientchar_t));
887 cm_OemToClientString(inpathdatap, -1, inpathp, cch);
891 cm_ClientStrCpy(tbuffer, lengthof(tbuffer), inpathp);
892 tp = cm_ClientStrRChr(tbuffer, '\\');
893 jp = cm_ClientStrRChr(tbuffer, '/');
896 else if (jp && (tp - tbuffer) < (jp - tbuffer))
899 cm_ClientStrCpy(tbuffer, lengthof(tbuffer), _C("\\"));
901 cm_ClientStrCpy(leafp, LEAF_SIZE, inpathp);
906 cm_ClientStrCpy(leafp, LEAF_SIZE, tp+1);
910 inpathp = NULL; /* We don't need this from this point on */
912 if (tbuffer[0] == tbuffer[1] &&
913 tbuffer[1] == '\\' &&
914 !cm_ClientStrCmpNI(cm_NetbiosNameC, tbuffer+2,
915 (int)cm_ClientStrLen(cm_NetbiosNameC)))
917 clientchar_t shareName[256];
918 clientchar_t *sharePath;
921 /* We may have found a UNC path.
922 * If the first component is the NetbiosName,
923 * then throw out the second component (the submount)
924 * since it had better expand into the value of ioctl->tidPathp
927 p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
928 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
931 for (i = 0; *p && *p != '\\'; i++,p++ ) {
934 p++; /* skip past trailing slash */
935 shareName[i] = 0; /* terminate string */
937 shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
939 /* we found a sharename, therefore use the resulting path */
940 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
941 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
942 userp, sharePath, reqp, &substRootp);
944 if (code) return code;
946 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
947 userp, NULL, reqp, scpp);
948 cm_ReleaseSCache(substRootp);
949 if (code) return code;
951 /* otherwise, treat the name as a cellname mounted off the afs root.
952 * This requires that we reconstruct the shareName string with
953 * leading and trailing slashes.
955 p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
956 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
960 for (i = 1; *p && *p != '\\'; i++,p++ ) {
963 p++; /* skip past trailing slash */
964 shareName[i++] = '/'; /* add trailing slash */
965 shareName[i] = 0; /* terminate string */
967 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
968 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
969 userp, shareName, reqp, &substRootp);
970 if (code) return code;
972 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
973 userp, NULL, reqp, scpp);
974 cm_ReleaseSCache(substRootp);
975 if (code) return code;
978 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
979 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
980 userp, ioctlp->tidPathp, reqp, &substRootp);
981 if (code) return code;
983 code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
984 userp, NULL, reqp, scpp);
985 cm_ReleaseSCache(substRootp);
986 if (code) return code;
989 /* # of bytes of path */
990 code = (long)strlen(ioctlp->ioctl.inDatap) + 1;
991 ioctlp->ioctl.inDatap += code;
993 /* Ensure that the status object is up to date */
994 lock_ObtainWrite(&(*scpp)->rw);
995 code = cm_SyncOp( *scpp, NULL, userp, reqp, 0,
996 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
998 cm_SyncOpDone( *scpp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
999 lock_ReleaseWrite(&(*scpp)->rw);
1001 /* and return success */
1006 smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1013 struct ClearToken ct;
1019 int release_userp = 0;
1020 clientchar_t *uname = NULL;
1021 clientchar_t *smbname = NULL;
1022 clientchar_t *wdir = NULL;
1023 clientchar_t *rpc_sid = NULL;
1026 saveDataPtr = ioctlp->ioctl.inDatap;
1028 cm_SkipIoctlPath(&ioctlp->ioctl);
1030 tp = ioctlp->ioctl.inDatap;
1033 memcpy(&ticketLen, tp, sizeof(ticketLen));
1034 tp += sizeof(ticketLen);
1035 if (ticketLen < MINKTCTICKETLEN || ticketLen > MAXKTCTICKETLEN)
1036 return CM_ERROR_INVAL;
1038 /* remember ticket and skip over it for now */
1042 /* clear token size */
1043 memcpy(&ctSize, tp, sizeof(ctSize));
1044 tp += sizeof(ctSize);
1045 if (ctSize != sizeof(struct ClearToken))
1046 return CM_ERROR_INVAL;
1049 memcpy(&ct, tp, ctSize);
1051 if (ct.AuthHandle == -1)
1052 ct.AuthHandle = 999; /* more rxvab compat stuff */
1054 /* more stuff, if any */
1055 if (ioctlp->ioctl.inCopied > tp - saveDataPtr) {
1056 /* flags: logon flag */
1057 memcpy(&flags, tp, sizeof(int));
1062 fschar_t * cellnamep;
1063 clientchar_t * temp;
1065 temp = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1066 cellnamep = cm_ClientStringToFsStringAlloc(temp, -1, NULL);
1067 cellp = cm_GetCell(cellnamep, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
1073 code = CM_ERROR_NOSUCHCELL;
1076 tp += strlen(tp) + 1;
1079 uname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1080 tp += strlen(tp) + 1;
1082 if (flags & PIOCTL_LOGON) {
1083 /* SMB user name with which to associate tokens */
1084 smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1085 osi_Log2(smb_logp,"smb_IoctlSetToken for user [%S] smbname [%S]",
1086 osi_LogSaveClientString(smb_logp,uname),
1087 osi_LogSaveClientString(smb_logp,smbname));
1088 fprintf(stderr, "SMB name = %S\n", smbname);
1089 tp += strlen(tp) + 1;
1091 osi_Log1(smb_logp,"smb_IoctlSetToken for user [%S]",
1092 osi_LogSaveClientString(smb_logp, uname));
1096 memcpy(&uuid, tp, sizeof(uuid));
1097 if (!cm_FindTokenEvent(uuid, sessionKey, &rpc_sid)) {
1098 code = CM_ERROR_INVAL;
1103 if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM)) {
1104 osi_Log1(smb_logp,"smb_IoctlSetToken Rpc Sid [%S]",
1105 osi_LogSaveClientString(smb_logp, rpc_sid));
1106 if (!cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, rpc_sid))
1107 pflags |= AFSCALL_FLAG_LOCAL_SYSTEM;
1112 if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1113 code = CM_ERROR_NOACCESS;
1117 cellp = cm_data.rootCellp;
1118 osi_Log0(smb_logp,"smb_IoctlSetToken - no name specified");
1121 if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1123 DWORD dwSize1 = 0, dwSize2 = 0;
1124 wchar_t *pszRefDomain = NULL;
1125 SID_NAME_USE snu = SidTypeGroup;
1126 clientchar_t * secSidString = NULL;
1130 * The specified smbname is may not be a SID for the user.
1131 * See if we can obtain the SID for the specified name.
1132 * If we can, use that instead of the name provided.
1135 LookupAccountNameW( NULL /* System Name to begin Search */,
1140 gle = GetLastError();
1141 if (gle == ERROR_INSUFFICIENT_BUFFER) {
1142 pSid = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, dwSize1);
1144 * Although dwSize2 is supposed to include the terminating
1145 * NUL character, on Win7 it does not.
1147 pszRefDomain = malloc((dwSize2 + 1) * sizeof(wchar_t));
1150 if ( pSid && pszRefDomain ) {
1151 if (LookupAccountNameW( NULL /* System Name to begin Search */,
1154 pszRefDomain, &dwSize2,
1156 ConvertSidToStringSidW(pSid, &secSidString);
1160 userp = smb_FindCMUserBySID( secSidString, ioctlp->fidp->vcp->rname,
1161 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1162 LocalFree(secSidString);
1164 /* Free the SID so we can reuse the variable */
1171 * If the SID for the name could not be found,
1172 * perhaps it already is a SID
1174 if (!ConvertStringSidToSidW( smbname, &pSid)) {
1175 userp = smb_FindCMUserBySID( smbname, ioctlp->fidp->vcp->rname,
1176 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1178 userp = smb_FindCMUserByName( smbname, ioctlp->fidp->vcp->rname,
1179 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1191 /* store the token */
1192 lock_ObtainMutex(&userp->mx);
1193 ucellp = cm_GetUCell(userp, cellp);
1194 osi_Log1(smb_logp,"smb_IoctlSetToken ucellp %lx", ucellp);
1195 ucellp->ticketLen = ticketLen;
1196 if (ucellp->ticketp)
1197 free(ucellp->ticketp); /* Discard old token if any */
1198 ucellp->ticketp = malloc(ticketLen);
1199 memcpy(ucellp->ticketp, ticket, ticketLen);
1201 * Get the session key from the RPC, rather than from the pioctl.
1204 memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey));
1206 memcpy(ucellp->sessionKey.data, sessionKey, sizeof(sessionKey));
1207 ucellp->kvno = ct.AuthHandle;
1208 ucellp->expirationTime = ct.EndTimestamp;
1211 ucellp->uid = ANONYMOUSID;
1214 cm_ClientStringToFsString(uname, -1, ucellp->userName, MAXKTCNAMELEN);
1216 cm_UsernameToId(uname, ucellp, &ucellp->uid);
1219 _InterlockedOr(&ucellp->flags, CM_UCELLFLAG_RXKAD);
1220 lock_ReleaseMutex(&userp->mx);
1222 if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1223 ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
1226 cm_ResetACLCache(cellp, userp);
1229 SecureZeroMemory(sessionKey, sizeof(sessionKey));
1232 cm_ReleaseUser(userp);
1246 smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1248 smb_user_t *uidp = ioctlp->uidp;
1250 if (uidp && uidp->unp) {
1253 cch = cm_ClientStringToUtf8(uidp->unp->name,
1255 ioctlp->ioctl.outDatap,
1256 (int)(SMB_IOCTL_MAXDATA -
1257 (ioctlp->ioctl.outDatap - ioctlp->ioctl.outAllocp))
1258 / sizeof(cm_utf8char_t));
1260 ioctlp->ioctl.outDatap += cch * sizeof(cm_utf8char_t);
1267 smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1272 cm_ioctlQueryOptions_t *optionsp;
1273 afs_uint32 flags = 0;
1277 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1278 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1279 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1281 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1283 cm_SkipIoctlPath(&ioctlp->ioctl);
1284 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1285 optionsp->fid.vnode, optionsp->fid.unique);
1286 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
1288 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1294 code = cm_IoctlGetACL(&ioctlp->ioctl, userp, scp, &req);
1296 cm_ReleaseSCache(scp);
1301 smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1306 afs_uint32 flags = 0;
1310 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1314 code = cm_IoctlSetACL(&ioctlp->ioctl, userp, scp, &req);
1316 cm_ReleaseSCache(scp);
1321 smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1326 cm_ioctlQueryOptions_t *optionsp;
1327 afs_uint32 flags = 0;
1331 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1332 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1333 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1335 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1337 cm_SkipIoctlPath(&ioctlp->ioctl);
1338 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1339 optionsp->fid.vnode, optionsp->fid.unique);
1340 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
1342 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1347 code = cm_IoctlGetFileCellName(&ioctlp->ioctl, userp, scp, &req);
1349 cm_ReleaseSCache(scp);
1355 smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1361 cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
1363 return cm_IoctlFlushAllVolumes(&ioctlp->ioctl, userp, &req);
1367 smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1372 cm_ioctlQueryOptions_t *optionsp;
1373 afs_uint32 flags = 0;
1377 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1378 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1379 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1381 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1383 cm_SkipIoctlPath(&ioctlp->ioctl);
1384 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1385 optionsp->fid.vnode, optionsp->fid.unique);
1386 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
1388 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1393 code = cm_IoctlFlushVolume(&ioctlp->ioctl, userp, scp, &req);
1395 cm_ReleaseSCache(scp);
1401 smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1406 cm_ioctlQueryOptions_t *optionsp;
1407 afs_uint32 flags = 0;
1411 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1412 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1413 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1415 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1417 cm_SkipIoctlPath(&ioctlp->ioctl);
1418 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1419 optionsp->fid.vnode, optionsp->fid.unique);
1420 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
1422 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1427 code = cm_IoctlFlushFile(&ioctlp->ioctl, userp, scp, &req);
1429 cm_ReleaseSCache(scp);
1434 smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1442 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, 0);
1443 if (code) return code;
1445 code = cm_IoctlSetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
1446 cm_ReleaseSCache(scp);
1452 smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1456 cm_ioctlQueryOptions_t *optionsp;
1457 afs_uint32 flags = 0;
1462 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1463 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1464 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1466 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1468 cm_SkipIoctlPath(&ioctlp->ioctl);
1469 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1470 optionsp->fid.vnode, optionsp->fid.unique);
1471 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
1473 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1478 code = cm_IoctlGetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
1480 cm_ReleaseSCache(scp);
1486 smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1491 cm_ioctlQueryOptions_t * optionsp;
1492 afs_uint32 flags = 0;
1496 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1497 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1498 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1500 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1504 code = cm_IoctlGetFid(&ioctlp->ioctl, userp, scp, &req);
1506 cm_ReleaseSCache(scp);
1512 smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1517 cm_ioctlQueryOptions_t * optionsp;
1518 afs_uint32 flags = 0;
1522 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1523 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1524 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1526 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1528 cm_SkipIoctlPath(&ioctlp->ioctl);
1529 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1530 optionsp->fid.vnode, optionsp->fid.unique);
1531 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
1533 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1538 code = cm_IoctlGetFileType(&ioctlp->ioctl, userp, scp, &req);
1540 cm_ReleaseSCache(scp);
1546 smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1551 cm_ioctlQueryOptions_t *optionsp;
1552 afs_uint32 flags = 0;
1556 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1557 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1558 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1560 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1562 cm_SkipIoctlPath(&ioctlp->ioctl);
1563 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1564 optionsp->fid.vnode, optionsp->fid.unique);
1565 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
1567 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1572 code = cm_IoctlGetOwner(&ioctlp->ioctl, userp, scp, &req);
1574 cm_ReleaseSCache(scp);
1580 smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1585 cm_ioctlQueryOptions_t *optionsp;
1586 afs_uint32 flags = 0;
1590 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1591 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1592 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1594 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1596 cm_SkipIoctlPath(&ioctlp->ioctl);
1597 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1598 optionsp->fid.vnode, optionsp->fid.unique);
1599 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
1601 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1606 code = cm_IoctlWhereIs(&ioctlp->ioctl, userp, scp, &req);
1608 cm_ReleaseSCache(scp);
1615 smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1623 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1627 code = cm_IoctlStatMountPoint(&ioctlp->ioctl, userp, dscp, &req);
1629 cm_ReleaseSCache(dscp);
1635 smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1643 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1647 code = cm_IoctlDeleteMountPoint(&ioctlp->ioctl, userp, dscp, &req);
1649 cm_ReleaseSCache(dscp);
1655 smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1657 cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
1659 return cm_IoctlCheckServers(&ioctlp->ioctl, userp);
1663 smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1665 /* we don't print anything superfluous, so we don't support the gag call */
1666 return CM_ERROR_INVAL;
1670 smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1672 cm_SkipIoctlPath(&ioctlp->ioctl);
1674 return cm_IoctlCheckVolumes(&ioctlp->ioctl, userp);
1677 afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1679 cm_SkipIoctlPath(&ioctlp->ioctl);
1681 return cm_IoctlSetCacheSize(&ioctlp->ioctl, userp);
1686 smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1688 cm_SkipIoctlPath(&ioctlp->ioctl);
1690 return cm_IoctlTraceControl(&ioctlp->ioctl, userp);
1694 smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1696 cm_SkipIoctlPath(&ioctlp->ioctl);
1698 return cm_IoctlGetCacheParms(&ioctlp->ioctl, userp);
1702 smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1704 cm_SkipIoctlPath(&ioctlp->ioctl);
1706 return cm_IoctlGetCell(&ioctlp->ioctl, userp);
1710 smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1712 cm_SkipIoctlPath(&ioctlp->ioctl);
1714 return cm_IoctlNewCell(&ioctlp->ioctl, userp);
1718 smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1720 cm_SkipIoctlPath(&ioctlp->ioctl);
1722 return cm_IoctlNewCell2(&ioctlp->ioctl, userp);
1726 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1728 cm_SkipIoctlPath(&ioctlp->ioctl);
1730 return cm_IoctlGetWsCell(&ioctlp->ioctl, userp);
1734 smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1736 cm_SkipIoctlPath(&ioctlp->ioctl);
1738 return cm_IoctlSysName(&ioctlp->ioctl, userp);
1742 smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1744 cm_SkipIoctlPath(&ioctlp->ioctl);
1746 return cm_IoctlGetCellStatus(&ioctlp->ioctl, userp);
1750 smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1752 cm_SkipIoctlPath(&ioctlp->ioctl);
1754 return cm_IoctlSetCellStatus(&ioctlp->ioctl, userp);
1758 smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1760 cm_SkipIoctlPath(&ioctlp->ioctl);
1762 return cm_IoctlSetSPrefs(&ioctlp->ioctl, userp);
1766 smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1768 cm_SkipIoctlPath(&ioctlp->ioctl);
1770 return cm_IoctlGetSPrefs(&ioctlp->ioctl, userp);
1774 smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1776 /* we ignore default asynchrony since we only have one way
1777 * of doing this today.
1783 smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1787 clientchar_t leaf[LEAF_SIZE];
1792 code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
1796 code = cm_IoctlCreateMountPoint(&ioctlp->ioctl, userp, dscp, &req, leaf);
1798 cm_ReleaseSCache(dscp);
1803 smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1807 clientchar_t leaf[LEAF_SIZE];
1812 code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
1813 if (code) return code;
1815 code = cm_IoctlSymlink(&ioctlp->ioctl, userp, dscp, &req, leaf);
1817 cm_ReleaseSCache(dscp);
1823 smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1831 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1832 if (code) return code;
1834 code = cm_IoctlListlink(&ioctlp->ioctl, userp, dscp, &req);
1836 cm_ReleaseSCache(dscp);
1841 smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1842 {/*CHECK FOR VALID SYMLINK*/
1849 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1850 if (code) return code;
1852 code = cm_IoctlIslink(&ioctlp->ioctl, userp, dscp, &req);
1854 cm_ReleaseSCache(dscp);
1860 smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1868 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1869 if (code) return code;
1871 code = cm_IoctlDeletelink(&ioctlp->ioctl, userp, dscp, &req);
1873 cm_ReleaseSCache(dscp);
1879 smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1881 cm_SkipIoctlPath(&ioctlp->ioctl);
1883 return cm_IoctlGetTokenIter(&ioctlp->ioctl, userp);
1887 smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1889 cm_SkipIoctlPath(&ioctlp->ioctl);
1891 return cm_IoctlGetToken(&ioctlp->ioctl, userp);
1896 smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1898 cm_SkipIoctlPath(&ioctlp->ioctl);
1900 return cm_IoctlDelToken(&ioctlp->ioctl, userp);
1905 smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1907 cm_SkipIoctlPath(&ioctlp->ioctl);
1909 return cm_IoctlDelAllToken(&ioctlp->ioctl, userp);
1914 smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1916 cm_SkipIoctlPath(&ioctlp->ioctl);
1918 return cm_IoctlMakeSubmount(&ioctlp->ioctl, userp);
1922 smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1924 cm_SkipIoctlPath(&ioctlp->ioctl);
1926 return cm_IoctlGetRxkcrypt(&ioctlp->ioctl, userp);
1930 smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1932 cm_SkipIoctlPath(&ioctlp->ioctl);
1934 return cm_IoctlSetRxkcrypt(&ioctlp->ioctl, userp);
1938 smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1940 cm_SkipIoctlPath(&ioctlp->ioctl);
1942 return cm_IoctlRxStatProcess(&ioctlp->ioctl, userp);
1947 smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1949 cm_SkipIoctlPath(&ioctlp->ioctl);
1951 return cm_IoctlRxStatPeer(&ioctlp->ioctl, userp);
1955 smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1957 cm_SkipIoctlPath(&ioctlp->ioctl);
1959 return cm_IoctlUnicodeControl(&ioctlp->ioctl, userp);
1963 smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1965 cm_SkipIoctlPath(&ioctlp->ioctl);
1967 return cm_IoctlUUIDControl(&ioctlp->ioctl, userp);
1972 smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1974 cm_SkipIoctlPath(&ioctlp->ioctl);
1976 return cm_IoctlMemoryDump(&ioctlp->ioctl, userp);
1980 smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1985 cm_ioctlQueryOptions_t *optionsp;
1986 afs_uint32 flags = 0;
1990 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1991 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1992 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1994 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1996 cm_SkipIoctlPath(&ioctlp->ioctl);
1997 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1998 optionsp->fid.vnode, optionsp->fid.unique);
1999 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
2001 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2006 code = cm_IoctlPathAvailability(&ioctlp->ioctl, userp, scp, &req);
2007 cm_ReleaseSCache(scp);
2012 smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2018 cm_SkipIoctlPath(&ioctlp->ioctl);
2020 return cm_IoctlVolStatTest(&ioctlp->ioctl, userp, &req);
2026 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
2030 smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2035 cm_ioctlQueryOptions_t *optionsp;
2036 afs_uint32 flags = 0;
2040 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2042 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2043 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2045 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2047 cm_SkipIoctlPath(&ioctlp->ioctl);
2048 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2049 optionsp->fid.vnode, optionsp->fid.unique);
2050 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
2052 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2057 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
2060 code = cm_IoctlSetOwner(&ioctlp->ioctl, userp, scp, &req);
2062 cm_ReleaseSCache(scp);
2070 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
2074 smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2079 cm_ioctlQueryOptions_t *optionsp;
2080 afs_uint32 flags = 0;
2084 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2086 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2087 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2089 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2091 cm_SkipIoctlPath(&ioctlp->ioctl);
2092 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2093 optionsp->fid.vnode, optionsp->fid.unique);
2094 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
2096 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2101 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
2104 code = cm_IoctlSetGroup(&ioctlp->ioctl, userp, scp, &req);
2106 cm_ReleaseSCache(scp);
2113 smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2118 cm_ioctlQueryOptions_t *optionsp;
2119 afs_uint32 flags = 0;
2123 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2124 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2125 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2127 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2129 cm_SkipIoctlPath(&ioctlp->ioctl);
2130 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2131 optionsp->fid.vnode, optionsp->fid.unique);
2132 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
2134 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2139 code = cm_IoctlGetUnixMode(&ioctlp->ioctl, userp, scp, &req);
2141 cm_ReleaseSCache(scp);
2150 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
2153 smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2158 cm_ioctlQueryOptions_t *optionsp;
2159 afs_uint32 flags = 0;
2163 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2165 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2166 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2168 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2170 cm_SkipIoctlPath(&ioctlp->ioctl);
2171 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2172 optionsp->fid.vnode, optionsp->fid.unique);
2173 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
2175 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2180 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
2183 code = cm_IoctlSetUnixMode(&ioctlp->ioctl, userp, scp, &req);
2185 cm_ReleaseSCache(scp);
2191 smb_IoctlGetVerifyData(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2193 cm_SkipIoctlPath(&ioctlp->ioctl);
2195 return cm_IoctlGetVerifyData(&ioctlp->ioctl);
2199 smb_IoctlSetVerifyData(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2201 cm_SkipIoctlPath(&ioctlp->ioctl);
2203 return cm_IoctlSetVerifyData(&ioctlp->ioctl);
2207 smb_IoctlGetCallerAccess(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2212 cm_ioctlQueryOptions_t * optionsp;
2213 afs_uint32 flags = 0;
2217 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2218 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2219 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2221 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2223 cm_SkipIoctlPath(&ioctlp->ioctl);
2224 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2225 optionsp->fid.vnode, optionsp->fid.unique);
2226 code = cm_GetSCache(&fid, NULL, &scp, userp, &req);
2228 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2233 code = cm_IoctlGetCallerAccess(&ioctlp->ioctl, userp, scp, &req);
2235 cm_ReleaseSCache(scp);