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_IoctlSetUnixMode;
101 /* called to make a fid structure into an IOCTL fid structure */
103 smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
106 cm_space_t *copyPrefix;
108 lock_ObtainMutex(&fidp->mx);
109 fidp->flags |= SMB_FID_IOCTL;
110 fidp->scp = &cm_data.fakeSCache;
111 cm_HoldSCache(fidp->scp);
112 if (fidp->ioctlp == NULL) {
113 iop = malloc(sizeof(*iop));
114 memset(iop, 0, sizeof(*iop));
119 copyPrefix = cm_GetSpace();
120 memcpy(copyPrefix->data, prefix->data, CM_UTILS_SPACESIZE);
121 fidp->ioctlp->prefix = copyPrefix;
123 lock_ReleaseMutex(&fidp->mx);
126 /* called when we receive a read call, does the send of the received data if
127 * this is the first read call. This is the function that actually makes the
128 * call to the ioctl code.
131 smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
134 smb_ioctlProc_t *procp = NULL;
137 if (ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN) {
138 ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAIN;
139 ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAOUT;
141 /* do the call now, or fail if we didn't get an opcode, or
142 * enough of an opcode.
144 if (ioctlp->ioctl.inCopied < sizeof(afs_int32))
145 return CM_ERROR_INVAL;
146 memcpy(&opcode, ioctlp->ioctl.inDatap, sizeof(afs_int32));
147 ioctlp->ioctl.inDatap += sizeof(afs_int32);
149 osi_Log1(afsd_logp, "smb_IoctlPrepareRead opcode 0x%x", opcode);
150 /* check for opcode out of bounds */
151 if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS) {
152 osi_Log0(afsd_logp, "smb_IoctlPrepareRead - invalid opcode");
153 return CM_ERROR_TOOBIG;
156 /* check for no such proc */
157 procp = smb_ioctlProcsp[opcode];
159 osi_Log0(afsd_logp, "smb_IoctlPrepareRead - unassigned opcode");
160 return CM_ERROR_INVAL;
162 /* otherwise, make the call */
163 ioctlp->ioctl.outDatap += sizeof(afs_int32); /* reserve room for return code */
164 code = (*procp)(ioctlp, userp, pflags);
165 osi_Log1(afsd_logp, "smb_IoctlPrepareRead operation returns code 0x%x", code);
167 /* copy in return code */
168 memcpy(ioctlp->ioctl.outAllocp, &code, sizeof(afs_int32));
169 } else if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAOUT)) {
170 osi_Log0(afsd_logp, "Ioctl invalid state - dataout expected");
171 return CM_ERROR_INVAL;
177 /* called when we receive a write call. If this is the first write call after
178 * a series of reads (or the very first call), then we start a new call.
179 * We also ensure that things are properly initialized for the start of a call.
182 smb_IoctlPrepareWrite(smb_fid_t *fidp, smb_ioctl_t *ioctlp)
184 /* make sure the buffer(s) are allocated */
185 if (!ioctlp->ioctl.inAllocp)
186 ioctlp->ioctl.inAllocp = malloc(SMB_IOCTL_MAXDATA);
187 if (!ioctlp->ioctl.outAllocp)
188 ioctlp->ioctl.outAllocp = malloc(SMB_IOCTL_MAXDATA);
190 /* Fixes fs la problem. We do a StrToOEM later and if this data isn't initialized we get memory issues. */
191 (void) memset(ioctlp->ioctl.inAllocp, 0, SMB_IOCTL_MAXDATA);
192 (void) memset(ioctlp->ioctl.outAllocp, 0, SMB_IOCTL_MAXDATA);
194 /* and make sure that we've reset our state for the new incoming request */
195 if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN)) {
196 ioctlp->ioctl.inCopied = 0;
197 ioctlp->ioctl.outCopied = 0;
198 ioctlp->ioctl.inDatap = ioctlp->ioctl.inAllocp;
199 ioctlp->ioctl.outDatap = ioctlp->ioctl.outAllocp;
200 ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAIN;
201 ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAOUT;
205 /* called from smb_ReceiveCoreRead when we receive a read on the ioctl fid */
207 smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
211 afs_int32 leftToCopy;
215 cm_user_t *userp = NULL;
220 count = smb_GetSMBParm(inp, 1);
222 /* Get the user and determine if it is the local machine account */
223 smbp = (smb_t *) inp;
224 uidp = smb_FindUID(vcp, smbp->uid, 0);
226 isSystem = smb_userIsLocalSystem(uidp);
227 userp = smb_GetUserFromUID(uidp);
229 osi_Log3(afsd_logp, "smb_IoctlRead uid %d user %x name %s",
231 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
233 osi_Log2(afsd_logp, "smb_IoctlRead uid %d user %x no name",
234 uidp->userID, userp);
236 smb_ReleaseUID(uidp);
238 osi_Log1(afsd_logp, "smb_IoctlRead no uid user %x no name", userp);
239 return CM_ERROR_BADSMB;
243 userp = cm_rootUserp;
248 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
250 cm_ReleaseUser(userp);
251 return CM_ERROR_NOSUCHPATH;
254 /* turn the connection around, if required */
255 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
258 cm_ReleaseUser(userp);
262 leftToCopy = (afs_int32)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
263 if (leftToCopy < 0) {
264 osi_Log0(afsd_logp, "smb_IoctlRead leftToCopy went negative");
265 cm_ReleaseUser(userp);
266 return CM_ERROR_INVAL;
268 if (count > leftToCopy)
271 /* now set the parms for a read of count bytes */
272 smb_SetSMBParm(outp, 0, count);
273 smb_SetSMBParm(outp, 1, 0);
274 smb_SetSMBParm(outp, 2, 0);
275 smb_SetSMBParm(outp, 3, 0);
276 smb_SetSMBParm(outp, 4, 0);
278 smb_SetSMBDataLength(outp, count+3);
280 op = smb_GetSMBData(outp, NULL);
282 *op++ = (char)(count & 0xff);
283 *op++ = (char)((count >> 8) & 0xff);
285 /* now copy the data into the response packet */
286 memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
288 /* and adjust the counters */
289 iop->ioctl.outCopied += count;
291 cm_ReleaseUser(userp);
296 /* called from smb_ReceiveCoreWrite when we receive a write call on the IOCTL
300 smb_IoctlWrite(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
306 int inDataBlockCount;
309 count = smb_GetSMBParm(inp, 1);
312 smb_IoctlPrepareWrite(fidp, iop);
314 op = smb_GetSMBData(inp, NULL);
315 op = smb_ParseDataBlock(op, NULL, &inDataBlockCount);
317 if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
318 code = CM_ERROR_TOOBIG;
323 memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
326 iop->ioctl.inCopied += count;
329 /* return # of bytes written */
331 smb_SetSMBParm(outp, 0, count);
332 smb_SetSMBDataLength(outp, 0);
338 /* called from smb_ReceiveV3WriteX when we receive a write call on the IOCTL
342 smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
348 int inDataBlockCount;
351 count = smb_GetSMBParm(inp, 10);
354 smb_IoctlPrepareWrite(fidp, iop);
356 op = inp->data + smb_GetSMBParm(inp, 11);
357 inDataBlockCount = count;
359 if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
360 code = CM_ERROR_TOOBIG;
365 memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
368 iop->ioctl.inCopied += count;
371 /* return # of bytes written */
373 smb_SetSMBParm(outp, 2, count);
374 smb_SetSMBParm(outp, 3, 0); /* reserved */
375 smb_SetSMBParm(outp, 4, 0); /* reserved */
376 smb_SetSMBParm(outp, 5, 0); /* reserved */
377 smb_SetSMBDataLength(outp, 0);
384 /* called from V3 read to handle IOCTL descriptor reads */
386 smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
389 unsigned short count;
398 count = smb_GetSMBParm(inp, 5);
400 /* Get the user and determine if it is the local machine account */
401 uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
403 isSystem = smb_userIsLocalSystem(uidp);
404 userp = smb_GetUserFromUID(uidp);
406 osi_Log3(afsd_logp, "smb_IoctlV3Read uid %d user %x name %s",
408 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
410 osi_Log2(afsd_logp, "smb_IoctlV3Read uid %d user %x no name",
411 uidp->userID, userp);
414 osi_Log0(afsd_logp, "smb_IoctlV3Read no uid");
415 return CM_ERROR_BADSMB;
419 userp = cm_rootUserp;
426 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
429 smb_ReleaseUID(uidp);
430 cm_ReleaseUser(userp);
431 return CM_ERROR_NOSUCHPATH;
434 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
437 smb_ReleaseUID(uidp);
440 cm_ReleaseUser(userp);
444 leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
445 if (leftToCopy < 0) {
446 osi_Log0(afsd_logp, "smb_IoctlV3Read leftToCopy went negative");
447 cm_ReleaseUser(userp);
448 return CM_ERROR_INVAL;
450 if (count > leftToCopy)
451 count = (unsigned short)leftToCopy;
453 /* 0 and 1 are reserved for request chaining, were setup by our caller,
454 * and will be further filled in after we return.
456 smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */
457 smb_SetSMBParm(outp, 3, 0); /* resvd */
458 smb_SetSMBParm(outp, 4, 0); /* resvd */
459 smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */
460 /* fill in #6 when we have all the parameters' space reserved */
461 smb_SetSMBParm(outp, 7, 0); /* resv'd */
462 smb_SetSMBParm(outp, 8, 0); /* resv'd */
463 smb_SetSMBParm(outp, 9, 0); /* resv'd */
464 smb_SetSMBParm(outp, 10, 0); /* resv'd */
465 smb_SetSMBParm(outp, 11, 0); /* reserved */
467 /* get op ptr after putting in the last parm, since otherwise we don't
468 * know where the data really is.
470 op = smb_GetSMBData(outp, NULL);
472 /* now fill in offset from start of SMB header to first data byte (to op) */
473 smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
475 /* set the packet data length the count of the # of bytes */
476 smb_SetSMBDataLength(outp, count);
478 /* now copy the data into the response packet */
479 memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
481 /* and adjust the counters */
482 iop->ioctl.outCopied += count;
484 /* and cleanup things */
485 cm_ReleaseUser(userp);
490 /* called from Read Raw to handle IOCTL descriptor reads */
492 smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
505 /* Get the user and determine if it is the local machine account */
506 uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
508 isSystem = smb_userIsLocalSystem(uidp);
509 userp = smb_GetUserFromUID(uidp);
511 osi_Log3(afsd_logp, "smb_IoctlRawRead uid %d user %x name %s",
513 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
515 osi_Log2(afsd_logp, "smb_IoctlRawRead uid %d user %x no name",
516 uidp->userID, userp);
518 smb_ReleaseUID(uidp);
520 osi_Log0(afsd_logp, "smb_IoctlRawRead no uid");
524 userp = cm_rootUserp;
528 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
530 code = CM_ERROR_NOSUCHPATH;
534 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
539 leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
540 if (leftToCopy < 0) {
541 osi_Log0(afsd_logp, "smb_IoctlReadRaw leftToCopy went negative");
542 code = CM_ERROR_INVAL;
547 memset(ncbp, 0, sizeof(NCB));
549 ncbp->ncb_length = (unsigned short) leftToCopy;
550 ncbp->ncb_lsn = (unsigned char) vcp->lsn;
551 ncbp->ncb_command = NCBSEND;
552 /*ncbp->ncb_lana_num = smb_LANadapter;*/
553 ncbp->ncb_lana_num = vcp->lana;
555 ncbp->ncb_buffer = iop->ioctl.outCopied + iop->ioctl.outAllocp;
556 code = Netbios(ncbp);
559 osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
562 cm_ReleaseUser(userp);
567 /* parse the passed-in file name and do a namei on it. If we fail,
568 * return an error code, otherwise return the vnode located in *scpp.
570 #define CM_PARSE_FLAG_LITERAL 1
573 smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
574 cm_scache_t **scpp, afs_uint32 flags)
577 cm_scache_t *substRootp = NULL;
578 cm_scache_t *iscp = NULL;
580 clientchar_t *relativePath = NULL;
581 clientchar_t *lastComponent = NULL;
582 afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
584 inPath = ioctlp->ioctl.inDatap;
585 /* setup the next data value for the caller to use */
586 ioctlp->ioctl.inDatap += (long)strlen(ioctlp->ioctl.inDatap) + 1;
588 osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,inPath));
590 /* This is usually the file name, but for StatMountPoint it is the path. */
591 /* ioctlp->ioctl.inDatap can be either of the form:
594 * \\netbios-name\submount\path\.
595 * \\netbios-name\submount\path\file
598 /* We do not perform path name translation on the ioctl path data
599 * because these paths were not translated by Windows through the
600 * file system API. Therefore, they are not OEM characters but
601 * whatever the display character set is.
604 // TranslateExtendedChars(relativePath);
606 /* This is usually nothing, but for StatMountPoint it is the file name. */
607 // TranslateExtendedChars(ioctlp->ioctl.inDatap);
609 /* If the string starts with our UTF-8 prefix (which is the
610 sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
611 strings), we assume that the provided path is UTF-8. Otherwise
612 we have to convert the string to UTF-8, since that is what we
613 want to use everywhere else.*/
615 if (memcmp(inPath, utf8_prefix, utf8_prefix_size) == 0) {
616 /* String is UTF-8 */
617 inPath += utf8_prefix_size;
618 ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
620 relativePath = cm_Utf8ToClientStringAlloc(inPath, -1, NULL);
624 /* Not a UTF-8 string */
625 /* TODO: If this is an OEM string, we should convert it to
627 if (smb_StoreAnsiFilenames) {
628 cch = cm_AnsiToClientString(inPath, -1, NULL, 0);
632 relativePath = malloc(cch * sizeof(clientchar_t));
633 cm_AnsiToClientString(inPath, -1, relativePath, cch);
635 TranslateExtendedChars(inPath);
637 cch = cm_OemToClientString(inPath, -1, NULL, 0);
641 relativePath = malloc(cch * sizeof(clientchar_t));
642 cm_OemToClientString(inPath, -1, relativePath, cch);
646 if (relativePath[0] == relativePath[1] &&
647 relativePath[1] == '\\' &&
648 !cm_ClientStrCmpNI(cm_NetbiosNameC, relativePath+2,
649 cm_ClientStrLen(cm_NetbiosNameC)))
651 clientchar_t shareName[256];
652 clientchar_t *sharePath;
655 /* We may have found a UNC path.
656 * If the first component is the NetbiosName,
657 * then throw out the second component (the submount)
658 * since it had better expand into the value of ioctl->tidPathp
661 p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1; /* buffer overflow vuln.? */
662 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
665 for (i = 0; *p && *p != '\\'; i++,p++ ) {
668 p++; /* skip past trailing slash */
669 shareName[i] = 0; /* terminate string */
671 shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
673 /* we found a sharename, therefore use the resulting path */
674 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
675 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
676 userp, sharePath, reqp, &substRootp);
679 osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code);
685 lastComponent = cm_ClientStrRChr(p, '\\');
686 if (lastComponent && (lastComponent - p) > 1 &&
687 cm_ClientStrLen(lastComponent) > 1) {
688 *lastComponent = '\0';
691 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
692 userp, NULL, reqp, &iscp);
694 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
695 userp, NULL, reqp, scpp);
697 cm_ReleaseSCache(iscp);
699 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
700 userp, NULL, reqp, scpp);
702 cm_ReleaseSCache(substRootp);
704 osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code);
710 /* otherwise, treat the name as a cellname mounted off the afs root.
711 * This requires that we reconstruct the shareName string with
712 * leading and trailing slashes.
714 p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
715 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
719 for (i = 1; *p && *p != '\\'; i++,p++ ) {
722 p++; /* skip past trailing slash */
723 shareName[i++] = '/'; /* add trailing slash */
724 shareName[i] = 0; /* terminate string */
727 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
728 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
729 userp, shareName, reqp, &substRootp);
731 osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code);
737 lastComponent = cm_ClientStrRChr(p, '\\');
738 if (lastComponent && (lastComponent - p) > 1 &&
739 cm_ClientStrLen(lastComponent) > 1) {
740 *lastComponent = '\0';
743 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
744 userp, NULL, reqp, &iscp);
746 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
747 userp, NULL, reqp, scpp);
749 cm_ReleaseSCache(iscp);
751 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
752 userp, NULL, reqp, scpp);
756 cm_ReleaseSCache(substRootp);
757 osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code);
764 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
765 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
766 userp, ioctlp->tidPathp, reqp, &substRootp);
768 osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code);
774 lastComponent = cm_ClientStrRChr(relativePath, '\\');
775 if (lastComponent && (lastComponent - relativePath) > 1 &&
776 cm_ClientStrLen(lastComponent) > 1) {
777 *lastComponent = '\0';
780 code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
781 userp, NULL, reqp, &iscp);
783 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
784 userp, NULL, reqp, scpp);
786 cm_ReleaseSCache(iscp);
788 code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | follow,
789 userp, NULL, reqp, scpp);
792 cm_ReleaseSCache(substRootp);
793 osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code);
801 cm_ReleaseSCache(substRootp);
806 /* Ensure that the status object is up to date */
807 lock_ObtainWrite(&(*scpp)->rw);
808 code = cm_SyncOp( *scpp, NULL, userp, reqp, 0,
809 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
811 cm_SyncOpDone( *scpp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
812 lock_ReleaseWrite(&(*scpp)->rw);
814 /* and return success */
815 osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
821 #define LEAF_SIZE 256
822 /* parse the passed-in file name and do a namei on its parent. If we fail,
823 * return an error code, otherwise return the vnode located in *scpp.
826 smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
827 cm_scache_t **scpp, clientchar_t *leafp)
830 clientchar_t tbuffer[1024];
831 clientchar_t *tp, *jp;
832 cm_scache_t *substRootp = NULL;
833 clientchar_t *inpathp = NULL;
836 inpathdatap = ioctlp->ioctl.inDatap;
838 /* If the string starts with our UTF-8 prefix (which is the
839 sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
840 strings), we assume that the provided path is UTF-8. Otherwise
841 we have to convert the string to UTF-8, since that is what we
842 want to use everywhere else.*/
844 if (memcmp(inpathdatap, utf8_prefix, utf8_prefix_size) == 0) {
846 /* String is UTF-8 */
847 inpathdatap += utf8_prefix_size;
848 ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
850 inpathp = cm_Utf8ToClientStringAlloc(inpathdatap, -1, NULL);
854 /* Not a UTF-8 string */
855 /* TODO: If this is an OEM string, we should convert it to
857 if (smb_StoreAnsiFilenames) {
858 cch = cm_AnsiToClientString(inpathdatap, -1, NULL, 0);
862 inpathp = malloc(cch * sizeof(clientchar_t));
863 cm_AnsiToClientString(inpathdatap, -1, inpathp, cch);
865 TranslateExtendedChars(inpathdatap);
867 cch = cm_OemToClientString(inpathdatap, -1, NULL, 0);
871 inpathp = malloc(cch * sizeof(clientchar_t));
872 cm_OemToClientString(inpathdatap, -1, inpathp, cch);
876 cm_ClientStrCpy(tbuffer, lengthof(tbuffer), inpathp);
877 tp = cm_ClientStrRChr(tbuffer, '\\');
878 jp = cm_ClientStrRChr(tbuffer, '/');
881 else if (jp && (tp - tbuffer) < (jp - tbuffer))
884 cm_ClientStrCpy(tbuffer, lengthof(tbuffer), _C("\\"));
886 cm_ClientStrCpy(leafp, LEAF_SIZE, inpathp);
891 cm_ClientStrCpy(leafp, LEAF_SIZE, tp+1);
895 inpathp = NULL; /* We don't need this from this point on */
897 if (tbuffer[0] == tbuffer[1] &&
898 tbuffer[1] == '\\' &&
899 !cm_ClientStrCmpNI(cm_NetbiosNameC, tbuffer+2,
900 cm_ClientStrLen(cm_NetbiosNameC)))
902 clientchar_t shareName[256];
903 clientchar_t *sharePath;
906 /* We may have found a UNC path.
907 * If the first component is the NetbiosName,
908 * then throw out the second component (the submount)
909 * since it had better expand into the value of ioctl->tidPathp
912 p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
913 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
916 for (i = 0; *p && *p != '\\'; i++,p++ ) {
919 p++; /* skip past trailing slash */
920 shareName[i] = 0; /* terminate string */
922 shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
924 /* we found a sharename, therefore use the resulting path */
925 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
926 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
927 userp, sharePath, reqp, &substRootp);
929 if (code) return code;
931 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
932 userp, NULL, reqp, scpp);
933 cm_ReleaseSCache(substRootp);
934 if (code) return code;
936 /* otherwise, treat the name as a cellname mounted off the afs root.
937 * This requires that we reconstruct the shareName string with
938 * leading and trailing slashes.
940 p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
941 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
945 for (i = 1; *p && *p != '\\'; i++,p++ ) {
948 p++; /* skip past trailing slash */
949 shareName[i++] = '/'; /* add trailing slash */
950 shareName[i] = 0; /* terminate string */
952 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
953 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
954 userp, shareName, reqp, &substRootp);
955 if (code) return code;
957 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
958 userp, NULL, reqp, scpp);
959 cm_ReleaseSCache(substRootp);
960 if (code) return code;
963 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
964 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
965 userp, ioctlp->tidPathp, reqp, &substRootp);
966 if (code) return code;
968 code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
969 userp, NULL, reqp, scpp);
970 cm_ReleaseSCache(substRootp);
971 if (code) return code;
974 /* # of bytes of path */
975 code = (long)strlen(ioctlp->ioctl.inDatap) + 1;
976 ioctlp->ioctl.inDatap += code;
978 /* Ensure that the status object is up to date */
979 lock_ObtainWrite(&(*scpp)->rw);
980 code = cm_SyncOp( *scpp, NULL, userp, reqp, 0,
981 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
983 cm_SyncOpDone( *scpp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
984 lock_ReleaseWrite(&(*scpp)->rw);
986 /* and return success */
991 smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
998 struct ClearToken ct;
1004 int release_userp = 0;
1005 clientchar_t *uname = NULL;
1006 clientchar_t *smbname = NULL;
1007 clientchar_t *wdir = NULL;
1008 clientchar_t *rpc_sid = NULL;
1011 saveDataPtr = ioctlp->ioctl.inDatap;
1013 cm_SkipIoctlPath(&ioctlp->ioctl);
1015 tp = ioctlp->ioctl.inDatap;
1018 memcpy(&ticketLen, tp, sizeof(ticketLen));
1019 tp += sizeof(ticketLen);
1020 if (ticketLen < MINKTCTICKETLEN || ticketLen > MAXKTCTICKETLEN)
1021 return CM_ERROR_INVAL;
1023 /* remember ticket and skip over it for now */
1027 /* clear token size */
1028 memcpy(&ctSize, tp, sizeof(ctSize));
1029 tp += sizeof(ctSize);
1030 if (ctSize != sizeof(struct ClearToken))
1031 return CM_ERROR_INVAL;
1034 memcpy(&ct, tp, ctSize);
1036 if (ct.AuthHandle == -1)
1037 ct.AuthHandle = 999; /* more rxvab compat stuff */
1039 /* more stuff, if any */
1040 if (ioctlp->ioctl.inCopied > tp - saveDataPtr) {
1041 /* flags: logon flag */
1042 memcpy(&flags, tp, sizeof(int));
1047 fschar_t * cellnamep;
1048 clientchar_t * temp;
1050 temp = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1051 cellnamep = cm_ClientStringToFsStringAlloc(temp, -1, NULL);
1052 cellp = cm_GetCell(cellnamep, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
1058 code = CM_ERROR_NOSUCHCELL;
1061 tp += strlen(tp) + 1;
1064 uname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1065 tp += strlen(tp) + 1;
1067 if (flags & PIOCTL_LOGON) {
1068 /* SMB user name with which to associate tokens */
1069 smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1070 osi_Log2(smb_logp,"smb_IoctlSetToken for user [%S] smbname [%S]",
1071 osi_LogSaveClientString(smb_logp,uname),
1072 osi_LogSaveClientString(smb_logp,smbname));
1073 fprintf(stderr, "SMB name = %S\n", smbname);
1074 tp += strlen(tp) + 1;
1076 osi_Log1(smb_logp,"smb_IoctlSetToken for user [%S]",
1077 osi_LogSaveClientString(smb_logp, uname));
1081 memcpy(&uuid, tp, sizeof(uuid));
1082 if (!cm_FindTokenEvent(uuid, sessionKey, &rpc_sid)) {
1083 code = CM_ERROR_INVAL;
1087 if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && rpc_sid) {
1088 osi_Log1(smb_logp,"smb_IoctlSetToken Rpc Sid [%S]",
1089 osi_LogSaveClientString(smb_logp, rpc_sid));
1090 if (!cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, rpc_sid))
1091 pflags |= AFSCALL_FLAG_LOCAL_SYSTEM;
1094 if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1095 code = CM_ERROR_NOACCESS;
1099 cellp = cm_data.rootCellp;
1100 osi_Log0(smb_logp,"smb_IoctlSetToken - no name specified");
1103 if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1105 DWORD dwSize1 = 0, dwSize2 = 0;
1106 wchar_t *pszRefDomain = NULL;
1107 SID_NAME_USE snu = SidTypeGroup;
1108 clientchar_t * secSidString = NULL;
1112 * The specified smbname is may not be a SID for the user.
1113 * See if we can obtain the SID for the specified name.
1114 * If we can, use that instead of the name provided.
1117 LookupAccountNameW( NULL /* System Name to begin Search */,
1122 gle = GetLastError();
1123 if (gle == ERROR_INSUFFICIENT_BUFFER) {
1124 pSid = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, dwSize1);
1126 * Although dwSize2 is supposed to include the terminating
1127 * NUL character, on Win7 it does not.
1129 pszRefDomain = malloc((dwSize2 + 1) * sizeof(wchar_t));
1132 if ( pSid && pszRefDomain ) {
1133 if (LookupAccountNameW( NULL /* System Name to begin Search */,
1136 pszRefDomain, &dwSize2,
1138 ConvertSidToStringSidW(pSid, &secSidString);
1142 userp = smb_FindCMUserBySID( secSidString, ioctlp->fidp->vcp->rname,
1143 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1144 LocalFree(secSidString);
1146 /* Free the SID so we can reuse the variable */
1153 * If the SID for the name could not be found,
1154 * perhaps it already is a SID
1156 if (!ConvertStringSidToSidW( smbname, &pSid)) {
1157 userp = smb_FindCMUserBySID( smbname, ioctlp->fidp->vcp->rname,
1158 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1160 userp = smb_FindCMUserByName( smbname, ioctlp->fidp->vcp->rname,
1161 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1173 /* store the token */
1174 lock_ObtainMutex(&userp->mx);
1175 ucellp = cm_GetUCell(userp, cellp);
1176 osi_Log1(smb_logp,"smb_IoctlSetToken ucellp %lx", ucellp);
1177 ucellp->ticketLen = ticketLen;
1178 if (ucellp->ticketp)
1179 free(ucellp->ticketp); /* Discard old token if any */
1180 ucellp->ticketp = malloc(ticketLen);
1181 memcpy(ucellp->ticketp, ticket, ticketLen);
1183 * Get the session key from the RPC, rather than from the pioctl.
1186 memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey));
1188 memcpy(ucellp->sessionKey.data, sessionKey, sizeof(sessionKey));
1189 ucellp->kvno = ct.AuthHandle;
1190 ucellp->expirationTime = ct.EndTimestamp;
1193 ucellp->uid = ANONYMOUSID;
1196 cm_ClientStringToFsString(uname, -1, ucellp->userName, MAXKTCNAMELEN);
1198 cm_UsernameToId(uname, ucellp, &ucellp->uid);
1201 _InterlockedOr(&ucellp->flags, CM_UCELLFLAG_RXKAD);
1202 lock_ReleaseMutex(&userp->mx);
1204 if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1205 ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
1208 cm_ResetACLCache(cellp, userp);
1211 SecureZeroMemory(sessionKey, sizeof(sessionKey));
1214 cm_ReleaseUser(userp);
1228 smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1230 smb_user_t *uidp = ioctlp->uidp;
1232 if (uidp && uidp->unp) {
1235 cch = cm_ClientStringToUtf8(uidp->unp->name,
1237 ioctlp->ioctl.outDatap,
1238 (SMB_IOCTL_MAXDATA -
1239 (ioctlp->ioctl.outDatap - ioctlp->ioctl.outAllocp))
1240 / sizeof(cm_utf8char_t));
1242 ioctlp->ioctl.outDatap += cch * sizeof(cm_utf8char_t);
1249 smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1254 cm_ioctlQueryOptions_t *optionsp;
1255 afs_uint32 flags = 0;
1259 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1260 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1261 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1263 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1265 cm_SkipIoctlPath(&ioctlp->ioctl);
1266 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1267 optionsp->fid.vnode, optionsp->fid.unique);
1268 code = cm_GetSCache(&fid, &scp, userp, &req);
1270 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1276 code = cm_IoctlGetACL(&ioctlp->ioctl, userp, scp, &req);
1278 cm_ReleaseSCache(scp);
1283 smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1288 afs_uint32 flags = 0;
1292 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1296 code = cm_IoctlSetACL(&ioctlp->ioctl, userp, scp, &req);
1298 cm_ReleaseSCache(scp);
1303 smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1308 cm_ioctlQueryOptions_t *optionsp;
1309 afs_uint32 flags = 0;
1313 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1314 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1315 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1317 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1319 cm_SkipIoctlPath(&ioctlp->ioctl);
1320 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1321 optionsp->fid.vnode, optionsp->fid.unique);
1322 code = cm_GetSCache(&fid, &scp, userp, &req);
1324 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1329 code = cm_IoctlGetFileCellName(&ioctlp->ioctl, userp, scp, &req);
1331 cm_ReleaseSCache(scp);
1337 smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1343 cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
1345 return cm_IoctlFlushAllVolumes(&ioctlp->ioctl, userp, &req);
1349 smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1354 cm_ioctlQueryOptions_t *optionsp;
1355 afs_uint32 flags = 0;
1359 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1360 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1361 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1363 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1365 cm_SkipIoctlPath(&ioctlp->ioctl);
1366 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1367 optionsp->fid.vnode, optionsp->fid.unique);
1368 code = cm_GetSCache(&fid, &scp, userp, &req);
1370 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1375 code = cm_IoctlFlushVolume(&ioctlp->ioctl, userp, scp, &req);
1377 cm_ReleaseSCache(scp);
1383 smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1388 cm_ioctlQueryOptions_t *optionsp;
1389 afs_uint32 flags = 0;
1393 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1394 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1395 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1397 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1399 cm_SkipIoctlPath(&ioctlp->ioctl);
1400 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1401 optionsp->fid.vnode, optionsp->fid.unique);
1402 code = cm_GetSCache(&fid, &scp, userp, &req);
1404 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1409 code = cm_IoctlFlushFile(&ioctlp->ioctl, userp, scp, &req);
1411 cm_ReleaseSCache(scp);
1416 smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1424 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, 0);
1425 if (code) return code;
1427 code = cm_IoctlSetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
1428 cm_ReleaseSCache(scp);
1434 smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1438 cm_ioctlQueryOptions_t *optionsp;
1439 afs_uint32 flags = 0;
1444 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1445 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1446 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1448 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1450 cm_SkipIoctlPath(&ioctlp->ioctl);
1451 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1452 optionsp->fid.vnode, optionsp->fid.unique);
1453 code = cm_GetSCache(&fid, &scp, userp, &req);
1455 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1460 code = cm_IoctlGetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
1462 cm_ReleaseSCache(scp);
1468 smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1473 cm_ioctlQueryOptions_t * optionsp;
1474 afs_uint32 flags = 0;
1478 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1479 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1480 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1482 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1486 code = cm_IoctlGetFid(&ioctlp->ioctl, userp, scp, &req);
1488 cm_ReleaseSCache(scp);
1494 smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1499 cm_ioctlQueryOptions_t * optionsp;
1500 afs_uint32 flags = 0;
1504 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1505 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1506 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1508 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1510 cm_SkipIoctlPath(&ioctlp->ioctl);
1511 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1512 optionsp->fid.vnode, optionsp->fid.unique);
1513 code = cm_GetSCache(&fid, &scp, userp, &req);
1515 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1520 code = cm_IoctlGetFileType(&ioctlp->ioctl, userp, scp, &req);
1522 cm_ReleaseSCache(scp);
1528 smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1533 cm_ioctlQueryOptions_t *optionsp;
1534 afs_uint32 flags = 0;
1538 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1539 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1540 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1542 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1544 cm_SkipIoctlPath(&ioctlp->ioctl);
1545 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1546 optionsp->fid.vnode, optionsp->fid.unique);
1547 code = cm_GetSCache(&fid, &scp, userp, &req);
1549 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1554 code = cm_IoctlGetOwner(&ioctlp->ioctl, userp, scp, &req);
1556 cm_ReleaseSCache(scp);
1562 smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1567 cm_ioctlQueryOptions_t *optionsp;
1568 afs_uint32 flags = 0;
1572 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1573 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1574 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1576 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1578 cm_SkipIoctlPath(&ioctlp->ioctl);
1579 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1580 optionsp->fid.vnode, optionsp->fid.unique);
1581 code = cm_GetSCache(&fid, &scp, userp, &req);
1583 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1588 code = cm_IoctlWhereIs(&ioctlp->ioctl, userp, scp, &req);
1590 cm_ReleaseSCache(scp);
1597 smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1605 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1609 code = cm_IoctlStatMountPoint(&ioctlp->ioctl, userp, dscp, &req);
1611 cm_ReleaseSCache(dscp);
1617 smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1625 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1629 code = cm_IoctlDeleteMountPoint(&ioctlp->ioctl, userp, dscp, &req);
1631 cm_ReleaseSCache(dscp);
1637 smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1639 cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
1641 return cm_IoctlCheckServers(&ioctlp->ioctl, userp);
1645 smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1647 /* we don't print anything superfluous, so we don't support the gag call */
1648 return CM_ERROR_INVAL;
1652 smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1654 cm_SkipIoctlPath(&ioctlp->ioctl);
1656 return cm_IoctlCheckVolumes(&ioctlp->ioctl, userp);
1659 afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1661 cm_SkipIoctlPath(&ioctlp->ioctl);
1663 return cm_IoctlSetCacheSize(&ioctlp->ioctl, userp);
1668 smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1670 cm_SkipIoctlPath(&ioctlp->ioctl);
1672 return cm_IoctlTraceControl(&ioctlp->ioctl, userp);
1676 smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1678 cm_SkipIoctlPath(&ioctlp->ioctl);
1680 return cm_IoctlGetCacheParms(&ioctlp->ioctl, userp);
1684 smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1686 cm_SkipIoctlPath(&ioctlp->ioctl);
1688 return cm_IoctlGetCell(&ioctlp->ioctl, userp);
1692 smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1694 cm_SkipIoctlPath(&ioctlp->ioctl);
1696 return cm_IoctlNewCell(&ioctlp->ioctl, userp);
1700 smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1702 cm_SkipIoctlPath(&ioctlp->ioctl);
1704 return cm_IoctlNewCell2(&ioctlp->ioctl, userp);
1708 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1710 cm_SkipIoctlPath(&ioctlp->ioctl);
1712 return cm_IoctlGetWsCell(&ioctlp->ioctl, userp);
1716 smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1718 cm_SkipIoctlPath(&ioctlp->ioctl);
1720 return cm_IoctlSysName(&ioctlp->ioctl, userp);
1724 smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1726 cm_SkipIoctlPath(&ioctlp->ioctl);
1728 return cm_IoctlGetCellStatus(&ioctlp->ioctl, userp);
1732 smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1734 cm_SkipIoctlPath(&ioctlp->ioctl);
1736 return cm_IoctlSetCellStatus(&ioctlp->ioctl, userp);
1740 smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1742 cm_SkipIoctlPath(&ioctlp->ioctl);
1744 return cm_IoctlSetSPrefs(&ioctlp->ioctl, userp);
1748 smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1750 cm_SkipIoctlPath(&ioctlp->ioctl);
1752 return cm_IoctlGetSPrefs(&ioctlp->ioctl, userp);
1756 smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1758 /* we ignore default asynchrony since we only have one way
1759 * of doing this today.
1765 smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1769 clientchar_t leaf[LEAF_SIZE];
1774 code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
1778 code = cm_IoctlCreateMountPoint(&ioctlp->ioctl, userp, dscp, &req, leaf);
1780 cm_ReleaseSCache(dscp);
1785 smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1789 clientchar_t leaf[LEAF_SIZE];
1794 code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
1795 if (code) return code;
1797 code = cm_IoctlSymlink(&ioctlp->ioctl, userp, dscp, &req, leaf);
1799 cm_ReleaseSCache(dscp);
1805 smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1813 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1814 if (code) return code;
1816 code = cm_IoctlListlink(&ioctlp->ioctl, userp, dscp, &req);
1818 cm_ReleaseSCache(dscp);
1823 smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1824 {/*CHECK FOR VALID SYMLINK*/
1831 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1832 if (code) return code;
1834 code = cm_IoctlIslink(&ioctlp->ioctl, userp, dscp, &req);
1836 cm_ReleaseSCache(dscp);
1842 smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1850 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1851 if (code) return code;
1853 code = cm_IoctlDeletelink(&ioctlp->ioctl, userp, dscp, &req);
1855 cm_ReleaseSCache(dscp);
1861 smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1863 cm_SkipIoctlPath(&ioctlp->ioctl);
1865 return cm_IoctlGetTokenIter(&ioctlp->ioctl, userp);
1869 smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1871 cm_SkipIoctlPath(&ioctlp->ioctl);
1873 return cm_IoctlGetToken(&ioctlp->ioctl, userp);
1878 smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1880 cm_SkipIoctlPath(&ioctlp->ioctl);
1882 return cm_IoctlDelToken(&ioctlp->ioctl, userp);
1887 smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1889 cm_SkipIoctlPath(&ioctlp->ioctl);
1891 return cm_IoctlDelAllToken(&ioctlp->ioctl, userp);
1896 smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1898 cm_SkipIoctlPath(&ioctlp->ioctl);
1900 return cm_IoctlMakeSubmount(&ioctlp->ioctl, userp);
1904 smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1906 cm_SkipIoctlPath(&ioctlp->ioctl);
1908 return cm_IoctlGetRxkcrypt(&ioctlp->ioctl, userp);
1912 smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1914 cm_SkipIoctlPath(&ioctlp->ioctl);
1916 return cm_IoctlSetRxkcrypt(&ioctlp->ioctl, userp);
1920 smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1922 cm_SkipIoctlPath(&ioctlp->ioctl);
1924 return cm_IoctlRxStatProcess(&ioctlp->ioctl, userp);
1929 smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1931 cm_SkipIoctlPath(&ioctlp->ioctl);
1933 return cm_IoctlRxStatPeer(&ioctlp->ioctl, userp);
1937 smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1939 cm_SkipIoctlPath(&ioctlp->ioctl);
1941 return cm_IoctlUnicodeControl(&ioctlp->ioctl, userp);
1945 smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1947 cm_SkipIoctlPath(&ioctlp->ioctl);
1949 return cm_IoctlUUIDControl(&ioctlp->ioctl, userp);
1954 smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1956 cm_SkipIoctlPath(&ioctlp->ioctl);
1958 return cm_IoctlMemoryDump(&ioctlp->ioctl, userp);
1962 smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1967 cm_ioctlQueryOptions_t *optionsp;
1968 afs_uint32 flags = 0;
1972 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1973 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1974 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1976 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1978 cm_SkipIoctlPath(&ioctlp->ioctl);
1979 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1980 optionsp->fid.vnode, optionsp->fid.unique);
1981 code = cm_GetSCache(&fid, &scp, userp, &req);
1983 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1988 code = cm_IoctlPathAvailability(&ioctlp->ioctl, userp, scp, &req);
1989 cm_ReleaseSCache(scp);
1994 smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2000 cm_SkipIoctlPath(&ioctlp->ioctl);
2002 return cm_IoctlVolStatTest(&ioctlp->ioctl, userp, &req);
2008 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
2012 smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2017 cm_ioctlQueryOptions_t *optionsp;
2018 afs_uint32 flags = 0;
2022 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2024 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2025 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2027 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2029 cm_SkipIoctlPath(&ioctlp->ioctl);
2030 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2031 optionsp->fid.vnode, optionsp->fid.unique);
2032 code = cm_GetSCache(&fid, &scp, userp, &req);
2034 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2039 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
2042 code = cm_IoctlSetOwner(&ioctlp->ioctl, userp, scp, &req);
2044 cm_ReleaseSCache(scp);
2052 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
2056 smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2061 cm_ioctlQueryOptions_t *optionsp;
2062 afs_uint32 flags = 0;
2066 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2068 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2069 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2071 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2073 cm_SkipIoctlPath(&ioctlp->ioctl);
2074 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2075 optionsp->fid.vnode, optionsp->fid.unique);
2076 code = cm_GetSCache(&fid, &scp, userp, &req);
2078 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2083 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
2086 code = cm_IoctlSetGroup(&ioctlp->ioctl, userp, scp, &req);
2088 cm_ReleaseSCache(scp);
2095 smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2100 cm_ioctlQueryOptions_t *optionsp;
2101 afs_uint32 flags = 0;
2105 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2106 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2107 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2109 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2111 cm_SkipIoctlPath(&ioctlp->ioctl);
2112 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2113 optionsp->fid.vnode, optionsp->fid.unique);
2114 code = cm_GetSCache(&fid, &scp, userp, &req);
2116 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2121 code = cm_IoctlGetUnixMode(&ioctlp->ioctl, userp, scp, &req);
2123 cm_ReleaseSCache(scp);
2132 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
2135 smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2140 cm_ioctlQueryOptions_t *optionsp;
2141 afs_uint32 flags = 0;
2145 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2147 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2148 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2150 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2152 cm_SkipIoctlPath(&ioctlp->ioctl);
2153 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2154 optionsp->fid.vnode, optionsp->fid.unique);
2155 code = cm_GetSCache(&fid, &scp, userp, &req);
2157 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2162 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
2165 code = cm_IoctlSetUnixMode(&ioctlp->ioctl, userp, scp, &req);
2167 cm_ReleaseSCache(scp);