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;
99 /* called to make a fid structure into an IOCTL fid structure */
101 smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
104 cm_space_t *copyPrefix;
106 lock_ObtainMutex(&fidp->mx);
107 fidp->flags |= SMB_FID_IOCTL;
108 fidp->scp = &cm_data.fakeSCache;
109 cm_HoldSCache(fidp->scp);
110 if (fidp->ioctlp == NULL) {
111 iop = malloc(sizeof(*iop));
112 memset(iop, 0, sizeof(*iop));
117 copyPrefix = cm_GetSpace();
118 memcpy(copyPrefix->data, prefix->data, CM_UTILS_SPACESIZE);
119 fidp->ioctlp->prefix = copyPrefix;
121 lock_ReleaseMutex(&fidp->mx);
124 /* called when we receive a read call, does the send of the received data if
125 * this is the first read call. This is the function that actually makes the
126 * call to the ioctl code.
129 smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
132 smb_ioctlProc_t *procp = NULL;
135 if (ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN) {
136 ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAIN;
137 ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAOUT;
139 /* do the call now, or fail if we didn't get an opcode, or
140 * enough of an opcode.
142 if (ioctlp->ioctl.inCopied < sizeof(afs_int32))
143 return CM_ERROR_INVAL;
144 memcpy(&opcode, ioctlp->ioctl.inDatap, sizeof(afs_int32));
145 ioctlp->ioctl.inDatap += sizeof(afs_int32);
147 osi_Log1(afsd_logp, "smb_IoctlPrepareRead opcode 0x%x", opcode);
148 /* check for opcode out of bounds */
149 if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS) {
150 osi_Log0(afsd_logp, "smb_IoctlPrepareRead - invalid opcode");
151 return CM_ERROR_TOOBIG;
154 /* check for no such proc */
155 procp = smb_ioctlProcsp[opcode];
157 osi_Log0(afsd_logp, "smb_IoctlPrepareRead - unassigned opcode");
158 return CM_ERROR_INVAL;
160 /* otherwise, make the call */
161 ioctlp->ioctl.outDatap += sizeof(afs_int32); /* reserve room for return code */
162 code = (*procp)(ioctlp, userp, pflags);
163 osi_Log1(afsd_logp, "smb_IoctlPrepareRead operation returns code 0x%x", code);
165 /* copy in return code */
166 memcpy(ioctlp->ioctl.outAllocp, &code, sizeof(afs_int32));
167 } else if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAOUT)) {
168 osi_Log0(afsd_logp, "Ioctl invalid state - dataout expected");
169 return CM_ERROR_INVAL;
175 /* called when we receive a write call. If this is the first write call after
176 * a series of reads (or the very first call), then we start a new call.
177 * We also ensure that things are properly initialized for the start of a call.
180 smb_IoctlPrepareWrite(smb_fid_t *fidp, smb_ioctl_t *ioctlp)
182 /* make sure the buffer(s) are allocated */
183 if (!ioctlp->ioctl.inAllocp)
184 ioctlp->ioctl.inAllocp = malloc(SMB_IOCTL_MAXDATA);
185 if (!ioctlp->ioctl.outAllocp)
186 ioctlp->ioctl.outAllocp = malloc(SMB_IOCTL_MAXDATA);
188 /* Fixes fs la problem. We do a StrToOEM later and if this data isn't initialized we get memory issues. */
189 (void) memset(ioctlp->ioctl.inAllocp, 0, SMB_IOCTL_MAXDATA);
190 (void) memset(ioctlp->ioctl.outAllocp, 0, SMB_IOCTL_MAXDATA);
192 /* and make sure that we've reset our state for the new incoming request */
193 if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN)) {
194 ioctlp->ioctl.inCopied = 0;
195 ioctlp->ioctl.outCopied = 0;
196 ioctlp->ioctl.inDatap = ioctlp->ioctl.inAllocp;
197 ioctlp->ioctl.outDatap = ioctlp->ioctl.outAllocp;
198 ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAIN;
199 ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAOUT;
203 /* called from smb_ReceiveCoreRead when we receive a read on the ioctl fid */
205 smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
209 afs_int32 leftToCopy;
213 cm_user_t *userp = NULL;
218 count = smb_GetSMBParm(inp, 1);
220 /* Get the user and determine if it is the local machine account */
221 smbp = (smb_t *) inp;
222 uidp = smb_FindUID(vcp, smbp->uid, 0);
224 isSystem = smb_userIsLocalSystem(uidp);
225 userp = smb_GetUserFromUID(uidp);
227 osi_Log3(afsd_logp, "smb_IoctlRead uid %d user %x name %s",
229 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
231 osi_Log2(afsd_logp, "smb_IoctlRead uid %d user %x no name",
232 uidp->userID, userp);
234 smb_ReleaseUID(uidp);
236 osi_Log1(afsd_logp, "smb_IoctlRead no uid user %x no name", userp);
237 return CM_ERROR_BADSMB;
241 userp = cm_rootUserp;
246 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
248 cm_ReleaseUser(userp);
249 return CM_ERROR_NOSUCHPATH;
252 /* turn the connection around, if required */
253 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
256 cm_ReleaseUser(userp);
260 leftToCopy = (afs_int32)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
261 if (leftToCopy < 0) {
262 osi_Log0(afsd_logp, "smb_IoctlRead leftToCopy went negative");
263 cm_ReleaseUser(userp);
264 return CM_ERROR_INVAL;
266 if (count > leftToCopy)
269 /* now set the parms for a read of count bytes */
270 smb_SetSMBParm(outp, 0, count);
271 smb_SetSMBParm(outp, 1, 0);
272 smb_SetSMBParm(outp, 2, 0);
273 smb_SetSMBParm(outp, 3, 0);
274 smb_SetSMBParm(outp, 4, 0);
276 smb_SetSMBDataLength(outp, count+3);
278 op = smb_GetSMBData(outp, NULL);
280 *op++ = (char)(count & 0xff);
281 *op++ = (char)((count >> 8) & 0xff);
283 /* now copy the data into the response packet */
284 memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
286 /* and adjust the counters */
287 iop->ioctl.outCopied += count;
289 cm_ReleaseUser(userp);
294 /* called from smb_ReceiveCoreWrite when we receive a write call on the IOCTL
298 smb_IoctlWrite(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
304 int inDataBlockCount;
307 count = smb_GetSMBParm(inp, 1);
310 smb_IoctlPrepareWrite(fidp, iop);
312 op = smb_GetSMBData(inp, NULL);
313 op = smb_ParseDataBlock(op, NULL, &inDataBlockCount);
315 if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
316 code = CM_ERROR_TOOBIG;
321 memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
324 iop->ioctl.inCopied += count;
327 /* return # of bytes written */
329 smb_SetSMBParm(outp, 0, count);
330 smb_SetSMBDataLength(outp, 0);
336 /* called from smb_ReceiveV3WriteX when we receive a write call on the IOCTL
340 smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
346 int inDataBlockCount;
349 count = smb_GetSMBParm(inp, 10);
352 smb_IoctlPrepareWrite(fidp, iop);
354 op = inp->data + smb_GetSMBParm(inp, 11);
355 inDataBlockCount = count;
357 if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
358 code = CM_ERROR_TOOBIG;
363 memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
366 iop->ioctl.inCopied += count;
369 /* return # of bytes written */
371 smb_SetSMBParm(outp, 2, count);
372 smb_SetSMBParm(outp, 3, 0); /* reserved */
373 smb_SetSMBParm(outp, 4, 0); /* reserved */
374 smb_SetSMBParm(outp, 5, 0); /* reserved */
375 smb_SetSMBDataLength(outp, 0);
382 /* called from V3 read to handle IOCTL descriptor reads */
384 smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
387 unsigned short count;
396 count = smb_GetSMBParm(inp, 5);
398 /* Get the user and determine if it is the local machine account */
399 uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
401 isSystem = smb_userIsLocalSystem(uidp);
402 userp = smb_GetUserFromUID(uidp);
404 osi_Log3(afsd_logp, "smb_IoctlV3Read uid %d user %x name %s",
406 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
408 osi_Log2(afsd_logp, "smb_IoctlV3Read uid %d user %x no name",
409 uidp->userID, userp);
412 osi_Log0(afsd_logp, "smb_IoctlV3Read no uid");
413 return CM_ERROR_BADSMB;
417 userp = cm_rootUserp;
424 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
427 smb_ReleaseUID(uidp);
428 cm_ReleaseUser(userp);
429 return CM_ERROR_NOSUCHPATH;
432 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
435 smb_ReleaseUID(uidp);
438 cm_ReleaseUser(userp);
442 leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
443 if (leftToCopy < 0) {
444 osi_Log0(afsd_logp, "smb_IoctlV3Read leftToCopy went negative");
445 cm_ReleaseUser(userp);
446 return CM_ERROR_INVAL;
448 if (count > leftToCopy)
449 count = (unsigned short)leftToCopy;
451 /* 0 and 1 are reserved for request chaining, were setup by our caller,
452 * and will be further filled in after we return.
454 smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */
455 smb_SetSMBParm(outp, 3, 0); /* resvd */
456 smb_SetSMBParm(outp, 4, 0); /* resvd */
457 smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */
458 /* fill in #6 when we have all the parameters' space reserved */
459 smb_SetSMBParm(outp, 7, 0); /* resv'd */
460 smb_SetSMBParm(outp, 8, 0); /* resv'd */
461 smb_SetSMBParm(outp, 9, 0); /* resv'd */
462 smb_SetSMBParm(outp, 10, 0); /* resv'd */
463 smb_SetSMBParm(outp, 11, 0); /* reserved */
465 /* get op ptr after putting in the last parm, since otherwise we don't
466 * know where the data really is.
468 op = smb_GetSMBData(outp, NULL);
470 /* now fill in offset from start of SMB header to first data byte (to op) */
471 smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
473 /* set the packet data length the count of the # of bytes */
474 smb_SetSMBDataLength(outp, count);
476 /* now copy the data into the response packet */
477 memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
479 /* and adjust the counters */
480 iop->ioctl.outCopied += count;
482 /* and cleanup things */
483 cm_ReleaseUser(userp);
488 /* called from Read Raw to handle IOCTL descriptor reads */
490 smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
503 /* Get the user and determine if it is the local machine account */
504 uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
506 isSystem = smb_userIsLocalSystem(uidp);
507 userp = smb_GetUserFromUID(uidp);
509 osi_Log3(afsd_logp, "smb_IoctlRawRead uid %d user %x name %s",
511 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
513 osi_Log2(afsd_logp, "smb_IoctlRawRead uid %d user %x no name",
514 uidp->userID, userp);
516 smb_ReleaseUID(uidp);
518 osi_Log0(afsd_logp, "smb_IoctlRawRead no uid");
522 userp = cm_rootUserp;
526 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
528 code = CM_ERROR_NOSUCHPATH;
532 code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
537 leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
538 if (leftToCopy < 0) {
539 osi_Log0(afsd_logp, "smb_IoctlReadRaw leftToCopy went negative");
540 code = CM_ERROR_INVAL;
545 memset(ncbp, 0, sizeof(NCB));
547 ncbp->ncb_length = (unsigned short) leftToCopy;
548 ncbp->ncb_lsn = (unsigned char) vcp->lsn;
549 ncbp->ncb_command = NCBSEND;
550 /*ncbp->ncb_lana_num = smb_LANadapter;*/
551 ncbp->ncb_lana_num = vcp->lana;
553 ncbp->ncb_buffer = iop->ioctl.outCopied + iop->ioctl.outAllocp;
554 code = Netbios(ncbp);
557 osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
560 cm_ReleaseUser(userp);
565 /* parse the passed-in file name and do a namei on it. If we fail,
566 * return an error code, otherwise return the vnode located in *scpp.
568 #define CM_PARSE_FLAG_LITERAL 1
571 smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
572 cm_scache_t **scpp, afs_uint32 flags)
575 cm_scache_t *substRootp = NULL;
576 cm_scache_t *iscp = NULL;
578 clientchar_t *relativePath = NULL;
579 clientchar_t *lastComponent = NULL;
580 afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
582 inPath = ioctlp->ioctl.inDatap;
583 /* setup the next data value for the caller to use */
584 ioctlp->ioctl.inDatap += (long)strlen(ioctlp->ioctl.inDatap) + 1;
586 osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,inPath));
588 /* This is usually the file name, but for StatMountPoint it is the path. */
589 /* ioctlp->ioctl.inDatap can be either of the form:
592 * \\netbios-name\submount\path\.
593 * \\netbios-name\submount\path\file
596 /* We do not perform path name translation on the ioctl path data
597 * because these paths were not translated by Windows through the
598 * file system API. Therefore, they are not OEM characters but
599 * whatever the display character set is.
602 // TranslateExtendedChars(relativePath);
604 /* This is usually nothing, but for StatMountPoint it is the file name. */
605 // TranslateExtendedChars(ioctlp->ioctl.inDatap);
607 /* If the string starts with our UTF-8 prefix (which is the
608 sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
609 strings), we assume that the provided path is UTF-8. Otherwise
610 we have to convert the string to UTF-8, since that is what we
611 want to use everywhere else.*/
613 if (memcmp(inPath, utf8_prefix, utf8_prefix_size) == 0) {
614 /* String is UTF-8 */
615 inPath += utf8_prefix_size;
616 ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
618 relativePath = cm_Utf8ToClientStringAlloc(inPath, -1, NULL);
622 /* Not a UTF-8 string */
623 /* TODO: If this is an OEM string, we should convert it to
625 if (smb_StoreAnsiFilenames) {
626 cch = cm_AnsiToClientString(inPath, -1, NULL, 0);
630 relativePath = malloc(cch * sizeof(clientchar_t));
631 cm_AnsiToClientString(inPath, -1, relativePath, cch);
633 TranslateExtendedChars(inPath);
635 cch = cm_OemToClientString(inPath, -1, NULL, 0);
639 relativePath = malloc(cch * sizeof(clientchar_t));
640 cm_OemToClientString(inPath, -1, relativePath, cch);
644 if (relativePath[0] == relativePath[1] &&
645 relativePath[1] == '\\' &&
646 !cm_ClientStrCmpNI(cm_NetbiosNameC, relativePath+2,
647 cm_ClientStrLen(cm_NetbiosNameC)))
649 clientchar_t shareName[256];
650 clientchar_t *sharePath;
653 /* We may have found a UNC path.
654 * If the first component is the NetbiosName,
655 * then throw out the second component (the submount)
656 * since it had better expand into the value of ioctl->tidPathp
659 p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1; /* buffer overflow vuln.? */
660 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
663 for (i = 0; *p && *p != '\\'; i++,p++ ) {
666 p++; /* skip past trailing slash */
667 shareName[i] = 0; /* terminate string */
669 shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
671 /* we found a sharename, therefore use the resulting path */
672 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
673 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
674 userp, sharePath, reqp, &substRootp);
677 osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code);
683 lastComponent = cm_ClientStrRChr(p, '\\');
684 if (lastComponent && (lastComponent - p) > 1 &&
685 cm_ClientStrLen(lastComponent) > 1) {
686 *lastComponent = '\0';
689 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
690 userp, NULL, reqp, &iscp);
692 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
693 userp, NULL, reqp, scpp);
695 cm_ReleaseSCache(iscp);
697 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
698 userp, NULL, reqp, scpp);
700 cm_ReleaseSCache(substRootp);
702 osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code);
708 /* otherwise, treat the name as a cellname mounted off the afs root.
709 * This requires that we reconstruct the shareName string with
710 * leading and trailing slashes.
712 p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
713 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
717 for (i = 1; *p && *p != '\\'; i++,p++ ) {
720 p++; /* skip past trailing slash */
721 shareName[i++] = '/'; /* add trailing slash */
722 shareName[i] = 0; /* terminate string */
725 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
726 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
727 userp, shareName, reqp, &substRootp);
729 osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code);
735 lastComponent = cm_ClientStrRChr(p, '\\');
736 if (lastComponent && (lastComponent - p) > 1 &&
737 cm_ClientStrLen(lastComponent) > 1) {
738 *lastComponent = '\0';
741 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
742 userp, NULL, reqp, &iscp);
744 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
745 userp, NULL, reqp, scpp);
747 cm_ReleaseSCache(iscp);
749 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
750 userp, NULL, reqp, scpp);
754 cm_ReleaseSCache(substRootp);
755 osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code);
762 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
763 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
764 userp, ioctlp->tidPathp, reqp, &substRootp);
766 osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code);
772 lastComponent = cm_ClientStrRChr(relativePath, '\\');
773 if (lastComponent && (lastComponent - relativePath) > 1 &&
774 cm_ClientStrLen(lastComponent) > 1) {
775 *lastComponent = '\0';
778 code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
779 userp, NULL, reqp, &iscp);
781 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
782 userp, NULL, reqp, scpp);
784 cm_ReleaseSCache(iscp);
786 code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | follow,
787 userp, NULL, reqp, scpp);
790 cm_ReleaseSCache(substRootp);
791 osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code);
799 cm_ReleaseSCache(substRootp);
804 /* Ensure that the status object is up to date */
805 lock_ObtainWrite(&(*scpp)->rw);
806 code = cm_SyncOp( *scpp, NULL, userp, reqp, 0,
807 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
809 cm_SyncOpDone( *scpp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
810 lock_ReleaseWrite(&(*scpp)->rw);
812 /* and return success */
813 osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
819 #define LEAF_SIZE 256
820 /* parse the passed-in file name and do a namei on its parent. If we fail,
821 * return an error code, otherwise return the vnode located in *scpp.
824 smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
825 cm_scache_t **scpp, clientchar_t *leafp)
828 clientchar_t tbuffer[1024];
829 clientchar_t *tp, *jp;
830 cm_scache_t *substRootp = NULL;
831 clientchar_t *inpathp = NULL;
834 inpathdatap = ioctlp->ioctl.inDatap;
836 /* If the string starts with our UTF-8 prefix (which is the
837 sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
838 strings), we assume that the provided path is UTF-8. Otherwise
839 we have to convert the string to UTF-8, since that is what we
840 want to use everywhere else.*/
842 if (memcmp(inpathdatap, utf8_prefix, utf8_prefix_size) == 0) {
844 /* String is UTF-8 */
845 inpathdatap += utf8_prefix_size;
846 ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
848 inpathp = cm_Utf8ToClientStringAlloc(inpathdatap, -1, NULL);
852 /* Not a UTF-8 string */
853 /* TODO: If this is an OEM string, we should convert it to
855 if (smb_StoreAnsiFilenames) {
856 cch = cm_AnsiToClientString(inpathdatap, -1, NULL, 0);
860 inpathp = malloc(cch * sizeof(clientchar_t));
861 cm_AnsiToClientString(inpathdatap, -1, inpathp, cch);
863 TranslateExtendedChars(inpathdatap);
865 cch = cm_OemToClientString(inpathdatap, -1, NULL, 0);
869 inpathp = malloc(cch * sizeof(clientchar_t));
870 cm_OemToClientString(inpathdatap, -1, inpathp, cch);
874 cm_ClientStrCpy(tbuffer, lengthof(tbuffer), inpathp);
875 tp = cm_ClientStrRChr(tbuffer, '\\');
876 jp = cm_ClientStrRChr(tbuffer, '/');
879 else if (jp && (tp - tbuffer) < (jp - tbuffer))
882 cm_ClientStrCpy(tbuffer, lengthof(tbuffer), _C("\\"));
884 cm_ClientStrCpy(leafp, LEAF_SIZE, inpathp);
889 cm_ClientStrCpy(leafp, LEAF_SIZE, tp+1);
893 inpathp = NULL; /* We don't need this from this point on */
895 if (tbuffer[0] == tbuffer[1] &&
896 tbuffer[1] == '\\' &&
897 !cm_ClientStrCmpNI(cm_NetbiosNameC, tbuffer+2,
898 cm_ClientStrLen(cm_NetbiosNameC)))
900 clientchar_t shareName[256];
901 clientchar_t *sharePath;
904 /* We may have found a UNC path.
905 * If the first component is the NetbiosName,
906 * then throw out the second component (the submount)
907 * since it had better expand into the value of ioctl->tidPathp
910 p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
911 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
914 for (i = 0; *p && *p != '\\'; i++,p++ ) {
917 p++; /* skip past trailing slash */
918 shareName[i] = 0; /* terminate string */
920 shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
922 /* we found a sharename, therefore use the resulting path */
923 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
924 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
925 userp, sharePath, reqp, &substRootp);
927 if (code) return code;
929 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
930 userp, NULL, reqp, scpp);
931 cm_ReleaseSCache(substRootp);
932 if (code) return code;
934 /* otherwise, treat the name as a cellname mounted off the afs root.
935 * This requires that we reconstruct the shareName string with
936 * leading and trailing slashes.
938 p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
939 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
943 for (i = 1; *p && *p != '\\'; i++,p++ ) {
946 p++; /* skip past trailing slash */
947 shareName[i++] = '/'; /* add trailing slash */
948 shareName[i] = 0; /* terminate string */
950 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
951 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
952 userp, shareName, reqp, &substRootp);
953 if (code) return code;
955 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
956 userp, NULL, reqp, scpp);
957 cm_ReleaseSCache(substRootp);
958 if (code) return code;
961 code = cm_NameI(cm_RootSCachep(userp, reqp), ioctlp->prefix->wdata,
962 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
963 userp, ioctlp->tidPathp, reqp, &substRootp);
964 if (code) return code;
966 code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
967 userp, NULL, reqp, scpp);
968 cm_ReleaseSCache(substRootp);
969 if (code) return code;
972 /* # of bytes of path */
973 code = (long)strlen(ioctlp->ioctl.inDatap) + 1;
974 ioctlp->ioctl.inDatap += code;
976 /* Ensure that the status object is up to date */
977 lock_ObtainWrite(&(*scpp)->rw);
978 code = cm_SyncOp( *scpp, NULL, userp, reqp, 0,
979 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
981 cm_SyncOpDone( *scpp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
982 lock_ReleaseWrite(&(*scpp)->rw);
984 /* and return success */
989 smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
996 struct ClearToken ct;
1002 int release_userp = 0;
1003 clientchar_t *uname = NULL;
1004 clientchar_t *smbname = NULL;
1005 clientchar_t *wdir = NULL;
1006 clientchar_t *rpc_sid = NULL;
1009 saveDataPtr = ioctlp->ioctl.inDatap;
1011 cm_SkipIoctlPath(&ioctlp->ioctl);
1013 tp = ioctlp->ioctl.inDatap;
1016 memcpy(&ticketLen, tp, sizeof(ticketLen));
1017 tp += sizeof(ticketLen);
1018 if (ticketLen < MINKTCTICKETLEN || ticketLen > MAXKTCTICKETLEN)
1019 return CM_ERROR_INVAL;
1021 /* remember ticket and skip over it for now */
1025 /* clear token size */
1026 memcpy(&ctSize, tp, sizeof(ctSize));
1027 tp += sizeof(ctSize);
1028 if (ctSize != sizeof(struct ClearToken))
1029 return CM_ERROR_INVAL;
1032 memcpy(&ct, tp, ctSize);
1034 if (ct.AuthHandle == -1)
1035 ct.AuthHandle = 999; /* more rxvab compat stuff */
1037 /* more stuff, if any */
1038 if (ioctlp->ioctl.inCopied > tp - saveDataPtr) {
1039 /* flags: logon flag */
1040 memcpy(&flags, tp, sizeof(int));
1045 fschar_t * cellnamep;
1046 clientchar_t * temp;
1048 temp = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1049 cellnamep = cm_ClientStringToFsStringAlloc(temp, -1, NULL);
1050 cellp = cm_GetCell(cellnamep, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
1056 code = CM_ERROR_NOSUCHCELL;
1059 tp += strlen(tp) + 1;
1062 uname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1063 tp += strlen(tp) + 1;
1065 if (flags & PIOCTL_LOGON) {
1066 /* SMB user name with which to associate tokens */
1067 smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
1068 osi_Log2(smb_logp,"smb_IoctlSetToken for user [%S] smbname [%S]",
1069 osi_LogSaveClientString(smb_logp,uname),
1070 osi_LogSaveClientString(smb_logp,smbname));
1071 fprintf(stderr, "SMB name = %S\n", smbname);
1072 tp += strlen(tp) + 1;
1074 osi_Log1(smb_logp,"smb_IoctlSetToken for user [%S]",
1075 osi_LogSaveClientString(smb_logp, uname));
1079 memcpy(&uuid, tp, sizeof(uuid));
1080 if (!cm_FindTokenEvent(uuid, sessionKey, &rpc_sid)) {
1081 code = CM_ERROR_INVAL;
1085 if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && rpc_sid) {
1086 osi_Log1(smb_logp,"smb_IoctlSetToken Rpc Sid [%S]",
1087 osi_LogSaveClientString(smb_logp, rpc_sid));
1088 if (!cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, rpc_sid))
1089 pflags |= AFSCALL_FLAG_LOCAL_SYSTEM;
1092 if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1093 code = CM_ERROR_NOACCESS;
1097 cellp = cm_data.rootCellp;
1098 osi_Log0(smb_logp,"smb_IoctlSetToken - no name specified");
1101 if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1103 DWORD dwSize1 = 0, dwSize2 = 0;
1104 wchar_t *pszRefDomain = NULL;
1105 SID_NAME_USE snu = SidTypeGroup;
1106 clientchar_t * secSidString = NULL;
1110 * The specified smbname is may not be a SID for the user.
1111 * See if we can obtain the SID for the specified name.
1112 * If we can, use that instead of the name provided.
1115 LookupAccountNameW( NULL /* System Name to begin Search */,
1120 gle = GetLastError();
1121 if (gle == ERROR_INSUFFICIENT_BUFFER) {
1122 pSid = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, dwSize1);
1124 * Although dwSize2 is supposed to include the terminating
1125 * NUL character, on Win7 it does not.
1127 pszRefDomain = malloc((dwSize2 + 1) * sizeof(wchar_t));
1130 if ( pSid && pszRefDomain ) {
1131 if (LookupAccountNameW( NULL /* System Name to begin Search */,
1134 pszRefDomain, &dwSize2,
1136 ConvertSidToStringSidW(pSid, &secSidString);
1140 userp = smb_FindCMUserBySID( secSidString, ioctlp->fidp->vcp->rname,
1141 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1142 LocalFree(secSidString);
1144 /* Free the SID so we can reuse the variable */
1151 * If the SID for the name could not be found,
1152 * perhaps it already is a SID
1154 if (!ConvertStringSidToSidW( smbname, &pSid)) {
1155 userp = smb_FindCMUserBySID( smbname, ioctlp->fidp->vcp->rname,
1156 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1158 userp = smb_FindCMUserByName( smbname, ioctlp->fidp->vcp->rname,
1159 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1171 /* store the token */
1172 lock_ObtainMutex(&userp->mx);
1173 ucellp = cm_GetUCell(userp, cellp);
1174 osi_Log1(smb_logp,"smb_IoctlSetToken ucellp %lx", ucellp);
1175 ucellp->ticketLen = ticketLen;
1176 if (ucellp->ticketp)
1177 free(ucellp->ticketp); /* Discard old token if any */
1178 ucellp->ticketp = malloc(ticketLen);
1179 memcpy(ucellp->ticketp, ticket, ticketLen);
1181 * Get the session key from the RPC, rather than from the pioctl.
1184 memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey));
1186 memcpy(ucellp->sessionKey.data, sessionKey, sizeof(sessionKey));
1187 ucellp->kvno = ct.AuthHandle;
1188 ucellp->expirationTime = ct.EndTimestamp;
1191 ucellp->uid = ANONYMOUSID;
1194 cm_ClientStringToFsString(uname, -1, ucellp->userName, MAXKTCNAMELEN);
1196 cm_UsernameToId(uname, ucellp, &ucellp->uid);
1199 ucellp->flags |= CM_UCELLFLAG_RXKAD;
1200 lock_ReleaseMutex(&userp->mx);
1202 if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
1203 ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
1206 cm_ResetACLCache(cellp, userp);
1209 SecureZeroMemory(sessionKey, sizeof(sessionKey));
1212 cm_ReleaseUser(userp);
1226 smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1228 smb_user_t *uidp = ioctlp->uidp;
1230 if (uidp && uidp->unp) {
1233 cch = cm_ClientStringToUtf8(uidp->unp->name,
1235 ioctlp->ioctl.outDatap,
1236 (SMB_IOCTL_MAXDATA -
1237 (ioctlp->ioctl.outDatap - ioctlp->ioctl.outAllocp))
1238 / sizeof(cm_utf8char_t));
1240 ioctlp->ioctl.outDatap += cch * sizeof(cm_utf8char_t);
1247 smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1252 cm_ioctlQueryOptions_t *optionsp;
1253 afs_uint32 flags = 0;
1257 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1258 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1259 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1261 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1263 cm_SkipIoctlPath(&ioctlp->ioctl);
1264 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1265 optionsp->fid.vnode, optionsp->fid.unique);
1266 code = cm_GetSCache(&fid, &scp, userp, &req);
1268 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1274 code = cm_IoctlGetACL(&ioctlp->ioctl, userp, scp, &req);
1276 cm_ReleaseSCache(scp);
1281 smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1286 afs_uint32 flags = 0;
1290 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1294 code = cm_IoctlSetACL(&ioctlp->ioctl, userp, scp, &req);
1296 cm_ReleaseSCache(scp);
1301 smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1306 cm_ioctlQueryOptions_t *optionsp;
1307 afs_uint32 flags = 0;
1311 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1312 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1313 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1315 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1317 cm_SkipIoctlPath(&ioctlp->ioctl);
1318 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1319 optionsp->fid.vnode, optionsp->fid.unique);
1320 code = cm_GetSCache(&fid, &scp, userp, &req);
1322 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1327 code = cm_IoctlGetFileCellName(&ioctlp->ioctl, userp, scp, &req);
1329 cm_ReleaseSCache(scp);
1335 smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1341 cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
1343 return cm_IoctlFlushAllVolumes(&ioctlp->ioctl, userp, &req);
1347 smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1352 cm_ioctlQueryOptions_t *optionsp;
1353 afs_uint32 flags = 0;
1357 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1358 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1359 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1361 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1363 cm_SkipIoctlPath(&ioctlp->ioctl);
1364 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1365 optionsp->fid.vnode, optionsp->fid.unique);
1366 code = cm_GetSCache(&fid, &scp, userp, &req);
1368 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1373 code = cm_IoctlFlushVolume(&ioctlp->ioctl, userp, scp, &req);
1375 cm_ReleaseSCache(scp);
1381 smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1386 cm_ioctlQueryOptions_t *optionsp;
1387 afs_uint32 flags = 0;
1391 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1392 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1393 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1395 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1397 cm_SkipIoctlPath(&ioctlp->ioctl);
1398 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1399 optionsp->fid.vnode, optionsp->fid.unique);
1400 code = cm_GetSCache(&fid, &scp, userp, &req);
1402 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1407 code = cm_IoctlFlushFile(&ioctlp->ioctl, userp, scp, &req);
1409 cm_ReleaseSCache(scp);
1414 smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1422 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, 0);
1423 if (code) return code;
1425 code = cm_IoctlSetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
1426 cm_ReleaseSCache(scp);
1432 smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1436 cm_ioctlQueryOptions_t *optionsp;
1437 afs_uint32 flags = 0;
1442 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1443 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1444 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1446 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1448 cm_SkipIoctlPath(&ioctlp->ioctl);
1449 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1450 optionsp->fid.vnode, optionsp->fid.unique);
1451 code = cm_GetSCache(&fid, &scp, userp, &req);
1453 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1458 code = cm_IoctlGetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
1460 cm_ReleaseSCache(scp);
1466 smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1471 cm_ioctlQueryOptions_t * optionsp;
1472 afs_uint32 flags = 0;
1476 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1477 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1478 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1480 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1484 code = cm_IoctlGetFid(&ioctlp->ioctl, userp, scp, &req);
1486 cm_ReleaseSCache(scp);
1492 smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1497 cm_ioctlQueryOptions_t * optionsp;
1498 afs_uint32 flags = 0;
1502 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1503 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1504 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1506 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1508 cm_SkipIoctlPath(&ioctlp->ioctl);
1509 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1510 optionsp->fid.vnode, optionsp->fid.unique);
1511 code = cm_GetSCache(&fid, &scp, userp, &req);
1513 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1518 code = cm_IoctlGetFileType(&ioctlp->ioctl, userp, scp, &req);
1520 cm_ReleaseSCache(scp);
1526 smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1531 cm_ioctlQueryOptions_t *optionsp;
1532 afs_uint32 flags = 0;
1536 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1537 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1538 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1540 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1542 cm_SkipIoctlPath(&ioctlp->ioctl);
1543 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1544 optionsp->fid.vnode, optionsp->fid.unique);
1545 code = cm_GetSCache(&fid, &scp, userp, &req);
1547 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1552 code = cm_IoctlGetOwner(&ioctlp->ioctl, userp, scp, &req);
1554 cm_ReleaseSCache(scp);
1560 smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1565 cm_ioctlQueryOptions_t *optionsp;
1566 afs_uint32 flags = 0;
1570 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1571 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1572 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1574 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1576 cm_SkipIoctlPath(&ioctlp->ioctl);
1577 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1578 optionsp->fid.vnode, optionsp->fid.unique);
1579 code = cm_GetSCache(&fid, &scp, userp, &req);
1581 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1586 code = cm_IoctlWhereIs(&ioctlp->ioctl, userp, scp, &req);
1588 cm_ReleaseSCache(scp);
1595 smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1603 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1607 code = cm_IoctlStatMountPoint(&ioctlp->ioctl, userp, dscp, &req);
1609 cm_ReleaseSCache(dscp);
1615 smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1623 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1627 code = cm_IoctlDeleteMountPoint(&ioctlp->ioctl, userp, dscp, &req);
1629 cm_ReleaseSCache(dscp);
1635 smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1637 cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
1639 return cm_IoctlCheckServers(&ioctlp->ioctl, userp);
1643 smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1645 /* we don't print anything superfluous, so we don't support the gag call */
1646 return CM_ERROR_INVAL;
1650 smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1652 cm_SkipIoctlPath(&ioctlp->ioctl);
1654 return cm_IoctlCheckVolumes(&ioctlp->ioctl, userp);
1657 afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1659 cm_SkipIoctlPath(&ioctlp->ioctl);
1661 return cm_IoctlSetCacheSize(&ioctlp->ioctl, userp);
1666 smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1668 cm_SkipIoctlPath(&ioctlp->ioctl);
1670 return cm_IoctlTraceControl(&ioctlp->ioctl, userp);
1674 smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1676 cm_SkipIoctlPath(&ioctlp->ioctl);
1678 return cm_IoctlGetCacheParms(&ioctlp->ioctl, userp);
1682 smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1684 cm_SkipIoctlPath(&ioctlp->ioctl);
1686 return cm_IoctlGetCell(&ioctlp->ioctl, userp);
1690 smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1692 cm_SkipIoctlPath(&ioctlp->ioctl);
1694 return cm_IoctlNewCell(&ioctlp->ioctl, userp);
1698 smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1700 cm_SkipIoctlPath(&ioctlp->ioctl);
1702 return cm_IoctlNewCell2(&ioctlp->ioctl, userp);
1706 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
1708 cm_SkipIoctlPath(&ioctlp->ioctl);
1710 return cm_IoctlGetWsCell(&ioctlp->ioctl, userp);
1714 smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1716 cm_SkipIoctlPath(&ioctlp->ioctl);
1718 return cm_IoctlSysName(&ioctlp->ioctl, userp);
1722 smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1724 cm_SkipIoctlPath(&ioctlp->ioctl);
1726 return cm_IoctlGetCellStatus(&ioctlp->ioctl, userp);
1730 smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1732 cm_SkipIoctlPath(&ioctlp->ioctl);
1734 return cm_IoctlSetCellStatus(&ioctlp->ioctl, userp);
1738 smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1740 cm_SkipIoctlPath(&ioctlp->ioctl);
1742 return cm_IoctlSetSPrefs(&ioctlp->ioctl, userp);
1746 smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1748 cm_SkipIoctlPath(&ioctlp->ioctl);
1750 return cm_IoctlGetSPrefs(&ioctlp->ioctl, userp);
1754 smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1756 /* we ignore default asynchrony since we only have one way
1757 * of doing this today.
1763 smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1767 clientchar_t leaf[LEAF_SIZE];
1772 code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
1776 code = cm_IoctlCreateMountPoint(&ioctlp->ioctl, userp, dscp, &req, leaf);
1778 cm_ReleaseSCache(dscp);
1783 smb_IoctlSymlink(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);
1793 if (code) return code;
1795 code = cm_IoctlSymlink(&ioctlp->ioctl, userp, dscp, &req, leaf);
1797 cm_ReleaseSCache(dscp);
1803 smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1811 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1812 if (code) return code;
1814 code = cm_IoctlListlink(&ioctlp->ioctl, userp, dscp, &req);
1816 cm_ReleaseSCache(dscp);
1821 smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1822 {/*CHECK FOR VALID SYMLINK*/
1829 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1830 if (code) return code;
1832 code = cm_IoctlIslink(&ioctlp->ioctl, userp, dscp, &req);
1834 cm_ReleaseSCache(dscp);
1840 smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1848 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1849 if (code) return code;
1851 code = cm_IoctlDeletelink(&ioctlp->ioctl, userp, dscp, &req);
1853 cm_ReleaseSCache(dscp);
1859 smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1861 cm_SkipIoctlPath(&ioctlp->ioctl);
1863 return cm_IoctlGetTokenIter(&ioctlp->ioctl, userp);
1867 smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1869 cm_SkipIoctlPath(&ioctlp->ioctl);
1871 return cm_IoctlGetToken(&ioctlp->ioctl, userp);
1876 smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1878 cm_SkipIoctlPath(&ioctlp->ioctl);
1880 return cm_IoctlDelToken(&ioctlp->ioctl, userp);
1885 smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1887 cm_SkipIoctlPath(&ioctlp->ioctl);
1889 return cm_IoctlDelAllToken(&ioctlp->ioctl, userp);
1894 smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1896 cm_SkipIoctlPath(&ioctlp->ioctl);
1898 return cm_IoctlMakeSubmount(&ioctlp->ioctl, userp);
1902 smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1904 cm_SkipIoctlPath(&ioctlp->ioctl);
1906 return cm_IoctlGetRxkcrypt(&ioctlp->ioctl, userp);
1910 smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1912 cm_SkipIoctlPath(&ioctlp->ioctl);
1914 return cm_IoctlSetRxkcrypt(&ioctlp->ioctl, userp);
1918 smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1920 cm_SkipIoctlPath(&ioctlp->ioctl);
1922 return cm_IoctlRxStatProcess(&ioctlp->ioctl, userp);
1927 smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1929 cm_SkipIoctlPath(&ioctlp->ioctl);
1931 return cm_IoctlRxStatPeer(&ioctlp->ioctl, userp);
1935 smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1937 cm_SkipIoctlPath(&ioctlp->ioctl);
1939 return cm_IoctlUnicodeControl(&ioctlp->ioctl, userp);
1943 smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1945 cm_SkipIoctlPath(&ioctlp->ioctl);
1947 return cm_IoctlUUIDControl(&ioctlp->ioctl, userp);
1952 smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1954 cm_SkipIoctlPath(&ioctlp->ioctl);
1956 return cm_IoctlMemoryDump(&ioctlp->ioctl, userp);
1960 smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1965 cm_ioctlQueryOptions_t *optionsp;
1966 afs_uint32 flags = 0;
1970 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1971 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1972 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1974 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1976 cm_SkipIoctlPath(&ioctlp->ioctl);
1977 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1978 optionsp->fid.vnode, optionsp->fid.unique);
1979 code = cm_GetSCache(&fid, &scp, userp, &req);
1981 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1986 code = cm_IoctlPathAvailability(&ioctlp->ioctl, userp, scp, &req);
1987 cm_ReleaseSCache(scp);
1992 smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
1998 cm_SkipIoctlPath(&ioctlp->ioctl);
2000 return cm_IoctlVolStatTest(&ioctlp->ioctl, userp, &req);
2006 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
2010 smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2015 cm_ioctlQueryOptions_t *optionsp;
2016 afs_uint32 flags = 0;
2020 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2022 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2023 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2025 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2027 cm_SkipIoctlPath(&ioctlp->ioctl);
2028 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2029 optionsp->fid.vnode, optionsp->fid.unique);
2030 code = cm_GetSCache(&fid, &scp, userp, &req);
2032 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2037 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
2040 code = cm_IoctlSetOwner(&ioctlp->ioctl, userp, scp, &req);
2042 cm_ReleaseSCache(scp);
2050 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
2054 smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
2059 cm_ioctlQueryOptions_t *optionsp;
2060 afs_uint32 flags = 0;
2064 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
2066 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
2067 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
2069 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
2071 cm_SkipIoctlPath(&ioctlp->ioctl);
2072 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
2073 optionsp->fid.vnode, optionsp->fid.unique);
2074 code = cm_GetSCache(&fid, &scp, userp, &req);
2076 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
2081 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
2084 code = cm_IoctlSetGroup(&ioctlp->ioctl, userp, scp, &req);
2086 cm_ReleaseSCache(scp);