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 <afs/param.h>
28 #include "afs/afsrpc.h"
31 smb_ioctlProc_t *smb_ioctlProcsp[SMB_IOCTL_MAXPROCS];
37 for (i=0; i<SMB_IOCTL_MAXPROCS; i++)
38 smb_ioctlProcsp[i] = NULL;
40 smb_ioctlProcsp[VIOCGETAL] = smb_IoctlGetACL;
41 smb_ioctlProcsp[VIOC_FILE_CELL_NAME] = smb_IoctlGetFileCellName;
42 smb_ioctlProcsp[VIOCSETAL] = smb_IoctlSetACL;
43 smb_ioctlProcsp[VIOC_FLUSHVOLUME] = smb_IoctlFlushVolume;
44 smb_ioctlProcsp[VIOCFLUSH] = smb_IoctlFlushFile;
45 smb_ioctlProcsp[VIOCSETVOLSTAT] = smb_IoctlSetVolumeStatus;
46 smb_ioctlProcsp[VIOCGETVOLSTAT] = smb_IoctlGetVolumeStatus;
47 smb_ioctlProcsp[VIOCWHEREIS] = smb_IoctlWhereIs;
48 smb_ioctlProcsp[VIOC_AFS_STAT_MT_PT] = smb_IoctlStatMountPoint;
49 smb_ioctlProcsp[VIOC_AFS_DELETE_MT_PT] = smb_IoctlDeleteMountPoint;
50 smb_ioctlProcsp[VIOCCKSERV] = smb_IoctlCheckServers;
51 smb_ioctlProcsp[VIOC_GAG] = smb_IoctlGag;
52 smb_ioctlProcsp[VIOCCKBACK] = smb_IoctlCheckVolumes;
53 smb_ioctlProcsp[VIOCSETCACHESIZE] = smb_IoctlSetCacheSize;
54 smb_ioctlProcsp[VIOCGETCACHEPARMS] = smb_IoctlGetCacheParms;
55 smb_ioctlProcsp[VIOCGETCELL] = smb_IoctlGetCell;
56 smb_ioctlProcsp[VIOCNEWCELL] = smb_IoctlNewCell;
57 smb_ioctlProcsp[VIOC_GET_WS_CELL] = smb_IoctlGetWsCell;
58 smb_ioctlProcsp[VIOC_AFS_SYSNAME] = smb_IoctlSysName;
59 smb_ioctlProcsp[VIOC_GETCELLSTATUS] = smb_IoctlGetCellStatus;
60 smb_ioctlProcsp[VIOC_SETCELLSTATUS] = smb_IoctlSetCellStatus;
61 smb_ioctlProcsp[VIOC_SETSPREFS] = smb_IoctlSetSPrefs;
62 smb_ioctlProcsp[VIOC_GETSPREFS] = smb_IoctlGetSPrefs;
63 smb_ioctlProcsp[VIOC_STOREBEHIND] = smb_IoctlStoreBehind;
64 smb_ioctlProcsp[VIOC_AFS_CREATE_MT_PT] = smb_IoctlCreateMountPoint;
65 smb_ioctlProcsp[VIOC_TRACECTL] = smb_IoctlTraceControl;
66 smb_ioctlProcsp[VIOCSETTOK] = smb_IoctlSetToken;
67 smb_ioctlProcsp[VIOCGETTOK] = smb_IoctlGetTokenIter;
68 smb_ioctlProcsp[VIOCNEWGETTOK] = smb_IoctlGetToken;
69 smb_ioctlProcsp[VIOCDELTOK] = smb_IoctlDelToken;
70 smb_ioctlProcsp[VIOCDELALLTOK] = smb_IoctlDelAllToken;
71 smb_ioctlProcsp[VIOC_SYMLINK] = smb_IoctlSymlink;
72 smb_ioctlProcsp[VIOC_LISTSYMLINK] = smb_IoctlListlink;
73 smb_ioctlProcsp[VIOC_DELSYMLINK] = smb_IoctlDeletelink;
74 smb_ioctlProcsp[VIOC_MAKESUBMOUNT] = smb_IoctlMakeSubmount;
75 smb_ioctlProcsp[VIOC_GETRXKCRYPT] = smb_IoctlGetRxkcrypt;
76 smb_ioctlProcsp[VIOC_SETRXKCRYPT] = smb_IoctlSetRxkcrypt;
77 smb_ioctlProcsp[VIOC_ISSYMLINK] = smb_IoctlIslink;
78 smb_ioctlProcsp[VIOC_TRACEMEMDUMP] = smb_IoctlMemoryDump;
79 smb_ioctlProcsp[VIOC_ISSYMLINK] = smb_IoctlIslink;
80 smb_ioctlProcsp[VIOC_FLUSHALL] = smb_IoctlFlushAllVolumes;
81 smb_ioctlProcsp[VIOCGETFID] = smb_IoctlGetFid;
82 smb_ioctlProcsp[VIOCGETOWNER] = smb_IoctlGetOwner;
83 smb_ioctlProcsp[VIOC_RXSTAT_PROC] = smb_IoctlRxStatProcess;
84 smb_ioctlProcsp[VIOC_RXSTAT_PEER] = smb_IoctlRxStatPeer;
85 smb_ioctlProcsp[VIOC_UUIDCTL] = smb_IoctlUUIDControl;
86 smb_ioctlProcsp[VIOC_PATH_AVAILABILITY] = smb_IoctlPathAvailability;
87 smb_ioctlProcsp[VIOC_GETFILETYPE] = smb_IoctlGetFileType;
88 smb_ioctlProcsp[VIOC_VOLSTAT_TEST] = smb_IoctlVolStatTest;
89 smb_ioctlProcsp[VIOC_UNICODECTL] = smb_IoctlUnicodeControl;
90 smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner;
91 smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup;
94 /* called to make a fid structure into an IOCTL fid structure */
96 smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
99 cm_space_t *copyPrefix;
101 lock_ObtainMutex(&fidp->mx);
102 fidp->flags |= SMB_FID_IOCTL;
103 fidp->scp = &cm_data.fakeSCache;
104 cm_HoldSCache(fidp->scp);
105 if (fidp->ioctlp == NULL) {
106 iop = malloc(sizeof(*iop));
107 memset(iop, 0, sizeof(*iop));
112 copyPrefix = cm_GetSpace();
113 memcpy(copyPrefix->data, prefix->data, CM_UTILS_SPACESIZE);
114 fidp->ioctlp->prefix = copyPrefix;
116 lock_ReleaseMutex(&fidp->mx);
119 /* called when we receive a read call, does the send of the received data if
120 * this is the first read call. This is the function that actually makes the
121 * call to the ioctl code.
124 smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
127 smb_ioctlProc_t *procp = NULL;
130 if (ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN) {
131 ioctlp->ioctl.flags &= ~CM_IOCTLFLAG_DATAIN;
133 /* do the call now, or fail if we didn't get an opcode, or
134 * enough of an opcode.
136 if (ioctlp->ioctl.inCopied < sizeof(afs_int32))
137 return CM_ERROR_INVAL;
138 memcpy(&opcode, ioctlp->ioctl.inDatap, sizeof(afs_int32));
139 ioctlp->ioctl.inDatap += sizeof(afs_int32);
141 osi_Log1(afsd_logp, "Ioctl opcode 0x%x", opcode);
143 /* check for opcode out of bounds */
144 if (opcode < 0 || opcode >= SMB_IOCTL_MAXPROCS)
145 return CM_ERROR_TOOBIG;
147 /* check for no such proc */
148 procp = smb_ioctlProcsp[opcode];
150 return CM_ERROR_BADOP;
152 /* otherwise, make the call */
153 ioctlp->ioctl.outDatap += sizeof(afs_int32); /* reserve room for return code */
154 code = (*procp)(ioctlp, userp);
156 osi_Log1(afsd_logp, "Ioctl return code 0x%x", code);
158 /* copy in return code */
159 memcpy(ioctlp->ioctl.outAllocp, &code, sizeof(afs_int32));
164 /* called when we receive a write call. If this is the first write call after
165 * a series of reads (or the very first call), then we start a new call.
166 * We also ensure that things are properly initialized for the start of a call.
169 smb_IoctlPrepareWrite(smb_fid_t *fidp, smb_ioctl_t *ioctlp)
171 /* make sure the buffer(s) are allocated */
172 if (!ioctlp->ioctl.inAllocp)
173 ioctlp->ioctl.inAllocp = malloc(SMB_IOCTL_MAXDATA);
174 if (!ioctlp->ioctl.outAllocp)
175 ioctlp->ioctl.outAllocp = malloc(SMB_IOCTL_MAXDATA);
177 /* Fixes fs la problem. We do a StrToOEM later and if this data isn't initialized we get memory issues. */
178 (void) memset(ioctlp->ioctl.inAllocp, 0, SMB_IOCTL_MAXDATA);
179 (void) memset(ioctlp->ioctl.outAllocp, 0, SMB_IOCTL_MAXDATA);
181 /* and make sure that we've reset our state for the new incoming request */
182 if (!(ioctlp->ioctl.flags & CM_IOCTLFLAG_DATAIN)) {
183 ioctlp->ioctl.inCopied = 0;
184 ioctlp->ioctl.outCopied = 0;
185 ioctlp->ioctl.inDatap = ioctlp->ioctl.inAllocp;
186 ioctlp->ioctl.outDatap = ioctlp->ioctl.outAllocp;
187 ioctlp->ioctl.flags |= CM_IOCTLFLAG_DATAIN;
191 /* called from smb_ReceiveCoreRead when we receive a read on the ioctl fid */
193 smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
197 afs_int32 leftToCopy;
203 count = smb_GetSMBParm(inp, 1);
204 userp = smb_GetUserFromVCP(vcp, inp);
207 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
209 cm_ReleaseUser(userp);
210 return CM_ERROR_NOSUCHPATH;
213 /* turn the connection around, if required */
214 code = smb_IoctlPrepareRead(fidp, iop, userp);
217 cm_ReleaseUser(userp);
221 leftToCopy = (afs_int32)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
222 if (count > leftToCopy)
225 /* now set the parms for a read of count bytes */
226 smb_SetSMBParm(outp, 0, count);
227 smb_SetSMBParm(outp, 1, 0);
228 smb_SetSMBParm(outp, 2, 0);
229 smb_SetSMBParm(outp, 3, 0);
230 smb_SetSMBParm(outp, 4, 0);
232 smb_SetSMBDataLength(outp, count+3);
234 op = smb_GetSMBData(outp, NULL);
236 *op++ = (char)(count & 0xff);
237 *op++ = (char)((count >> 8) & 0xff);
239 /* now copy the data into the response packet */
240 memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
242 /* and adjust the counters */
243 iop->ioctl.outCopied += count;
245 cm_ReleaseUser(userp);
250 /* called from smb_ReceiveCoreWrite when we receive a write call on the IOCTL
254 smb_IoctlWrite(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
260 int inDataBlockCount;
263 count = smb_GetSMBParm(inp, 1);
266 smb_IoctlPrepareWrite(fidp, iop);
268 op = smb_GetSMBData(inp, NULL);
269 op = smb_ParseDataBlock(op, NULL, &inDataBlockCount);
271 if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
272 code = CM_ERROR_TOOBIG;
277 memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
280 iop->ioctl.inCopied += count;
283 /* return # of bytes written */
285 smb_SetSMBParm(outp, 0, count);
286 smb_SetSMBDataLength(outp, 0);
292 /* called from smb_ReceiveV3WriteX when we receive a write call on the IOCTL
296 smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
302 int inDataBlockCount;
305 count = smb_GetSMBParm(inp, 10);
308 smb_IoctlPrepareWrite(fidp, iop);
310 op = inp->data + smb_GetSMBParm(inp, 11);
311 inDataBlockCount = count;
313 if (count + iop->ioctl.inCopied > SMB_IOCTL_MAXDATA) {
314 code = CM_ERROR_TOOBIG;
319 memcpy(iop->ioctl.inDatap + iop->ioctl.inCopied, op, count);
322 iop->ioctl.inCopied += count;
325 /* return # of bytes written */
327 smb_SetSMBParm(outp, 2, count);
328 smb_SetSMBParm(outp, 3, 0); /* reserved */
329 smb_SetSMBParm(outp, 4, 0); /* reserved */
330 smb_SetSMBParm(outp, 5, 0); /* reserved */
331 smb_SetSMBDataLength(outp, 0);
338 /* called from V3 read to handle IOCTL descriptor reads */
340 smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
351 count = smb_GetSMBParm(inp, 5);
353 uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
355 return CM_ERROR_BADSMB;
356 userp = smb_GetUserFromUID(uidp);
357 osi_assertx(userp != NULL, "null cm_user_t");
359 if (uidp && uidp->unp) {
360 osi_Log3(afsd_logp, "Ioctl uid %d user %x name %S",
362 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
365 osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
366 uidp->userID, userp);
368 osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
372 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
375 smb_ReleaseUID(uidp);
376 cm_ReleaseUser(userp);
377 return CM_ERROR_NOSUCHPATH;
380 code = smb_IoctlPrepareRead(fidp, iop, userp);
383 smb_ReleaseUID(uidp);
386 cm_ReleaseUser(userp);
390 leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
391 if (count > leftToCopy)
394 /* 0 and 1 are reserved for request chaining, were setup by our caller,
395 * and will be further filled in after we return.
397 smb_SetSMBParm(outp, 2, 0); /* remaining bytes, for pipes */
398 smb_SetSMBParm(outp, 3, 0); /* resvd */
399 smb_SetSMBParm(outp, 4, 0); /* resvd */
400 smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */
401 /* fill in #6 when we have all the parameters' space reserved */
402 smb_SetSMBParm(outp, 7, 0); /* resv'd */
403 smb_SetSMBParm(outp, 8, 0); /* resv'd */
404 smb_SetSMBParm(outp, 9, 0); /* resv'd */
405 smb_SetSMBParm(outp, 10, 0); /* resv'd */
406 smb_SetSMBParm(outp, 11, 0); /* reserved */
408 /* get op ptr after putting in the last parm, since otherwise we don't
409 * know where the data really is.
411 op = smb_GetSMBData(outp, NULL);
413 /* now fill in offset from start of SMB header to first data byte (to op) */
414 smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
416 /* set the packet data length the count of the # of bytes */
417 smb_SetSMBDataLength(outp, count);
419 /* now copy the data into the response packet */
420 memcpy(op, iop->ioctl.outCopied + iop->ioctl.outAllocp, count);
422 /* and adjust the counters */
423 iop->ioctl.outCopied += count;
425 /* and cleanup things */
426 cm_ReleaseUser(userp);
431 /* called from Read Raw to handle IOCTL descriptor reads */
433 smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
445 userp = smb_GetUserFromVCP(vcp, inp);
448 uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
449 if (uidp && uidp->unp) {
450 osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
452 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
454 osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
455 uidp->userID, userp);
457 osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
461 smb_ReleaseUID(uidp);
463 code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
465 code = CM_ERROR_NOSUCHPATH;
469 code = smb_IoctlPrepareRead(fidp, iop, userp);
474 leftToCopy = (long)((iop->ioctl.outDatap - iop->ioctl.outAllocp) - iop->ioctl.outCopied);
477 memset((char *)ncbp, 0, sizeof(NCB));
479 ncbp->ncb_length = (unsigned short) leftToCopy;
480 ncbp->ncb_lsn = (unsigned char) vcp->lsn;
481 ncbp->ncb_command = NCBSEND;
482 /*ncbp->ncb_lana_num = smb_LANadapter;*/
483 ncbp->ncb_lana_num = vcp->lana;
485 ncbp->ncb_buffer = iop->ioctl.outCopied + iop->ioctl.outAllocp;
486 code = Netbios(ncbp);
489 osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
492 cm_ReleaseUser(userp);
497 /* parse the passed-in file name and do a namei on it. If we fail,
498 * return an error code, otherwise return the vnode located in *scpp.
500 #define CM_PARSE_FLAG_LITERAL 1
503 smb_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
504 cm_scache_t **scpp, afs_uint32 flags)
507 cm_scache_t *substRootp = NULL;
508 cm_scache_t *iscp = NULL;
510 clientchar_t *relativePath = NULL;
511 clientchar_t *lastComponent = NULL;
512 afs_uint32 follow = (flags & CM_PARSE_FLAG_LITERAL ? CM_FLAG_NOMOUNTCHASE : CM_FLAG_FOLLOW);
514 inPath = ioctlp->ioctl.inDatap;
515 /* setup the next data value for the caller to use */
516 ioctlp->ioctl.inDatap += (long)strlen(ioctlp->ioctl.inDatap) + 1;
518 osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,inPath));
520 /* This is usually the file name, but for StatMountPoint it is the path. */
521 /* ioctlp->ioctl.inDatap can be either of the form:
524 * \\netbios-name\submount\path\.
525 * \\netbios-name\submount\path\file
528 /* We do not perform path name translation on the ioctl path data
529 * because these paths were not translated by Windows through the
530 * file system API. Therefore, they are not OEM characters but
531 * whatever the display character set is.
534 // TranslateExtendedChars(relativePath);
536 /* This is usually nothing, but for StatMountPoint it is the file name. */
537 // TranslateExtendedChars(ioctlp->ioctl.inDatap);
539 /* If the string starts with our UTF-8 prefix (which is the
540 sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
541 strings), we assume that the provided path is UTF-8. Otherwise
542 we have to convert the string to UTF-8, since that is what we
543 want to use everywhere else.*/
545 if (memcmp(inPath, utf8_prefix, utf8_prefix_size) == 0) {
546 /* String is UTF-8 */
547 inPath += utf8_prefix_size;
548 ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
550 relativePath = cm_Utf8ToClientStringAlloc(inPath, -1, NULL);
554 /* Not a UTF-8 string */
555 /* TODO: If this is an OEM string, we should convert it to
557 if (smb_StoreAnsiFilenames) {
558 cch = cm_AnsiToClientString(inPath, -1, NULL, 0);
562 relativePath = malloc(cch * sizeof(clientchar_t));
563 cm_AnsiToClientString(inPath, -1, relativePath, cch);
565 TranslateExtendedChars(inPath);
567 cch = cm_OemToClientString(inPath, -1, NULL, 0);
571 relativePath = malloc(cch * sizeof(clientchar_t));
572 cm_OemToClientString(inPath, -1, relativePath, cch);
576 if (relativePath[0] == relativePath[1] &&
577 relativePath[1] == '\\' &&
578 !cm_ClientStrCmpNI(cm_NetbiosNameC, relativePath+2,
579 cm_ClientStrLen(cm_NetbiosNameC)))
581 clientchar_t shareName[256];
582 clientchar_t *sharePath;
585 /* We may have found a UNC path.
586 * If the first component is the NetbiosName,
587 * then throw out the second component (the submount)
588 * since it had better expand into the value of ioctl->tidPathp
591 p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1; /* buffer overflow vuln.? */
592 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
595 for (i = 0; *p && *p != '\\'; i++,p++ ) {
598 p++; /* skip past trailing slash */
599 shareName[i] = 0; /* terminate string */
601 shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
603 /* we found a sharename, therefore use the resulting path */
604 code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
605 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
606 userp, sharePath, reqp, &substRootp);
609 osi_Log1(afsd_logp,"cm_ParseIoctlPath [1] code 0x%x", code);
615 lastComponent = cm_ClientStrRChr(p, '\\');
616 if (lastComponent && (lastComponent - p) > 1 &&
617 cm_ClientStrLen(lastComponent) > 1) {
618 *lastComponent = '\0';
621 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
622 userp, NULL, reqp, &iscp);
624 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
625 userp, NULL, reqp, scpp);
627 cm_ReleaseSCache(iscp);
629 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
630 userp, NULL, reqp, scpp);
632 cm_ReleaseSCache(substRootp);
634 osi_Log1(afsd_logp,"cm_ParseIoctlPath [2] code 0x%x", code);
640 /* otherwise, treat the name as a cellname mounted off the afs root.
641 * This requires that we reconstruct the shareName string with
642 * leading and trailing slashes.
644 p = relativePath + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
645 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
649 for (i = 1; *p && *p != '\\'; i++,p++ ) {
652 p++; /* skip past trailing slash */
653 shareName[i++] = '/'; /* add trailing slash */
654 shareName[i] = 0; /* terminate string */
657 code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
658 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
659 userp, shareName, reqp, &substRootp);
661 osi_Log1(afsd_logp,"cm_ParseIoctlPath [3] code 0x%x", code);
667 lastComponent = cm_ClientStrRChr(p, '\\');
668 if (lastComponent && (lastComponent - p) > 1 &&
669 cm_ClientStrLen(lastComponent) > 1) {
670 *lastComponent = '\0';
673 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
674 userp, NULL, reqp, &iscp);
676 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
677 userp, NULL, reqp, scpp);
679 cm_ReleaseSCache(iscp);
681 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD,
682 userp, NULL, reqp, scpp);
686 cm_ReleaseSCache(substRootp);
687 osi_Log1(afsd_logp,"cm_ParseIoctlPath code [4] 0x%x", code);
694 code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
695 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
696 userp, ioctlp->tidPathp, reqp, &substRootp);
698 osi_Log1(afsd_logp,"cm_ParseIoctlPath [6] code 0x%x", code);
704 lastComponent = cm_ClientStrRChr(relativePath, '\\');
705 if (lastComponent && (lastComponent - relativePath) > 1 &&
706 cm_ClientStrLen(lastComponent) > 1) {
707 *lastComponent = '\0';
710 code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
711 userp, NULL, reqp, &iscp);
713 code = cm_NameI(iscp, lastComponent, CM_FLAG_CASEFOLD | follow,
714 userp, NULL, reqp, scpp);
716 cm_ReleaseSCache(iscp);
718 code = cm_NameI(substRootp, relativePath, CM_FLAG_CASEFOLD | follow,
719 userp, NULL, reqp, scpp);
722 cm_ReleaseSCache(substRootp);
723 osi_Log1(afsd_logp,"cm_ParseIoctlPath [7] code 0x%x", code);
731 cm_ReleaseSCache(substRootp);
733 /* and return success */
734 osi_Log1(afsd_logp,"cm_ParseIoctlPath [8] code 0x%x", code);
743 #define LEAF_SIZE 256
744 /* parse the passed-in file name and do a namei on its parent. If we fail,
745 * return an error code, otherwise return the vnode located in *scpp.
748 smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
749 cm_scache_t **scpp, clientchar_t *leafp)
752 clientchar_t tbuffer[1024];
753 clientchar_t *tp, *jp;
754 cm_scache_t *substRootp = NULL;
755 clientchar_t *inpathp = NULL;
758 inpathdatap = ioctlp->ioctl.inDatap;
760 /* If the string starts with our UTF-8 prefix (which is the
761 sequence [ESC,'%','G'] as used by ISO-2022 to designate UTF-8
762 strings), we assume that the provided path is UTF-8. Otherwise
763 we have to convert the string to UTF-8, since that is what we
764 want to use everywhere else.*/
766 if (memcmp(inpathdatap, utf8_prefix, utf8_prefix_size) == 0) {
768 /* String is UTF-8 */
769 inpathdatap += utf8_prefix_size;
770 ioctlp->ioctl.flags |= CM_IOCTLFLAG_USEUTF8;
772 inpathp = cm_Utf8ToClientStringAlloc(inpathdatap, -1, NULL);
776 /* Not a UTF-8 string */
777 /* TODO: If this is an OEM string, we should convert it to
779 if (smb_StoreAnsiFilenames) {
780 cch = cm_AnsiToClientString(inpathdatap, -1, NULL, 0);
784 inpathp = malloc(cch * sizeof(clientchar_t));
785 cm_AnsiToClientString(inpathdatap, -1, inpathp, cch);
787 TranslateExtendedChars(inpathdatap);
789 cch = cm_OemToClientString(inpathdatap, -1, NULL, 0);
793 inpathp = malloc(cch * sizeof(clientchar_t));
794 cm_OemToClientString(inpathdatap, -1, inpathp, cch);
798 cm_ClientStrCpy(tbuffer, lengthof(tbuffer), inpathp);
799 tp = cm_ClientStrRChr(tbuffer, '\\');
800 jp = cm_ClientStrRChr(tbuffer, '/');
803 else if (jp && (tp - tbuffer) < (jp - tbuffer))
806 cm_ClientStrCpy(tbuffer, lengthof(tbuffer), _C("\\"));
808 cm_ClientStrCpy(leafp, LEAF_SIZE, inpathp);
813 cm_ClientStrCpy(leafp, LEAF_SIZE, tp+1);
817 inpathp = NULL; /* We don't need this from this point on */
819 if (tbuffer[0] == tbuffer[1] &&
820 tbuffer[1] == '\\' &&
821 !cm_ClientStrCmpNI(cm_NetbiosNameC, tbuffer+2,
822 cm_ClientStrLen(cm_NetbiosNameC)))
824 clientchar_t shareName[256];
825 clientchar_t *sharePath;
828 /* We may have found a UNC path.
829 * If the first component is the NetbiosName,
830 * then throw out the second component (the submount)
831 * since it had better expand into the value of ioctl->tidPathp
834 p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
835 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
838 for (i = 0; *p && *p != '\\'; i++,p++ ) {
841 p++; /* skip past trailing slash */
842 shareName[i] = 0; /* terminate string */
844 shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
846 /* we found a sharename, therefore use the resulting path */
847 code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
848 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
849 userp, sharePath, reqp, &substRootp);
851 if (code) return code;
853 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
854 userp, NULL, reqp, scpp);
855 cm_ReleaseSCache(substRootp);
856 if (code) return code;
858 /* otherwise, treat the name as a cellname mounted off the afs root.
859 * This requires that we reconstruct the shareName string with
860 * leading and trailing slashes.
862 p = tbuffer + 2 + cm_ClientStrLen(cm_NetbiosNameC) + 1;
863 if ( !cm_ClientStrCmpNI(_C("all"), p, 3) )
867 for (i = 1; *p && *p != '\\'; i++,p++ ) {
870 p++; /* skip past trailing slash */
871 shareName[i++] = '/'; /* add trailing slash */
872 shareName[i] = 0; /* terminate string */
874 code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
875 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
876 userp, shareName, reqp, &substRootp);
877 if (code) return code;
879 code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
880 userp, NULL, reqp, scpp);
881 cm_ReleaseSCache(substRootp);
882 if (code) return code;
885 code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->wdata,
886 CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
887 userp, ioctlp->tidPathp, reqp, &substRootp);
888 if (code) return code;
890 code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
891 userp, NULL, reqp, scpp);
892 cm_ReleaseSCache(substRootp);
893 if (code) return code;
896 /* # of bytes of path */
897 code = (long)strlen(ioctlp->ioctl.inDatap) + 1;
898 ioctlp->ioctl.inDatap += code;
900 /* and return success */
905 smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
912 struct ClearToken ct;
918 int release_userp = 0;
919 clientchar_t *uname = NULL;
920 clientchar_t *smbname = NULL;
921 clientchar_t *wdir = NULL;
924 saveDataPtr = ioctlp->ioctl.inDatap;
926 cm_SkipIoctlPath(&ioctlp->ioctl);
928 tp = ioctlp->ioctl.inDatap;
931 memcpy(&ticketLen, tp, sizeof(ticketLen));
932 tp += sizeof(ticketLen);
933 if (ticketLen < MINKTCTICKETLEN || ticketLen > MAXKTCTICKETLEN)
934 return CM_ERROR_INVAL;
936 /* remember ticket and skip over it for now */
940 /* clear token size */
941 memcpy(&ctSize, tp, sizeof(ctSize));
942 tp += sizeof(ctSize);
943 if (ctSize != sizeof(struct ClearToken))
944 return CM_ERROR_INVAL;
947 memcpy(&ct, tp, ctSize);
949 if (ct.AuthHandle == -1)
950 ct.AuthHandle = 999; /* more rxvab compat stuff */
952 /* more stuff, if any */
953 if (ioctlp->ioctl.inCopied > tp - saveDataPtr) {
954 /* flags: logon flag */
955 memcpy(&flags, tp, sizeof(int));
960 fschar_t * cellnamep;
963 temp = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
964 cellnamep = cm_ClientStringToFsStringAlloc(temp, -1, NULL);
965 cellp = cm_GetCell(cellnamep, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
971 code = CM_ERROR_NOSUCHCELL;
974 tp += strlen(tp) + 1;
977 uname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
978 tp += strlen(tp) + 1;
980 if (flags & PIOCTL_LOGON) {
981 /* SMB user name with which to associate tokens */
982 smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
983 osi_Log2(smb_logp,"cm_IoctlSetToken for user [%S] smbname [%S]",
984 osi_LogSaveClientString(smb_logp,uname),
985 osi_LogSaveClientString(smb_logp,smbname));
986 fprintf(stderr, "SMB name = %S\n", smbname);
987 tp += strlen(tp) + 1;
989 osi_Log1(smb_logp,"cm_IoctlSetToken for user [%S]",
990 osi_LogSaveClientString(smb_logp, uname));
994 memcpy(&uuid, tp, sizeof(uuid));
995 if (!cm_FindTokenEvent(uuid, sessionKey)) {
996 code = CM_ERROR_INVAL;
1000 cellp = cm_data.rootCellp;
1001 osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified");
1004 if (flags & PIOCTL_LOGON) {
1005 userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname,
1006 SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
1010 /* store the token */
1011 lock_ObtainMutex(&userp->mx);
1012 ucellp = cm_GetUCell(userp, cellp);
1013 osi_Log1(smb_logp,"cm_IoctlSetToken ucellp %lx", ucellp);
1014 ucellp->ticketLen = ticketLen;
1015 if (ucellp->ticketp)
1016 free(ucellp->ticketp); /* Discard old token if any */
1017 ucellp->ticketp = malloc(ticketLen);
1018 memcpy(ucellp->ticketp, ticket, ticketLen);
1020 * Get the session key from the RPC, rather than from the pioctl.
1023 memcpy(&ucellp->sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey));
1025 memcpy(ucellp->sessionKey.data, sessionKey, sizeof(sessionKey));
1026 ucellp->kvno = ct.AuthHandle;
1027 ucellp->expirationTime = ct.EndTimestamp;
1030 ucellp->uid = ANONYMOUSID;
1033 cm_ClientStringToFsString(uname, -1, ucellp->userName, MAXKTCNAMELEN);
1035 cm_UsernameToId(uname, ucellp, &ucellp->uid);
1038 ucellp->flags |= CM_UCELLFLAG_RXKAD;
1039 lock_ReleaseMutex(&userp->mx);
1041 if (flags & PIOCTL_LOGON) {
1042 ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
1045 cm_ResetACLCache(cellp, userp);
1049 cm_ReleaseUser(userp);
1063 smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
1065 smb_user_t *uidp = ioctlp->uidp;
1067 if (uidp && uidp->unp) {
1070 cch = cm_ClientStringToUtf8(uidp->unp->name,
1072 ioctlp->ioctl.outDatap,
1073 (SMB_IOCTL_MAXDATA -
1074 (ioctlp->ioctl.outDatap - ioctlp->ioctl.outAllocp))
1075 / sizeof(cm_utf8char_t));
1077 ioctlp->ioctl.outDatap += cch * sizeof(cm_utf8char_t);
1084 smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
1089 cm_ioctlQueryOptions_t *optionsp;
1090 afs_uint32 flags = 0;
1094 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1095 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1096 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1098 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1100 cm_SkipIoctlPath(&ioctlp->ioctl);
1101 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1102 optionsp->fid.vnode, optionsp->fid.unique);
1103 code = cm_GetSCache(&fid, &scp, userp, &req);
1105 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1111 code = cm_IoctlGetACL(&ioctlp->ioctl, userp, scp, &req);
1113 cm_ReleaseSCache(scp);
1118 smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
1123 afs_uint32 flags = 0;
1127 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1131 code = cm_IoctlSetACL(&ioctlp->ioctl, userp, scp, &req);
1133 cm_ReleaseSCache(scp);
1138 smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
1143 cm_ioctlQueryOptions_t *optionsp;
1144 afs_uint32 flags = 0;
1148 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1149 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1150 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1152 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1154 cm_SkipIoctlPath(&ioctlp->ioctl);
1155 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1156 optionsp->fid.vnode, optionsp->fid.unique);
1157 code = cm_GetSCache(&fid, &scp, userp, &req);
1159 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1164 code = cm_IoctlGetFileCellName(&ioctlp->ioctl, userp, scp, &req);
1166 cm_ReleaseSCache(scp);
1172 smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
1178 cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
1180 return cm_IoctlFlushAllVolumes(&ioctlp->ioctl, userp, &req);
1184 smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
1189 cm_ioctlQueryOptions_t *optionsp;
1190 afs_uint32 flags = 0;
1194 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1195 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1196 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1198 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1200 cm_SkipIoctlPath(&ioctlp->ioctl);
1201 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1202 optionsp->fid.vnode, optionsp->fid.unique);
1203 code = cm_GetSCache(&fid, &scp, userp, &req);
1205 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1210 code = cm_IoctlFlushVolume(&ioctlp->ioctl, userp, scp, &req);
1212 cm_ReleaseSCache(scp);
1218 smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp)
1223 cm_ioctlQueryOptions_t *optionsp;
1224 afs_uint32 flags = 0;
1228 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1229 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1230 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1232 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1234 cm_SkipIoctlPath(&ioctlp->ioctl);
1235 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1236 optionsp->fid.vnode, optionsp->fid.unique);
1237 code = cm_GetSCache(&fid, &scp, userp, &req);
1239 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1244 code = cm_IoctlFlushFile(&ioctlp->ioctl, userp, scp, &req);
1246 cm_ReleaseSCache(scp);
1251 smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
1259 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, 0);
1260 if (code) return code;
1262 code = cm_IoctlSetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
1263 cm_ReleaseSCache(scp);
1269 smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
1273 cm_ioctlQueryOptions_t *optionsp;
1274 afs_uint32 flags = 0;
1279 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1280 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1281 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1283 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1285 cm_SkipIoctlPath(&ioctlp->ioctl);
1286 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1287 optionsp->fid.vnode, optionsp->fid.unique);
1288 code = cm_GetSCache(&fid, &scp, userp, &req);
1290 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1295 code = cm_IoctlGetVolumeStatus(&ioctlp->ioctl, userp, scp, &req);
1297 cm_ReleaseSCache(scp);
1303 smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp)
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 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1321 code = cm_IoctlGetFid(&ioctlp->ioctl, userp, scp, &req);
1323 cm_ReleaseSCache(scp);
1329 smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp)
1334 cm_ioctlQueryOptions_t * optionsp;
1335 afs_uint32 flags = 0;
1339 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1340 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1341 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1343 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1345 cm_SkipIoctlPath(&ioctlp->ioctl);
1346 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1347 optionsp->fid.vnode, optionsp->fid.unique);
1348 code = cm_GetSCache(&fid, &scp, userp, &req);
1350 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1355 code = cm_IoctlGetFileType(&ioctlp->ioctl, userp, scp, &req);
1357 cm_ReleaseSCache(scp);
1363 smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
1368 cm_ioctlQueryOptions_t *optionsp;
1369 afs_uint32 flags = 0;
1373 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1374 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1375 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1377 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1379 cm_SkipIoctlPath(&ioctlp->ioctl);
1380 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1381 optionsp->fid.vnode, optionsp->fid.unique);
1382 code = cm_GetSCache(&fid, &scp, userp, &req);
1384 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1389 code = cm_IoctlGetOwner(&ioctlp->ioctl, userp, scp, &req);
1391 cm_ReleaseSCache(scp);
1397 smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
1402 cm_ioctlQueryOptions_t *optionsp;
1403 afs_uint32 flags = 0;
1407 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1408 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1409 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1411 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1413 cm_SkipIoctlPath(&ioctlp->ioctl);
1414 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1415 optionsp->fid.vnode, optionsp->fid.unique);
1416 code = cm_GetSCache(&fid, &scp, userp, &req);
1418 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1423 code = cm_IoctlWhereIs(&ioctlp->ioctl, userp, scp, &req);
1425 cm_ReleaseSCache(scp);
1432 smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
1440 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1444 code = cm_IoctlStatMountPoint(&ioctlp->ioctl, userp, dscp, &req);
1446 cm_ReleaseSCache(dscp);
1452 smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
1460 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1464 code = cm_IoctlDeleteMountPoint(&ioctlp->ioctl, userp, dscp, &req);
1466 cm_ReleaseSCache(dscp);
1472 smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp)
1474 cm_SkipIoctlPath(&ioctlp->ioctl); /* we don't care about the path */
1476 return cm_IoctlCheckServers(&ioctlp->ioctl, userp);
1480 smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp)
1482 /* we don't print anything superfluous, so we don't support the gag call */
1483 return CM_ERROR_INVAL;
1487 smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
1489 cm_SkipIoctlPath(&ioctlp->ioctl);
1491 return cm_IoctlCheckVolumes(&ioctlp->ioctl, userp);
1494 afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp)
1496 cm_SkipIoctlPath(&ioctlp->ioctl);
1498 return cm_IoctlSetCacheSize(&ioctlp->ioctl, userp);
1503 smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
1505 cm_SkipIoctlPath(&ioctlp->ioctl);
1507 return cm_IoctlTraceControl(&ioctlp->ioctl, userp);
1511 smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp)
1513 cm_SkipIoctlPath(&ioctlp->ioctl);
1515 return cm_IoctlGetCacheParms(&ioctlp->ioctl, userp);
1519 smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
1521 cm_SkipIoctlPath(&ioctlp->ioctl);
1523 return cm_IoctlGetCell(&ioctlp->ioctl, userp);
1527 smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
1529 cm_SkipIoctlPath(&ioctlp->ioctl);
1531 return cm_IoctlNewCell(&ioctlp->ioctl, userp);
1535 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
1537 cm_SkipIoctlPath(&ioctlp->ioctl);
1539 return cm_IoctlGetWsCell(&ioctlp->ioctl, userp);
1543 smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
1545 cm_SkipIoctlPath(&ioctlp->ioctl);
1547 return cm_IoctlSysName(&ioctlp->ioctl, userp);
1551 smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
1553 cm_SkipIoctlPath(&ioctlp->ioctl);
1555 return cm_IoctlGetCellStatus(&ioctlp->ioctl, userp);
1559 smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
1561 cm_SkipIoctlPath(&ioctlp->ioctl);
1563 return cm_IoctlSetCellStatus(&ioctlp->ioctl, userp);
1567 smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
1569 cm_SkipIoctlPath(&ioctlp->ioctl);
1571 return cm_IoctlSetSPrefs(&ioctlp->ioctl, userp);
1575 smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
1577 cm_SkipIoctlPath(&ioctlp->ioctl);
1579 return cm_IoctlGetSPrefs(&ioctlp->ioctl, userp);
1583 smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp)
1585 /* we ignore default asynchrony since we only have one way
1586 * of doing this today.
1592 smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
1596 clientchar_t leaf[LEAF_SIZE];
1601 code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
1605 code = cm_IoctlCreateMountPoint(&ioctlp->ioctl, userp, dscp, &req, leaf);
1607 cm_ReleaseSCache(dscp);
1612 smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
1616 clientchar_t leaf[LEAF_SIZE];
1621 code = smb_ParseIoctlParent(ioctlp, userp, &req, &dscp, leaf);
1622 if (code) return code;
1624 code = cm_IoctlSymlink(&ioctlp->ioctl, userp, dscp, &req, leaf);
1626 cm_ReleaseSCache(dscp);
1632 smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
1640 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1641 if (code) return code;
1643 code = cm_IoctlListlink(&ioctlp->ioctl, userp, dscp, &req);
1645 cm_ReleaseSCache(dscp);
1650 smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp)
1651 {/*CHECK FOR VALID SYMLINK*/
1658 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1659 if (code) return code;
1661 code = cm_IoctlIslink(&ioctlp->ioctl, userp, dscp, &req);
1663 cm_ReleaseSCache(dscp);
1669 smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
1677 code = smb_ParseIoctlPath(ioctlp, userp, &req, &dscp, 0);
1678 if (code) return code;
1680 code = cm_IoctlDeletelink(&ioctlp->ioctl, userp, dscp, &req);
1682 cm_ReleaseSCache(dscp);
1688 smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp)
1690 cm_SkipIoctlPath(&ioctlp->ioctl);
1692 return cm_IoctlGetTokenIter(&ioctlp->ioctl, userp);
1696 smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
1698 cm_SkipIoctlPath(&ioctlp->ioctl);
1700 return cm_IoctlGetToken(&ioctlp->ioctl, userp);
1705 smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
1707 cm_SkipIoctlPath(&ioctlp->ioctl);
1709 return cm_IoctlDelToken(&ioctlp->ioctl, userp);
1714 smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
1716 cm_SkipIoctlPath(&ioctlp->ioctl);
1718 return cm_IoctlDelAllToken(&ioctlp->ioctl, userp);
1723 smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp)
1725 cm_SkipIoctlPath(&ioctlp->ioctl);
1727 return cm_IoctlMakeSubmount(&ioctlp->ioctl, userp);
1731 smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
1733 cm_SkipIoctlPath(&ioctlp->ioctl);
1735 return cm_IoctlGetRxkcrypt(&ioctlp->ioctl, userp);
1739 smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
1741 cm_SkipIoctlPath(&ioctlp->ioctl);
1743 return cm_IoctlSetRxkcrypt(&ioctlp->ioctl, userp);
1747 smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp)
1749 cm_SkipIoctlPath(&ioctlp->ioctl);
1751 return cm_IoctlRxStatProcess(&ioctlp->ioctl, userp);
1756 smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp)
1758 cm_SkipIoctlPath(&ioctlp->ioctl);
1760 return cm_IoctlRxStatPeer(&ioctlp->ioctl, userp);
1764 smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
1766 cm_SkipIoctlPath(&ioctlp->ioctl);
1768 return cm_IoctlUnicodeControl(&ioctlp->ioctl, userp);
1772 smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
1774 cm_SkipIoctlPath(&ioctlp->ioctl);
1776 return cm_IoctlUUIDControl(&ioctlp->ioctl, userp);
1781 smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
1783 cm_SkipIoctlPath(&ioctlp->ioctl);
1785 return cm_IoctlMemoryDump(&ioctlp->ioctl, userp);
1789 smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp)
1794 cm_ioctlQueryOptions_t *optionsp;
1795 afs_uint32 flags = 0;
1799 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1800 if (optionsp && CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1801 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1803 if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1805 cm_SkipIoctlPath(&ioctlp->ioctl);
1806 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1807 optionsp->fid.vnode, optionsp->fid.unique);
1808 code = cm_GetSCache(&fid, &scp, userp, &req);
1810 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1815 code = cm_IoctlPathAvailability(&ioctlp->ioctl, userp, scp, &req);
1816 cm_ReleaseSCache(scp);
1821 smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp)
1827 cm_SkipIoctlPath(&ioctlp->ioctl);
1829 return cm_IoctlVolStatTest(&ioctlp->ioctl, userp, &req);
1835 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
1839 smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
1844 cm_ioctlQueryOptions_t *optionsp;
1845 afs_uint32 flags = 0;
1849 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1851 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1852 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1854 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1856 cm_SkipIoctlPath(&ioctlp->ioctl);
1857 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1858 optionsp->fid.vnode, optionsp->fid.unique);
1859 code = cm_GetSCache(&fid, &scp, userp, &req);
1861 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1866 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
1869 code = cm_IoctlSetOwner(&ioctlp->ioctl, userp, scp, &req);
1871 cm_ReleaseSCache(scp);
1879 * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
1883 smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp)
1888 cm_ioctlQueryOptions_t *optionsp;
1889 afs_uint32 flags = 0;
1893 optionsp = cm_IoctlGetQueryOptions(&ioctlp->ioctl, userp);
1895 if (CM_IOCTL_QOPTS_HAVE_LITERAL(optionsp))
1896 flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0);
1898 if (CM_IOCTL_QOPTS_HAVE_FID(optionsp)) {
1900 cm_SkipIoctlPath(&ioctlp->ioctl);
1901 cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume,
1902 optionsp->fid.vnode, optionsp->fid.unique);
1903 code = cm_GetSCache(&fid, &scp, userp, &req);
1905 code = smb_ParseIoctlPath(ioctlp, userp, &req, &scp, flags);
1910 cm_IoctlSkipQueryOptions(&ioctlp->ioctl, userp);
1913 code = cm_IoctlSetGroup(&ioctlp->ioctl, userp, scp, &req);
1915 cm_ReleaseSCache(scp);