11 thdr(Session *s, Share *sp)
15 p = cifshdr(s, sp, SMB_COM_TRANSACTION);
16 p->tbase = pl16(p, 0); /* 0 Total parameter bytes to be sent, filled later */
17 pl16(p, 0); /* 2 Total data bytes to be sent, filled later */
18 pl16(p, 64); /* 4 Max parameter to return */
19 pl16(p, s->mtu - T2HDRLEN - 128); /* 6 Max data to return */
20 pl16(p, 1); /* 8 Max setup count to return */
21 pl16(p, 0); /* 10 Flags */
22 pl32(p, 1000); /* 12 Timeout (ms) */
23 pl16(p, 0); /* 16 Reserved */
24 pl16(p, 0); /* 18 Parameter count, filled later */
25 pl16(p, 0); /* 20 Parameter offset, filled later */
26 pl16(p, 0); /* 22 Data count, filled later */
27 pl16(p, 0); /* 24 Data offset, filled later */
28 pl16(p, 0); /* 26 Setup count (in words) */
29 pbytes(p); /* end of cifs words section */
38 if(((p->pos - p->tbase) % 2) != 0)
39 p8(p, 0); /* pad to word boundry */
41 p->pos = p->tbase + 20;
42 pl16(p, pos - p->buf - NBHDRLEN); /* param offset */
43 p->tparam = p->pos = pos;
51 assert(p->tparam != 0);
52 if(((p->pos - p->tbase) % 2) != 0)
53 p8(p, 0); /* pad to word boundry */
55 p->pos = p->tbase + 0;
56 pl16(p, pos - p->tparam); /* total param count */
58 p->pos = p->tbase + 18;
59 pl16(p, pos - p->tparam); /* param count */
61 p->pos = p->tbase + 24;
62 pl16(p, pos - p->buf - NBHDRLEN); /* data offset */
64 p->tdata = p->pos = pos;
73 assert(p->tbase != 0);
74 assert(p->tdata != 0);
76 p->pos = p->tbase + 2;
77 pl16(p, pos - p->tdata); /* total data count */
79 p->pos = p->tbase + 22;
80 pl16(p, pos - p->tdata); /* data count */
83 if((got = cifsrpc(p)) == -1)
86 gl16(p); /* Total parameter count */
87 gl16(p); /* Total data count */
88 gl16(p); /* Reserved */
89 gl16(p); /* Parameter count in this buffer */
90 p->tparam = p->buf + NBHDRLEN + gl16(p); /* Parameter offset */
91 gl16(p); /* Parameter displacement */
92 gl16(p); /* Data count (this buffer); */
93 p->tdata = p->buf + NBHDRLEN + gl16(p); /* Data offset */
94 gl16(p); /* Data displacement */
95 g8(p); /* Setup count */
107 RAPshareenum(Session *s, Share *sp, Share **ent)
109 int ngot = 0, err, navail, nret;
115 pstr(p, "\\PIPE\\LANMAN");
118 pl16(p, API_WShareEnum);
119 pascii(p, REMSmb_NetShareEnum_P); /* request descriptor */
120 pascii(p, REMSmb_share_info_0); /* reply descriptor */
121 pl16(p, 0); /* detail level */
122 pl16(p, s->mtu - 1024); /* receive buffer length */
131 err = gl16(p); /* error code */
132 gl16(p); /* rx buffer offset */
133 nret = gl16(p); /* number of entries returned */
134 navail = gl16(p); /* number of entries available */
136 if(err && err != RAP_ERR_MOREINFO){
137 werrstr("%s", raperrstr(err));
143 *ent = emalloc9p(sizeof(Share) * navail);
144 memset(*ent, 0, sizeof(Share) * navail);
148 for (; ngot < navail && nret--; ngot++){
149 gmem(p, tmp, 13); /* name */
151 q->name = estrdup9p(tmp);
156 fprint(2, "%s: %d/%d - share list incomplete\n", argv0, ngot, navail);
164 RAPshareinfo(Session *s, Share *sp, char *share, Shareinfo2 *si2p)
171 pstr(p, "\\PIPE\\LANMAN");
174 pl16(p, API_WShareGetInfo);
175 pascii(p, REMSmb_NetShareGetInfo_P); /* request descriptor */
176 pascii(p, REMSmb_share_info_2); /* reply descriptor */
178 pl16(p, 1); /* detail level */
179 pl16(p, s->mtu - 1024); /* receive buffer length */
189 err = gl16(p); /* error code */
190 conv = gl16(p); /* rx buffer offset */
191 gl16(p); /* number of entries returned */
192 gl16(p); /* number of entries available */
195 werrstr("%s", raperrstr(err));
200 memset(si2p, 0, sizeof(Shareinfo2));
205 si2p->name = estrdup9p(tmp);
206 si2p->type = gl16(p);
207 gconv(p, conv, tmp, sizeof tmp);
208 si2p->comment = estrdup9p(tmp);
209 gl16(p); /* comment offset high (unused) */
210 si2p->perms = gl16(p);
211 si2p->maxusrs = gl16(p);
212 si2p->activeusrs = gl16(p);
213 gconv(p, conv, tmp, sizeof tmp);
214 si2p->path = estrdup9p(tmp);
215 gl16(p); /* path offset high (unused) */
218 si2p->passwd = estrdup9p(tmp);
225 * Tried to split sessionenum into two passes, one getting the names
226 * of the connected workstations and the other collecting the detailed info,
227 * however API_WSessionGetInfo doesn't seem to work agains win2k3 for infolevel
228 * ten and infolevel one and two are priviledged calls. This means this code
229 * will work for small numbers of sessions agains win2k3 and fail for samba 3.0
230 * as it supports info levels zero and two only.
233 RAPsessionenum(Session *s, Share *sp, Sessinfo **sip)
235 int ngot = 0, conv, err, navail, nret;
241 pstr(p, "\\PIPE\\LANMAN");
244 pl16(p, API_WSessionEnum);
245 pascii(p, REMSmb_NetSessionEnum_P); /* request descriptor */
246 pascii(p, REMSmb_session_info_10); /* reply descriptor */
247 pl16(p, 10); /* detail level */
248 pl16(p, s->mtu - 1024); /* receive buffer length */
257 err = gl16(p); /* error code */
258 conv = gl16(p); /* rx buffer offset */
259 nret = gl16(p); /* number of entries returned */
260 navail = gl16(p); /* number of entries available */
262 if(err && err != RAP_ERR_MOREINFO){
263 werrstr("%s", raperrstr(err));
269 *sip = emalloc9p(sizeof(Sessinfo) * navail);
270 memset(*sip, 0, sizeof(Sessinfo) * navail);
275 gconv(p, conv, tmp, sizeof tmp);
276 q->wrkstn = estrdup9p(tmp);
277 gconv(p, conv, tmp, sizeof tmp);
278 q->user = estrdup9p(tmp);
279 q->sesstime = gl32(p);
280 q->idletime = gl32(p);
285 fprint(2, "warning: %d/%d - session list incomplete\n", ngot, navail);
292 RAPgroupenum(Session *s, Share *sp, Namelist **nlp)
294 int ngot, err, navail, nret;
301 pstr(p, "\\PIPE\\LANMAN");
304 pl16(p, API_WGroupEnum);
305 pascii(p, REMSmb_NetGroupEnum_P); /* request descriptor */
306 pascii(p, REMSmb_group_info_0); /* reply descriptor */
307 pl16(p, 0); /* detail level */
308 pl16(p, s->mtu - 1024); /* receive buffer length */
317 err = gl16(p); /* error code */
318 gl16(p); /* rx buffer offset */
319 nret = gl16(p); /* number of entries returned */
320 navail = gl16(p); /* number of entries available */
322 if(err && err != RAP_ERR_MOREINFO){
323 werrstr("%s", raperrstr(err));
328 *nlp = emalloc9p(sizeof(Namelist) * navail);
329 memset(*nlp, 0, sizeof(Namelist) * navail);
332 while(ngot < navail && nret--){
335 q->name = estrdup9p(tmp);
338 if(p->pos >= p->eop) /* Windows seems to lie somtimes */
347 RAPgroupusers(Session *s, Share *sp, char *group, Namelist **nlp)
349 int ngot, err, navail, nret;
356 pstr(p, "\\PIPE\\LANMAN");
359 pl16(p, API_WGroupGetUsers);
360 pascii(p, REMSmb_NetGroupGetUsers_P); /* request descriptor */
361 pascii(p, REMSmb_user_info_0); /* reply descriptor */
362 pascii(p, group); /* group name for list */
363 pl16(p, 0); /* detail level */
364 pl16(p, s->mtu - 1024); /* receive buffer length */
373 err = gl16(p); /* error code */
374 gl16(p); /* rx buffer offset */
375 nret = gl16(p); /* number of entries returned */
376 navail = gl16(p); /* number of entries available */
378 if(err && err != RAP_ERR_MOREINFO){
379 werrstr("%s", raperrstr(err));
384 *nlp = emalloc9p(sizeof(Namelist) * navail);
385 memset(*nlp, 0, sizeof(Namelist) * navail);
388 while(ngot < navail && nret--){
391 q->name = estrdup9p(tmp);
394 if(p->pos >= p->eop) /* Windows seems to lie somtimes */
402 RAPuserenum(Session *s, Share *sp, Namelist **nlp)
404 int ngot, err, navail, nret;
411 pstr(p, "\\PIPE\\LANMAN");
414 pl16(p, API_WUserEnum);
415 pascii(p, REMSmb_NetUserEnum_P); /* request descriptor */
416 pascii(p, REMSmb_user_info_0); /* reply descriptor */
417 pl16(p, 0); /* detail level */
418 pl16(p, s->mtu - 1024); /* receive buffer length */
427 err = gl16(p); /* error code */
428 gl16(p); /* rx buffer offset */
429 nret = gl16(p); /* number of entries returned */
430 navail = gl16(p); /* number of entries available */
432 if(err && err != RAP_ERR_MOREINFO){
433 werrstr("%s", raperrstr(err));
438 *nlp = emalloc9p(sizeof(Namelist) * navail);
439 memset(*nlp, 0, sizeof(Namelist) * navail);
442 while(ngot < navail && nret--){
445 q->name = estrdup9p(tmp);
448 if(p->pos >= p->eop) /* Windows seems to lie somtimes */
456 RAPuserenum2(Session *s, Share *sp, Namelist **nlp)
458 int ngot, resume, err, navail, nret;
467 pstr(p, "\\PIPE\\LANMAN");
470 pl16(p, API_WUserEnum2);
471 pascii(p, REMSmb_NetUserEnum2_P); /* request descriptor */
472 pascii(p, REMSmb_user_info_0); /* reply descriptor */
473 pl16(p, 0); /* detail level */
474 pl16(p, s->mtu - 1024); /* receive buffer length */
475 pl32(p, resume); /* resume key to allow multiple fetches */
484 err = gl16(p); /* error code */
485 gl16(p); /* rx buffer offset */
486 resume = gl32(p); /* resume key returned */
487 nret = gl16(p); /* number of entries returned */
488 navail = gl16(p); /* number of entries available */
490 if(err && err != RAP_ERR_MOREINFO){
491 werrstr("%s", raperrstr(err));
497 *nlp = emalloc9p(sizeof(Namelist) * navail);
498 memset(*nlp, 0, sizeof(Namelist) * navail);
501 while(ngot < navail && nret--){
504 q->name = estrdup9p(tmp);
507 if(p->pos >= p->eop) /* Windows seems to lie somtimes */
517 RAPuserinfo(Session *s, Share *sp, char *user, Userinfo *uip)
524 pstr(p, "\\PIPE\\LANMAN");
527 pl16(p, API_WUserGetInfo);
528 pascii(p, REMSmb_NetUserGetInfo_P); /* request descriptor */
529 pascii(p, REMSmb_user_info_10); /* reply descriptor */
530 pascii(p, user); /* username */
531 pl16(p, 10); /* detail level */
532 pl16(p, s->mtu - 1024); /* receive buffer length */
541 err = gl16(p); /* error code */
542 conv = gl16(p); /* rx buffer offset */
543 gl16(p); /* number of entries returned */
544 gl16(p); /* number of entries available */
546 if(err && err != RAP_ERR_MOREINFO){
547 werrstr("%s", raperrstr(err));
554 uip->user = estrdup9p(tmp);
556 gconv(p, conv, tmp, sizeof tmp);
557 uip->comment = estrdup9p(tmp);
558 gconv(p, conv, tmp, sizeof tmp);
559 uip->user_comment = estrdup9p(tmp);
560 gconv(p, conv, tmp, sizeof tmp);
561 uip->fullname = estrdup9p(tmp);
568 * This works agains win2k3 but fails
569 * against XP with the undocumented error 71/0x47
572 RAPServerenum2(Session *s, Share *sp, char *workgroup, int type, int *more,
575 int ngot = 0, conv, err, nret, navail;
581 pstr(p, "\\PIPE\\LANMAN");
584 pl16(p, API_NetServerEnum2);
585 pascii(p, REMSmb_NetServerEnum2_P); /* request descriptor */
586 pascii(p, REMSmb_server_info_1); /* reply descriptor */
587 pl16(p, 1); /* detail level */
588 pl16(p, s->mtu - 1024); /* receive buffer length */
590 pascii(p, workgroup);
600 err = gl16(p); /* error code */
601 conv = gl16(p); /* rx buffer offset */
602 nret = gl16(p); /* number of entries returned */
603 navail = gl16(p); /* number of entries available */
605 if(err && err != RAP_ERR_MOREINFO){
606 werrstr("%s", raperrstr(err));
611 *si = emalloc9p(sizeof(Serverinfo) * navail);
612 memset(*si, 0, sizeof(Serverinfo) * navail);
615 for (; nret-- != 0 && ngot < navail; ngot++){
618 q->name = estrdup9p(tmp);
622 gconv(p, conv, tmp, sizeof tmp);
623 q->comment = estrdup9p(tmp);
627 *more = err == RAP_ERR_MOREINFO;
632 RAPServerenum3(Session *s, Share *sp, char *workgroup, int type, int last,
635 int conv, err, ngot, nret, navail;
636 char *first, tmp[1024];
641 first = si[last].name;
644 pstr(p, "\\PIPE\\LANMAN");
647 pl16(p, API_NetServerEnum3);
648 pascii(p, REMSmb_NetServerEnum3_P); /* request descriptor */
649 pascii(p, REMSmb_server_info_1); /* reply descriptor */
650 pl16(p, 1); /* detail level */
651 pl16(p, s->mtu - 1024); /* receive buffer length */
653 pascii(p, workgroup);
664 err = gl16(p); /* error code */
665 conv = gl16(p); /* rx buffer offset */
666 nret = gl16(p); /* number of entries returned */
667 navail = gl16(p); /* number of entries available */
669 if(err && err != RAP_ERR_MOREINFO){
670 werrstr("%s", raperrstr(err));
675 if(nret < 2){ /* paranoia */
681 while(nret-- != 0 && ngot < navail){
684 q->name = estrdup9p(tmp);
688 gconv(p, conv, tmp, sizeof tmp);
689 tmp[sizeof tmp - 1] = 0;
690 q->comment = estrdup9p(tmp);
691 if(strcmp(first, tmp) == 0){ /* 1st one thru _may_ be a repeat */
705 /* Only the Administrator has permission to do this */
707 RAPFileenum2(Session *s, Share *sp, char *user, char *path, Fileinfo **fip)
709 int conv, err, ngot, resume, nret, navail;
718 pstr(p, "\\PIPE\\LANMAN");
721 pl16(p, API_WFileEnum2);
722 pascii(p, REMSmb_NetFileEnum2_P); /* request descriptor */
723 pascii(p, REMSmb_file_info_1); /* reply descriptor */
726 pl16(p, 1); /* detail level */
727 pl16(p, s->mtu - 1024); /* receive buffer length */
728 pl32(p, resume); /* resume key */
729 /* FIXME: maybe the padding and resume key are the wrong way around? */
730 pl32(p, 0); /* padding ? */
740 err = gl16(p); /* error code */
741 conv = gl16(p); /* rx buffer offset */
742 resume = gl32(p); /* resume key returned */
743 nret = gl16(p); /* number of entries returned */
744 navail = gl16(p); /* number of entries available */
746 if(err && err != RAP_ERR_MOREINFO){
747 werrstr("%s", raperrstr(err));
752 if(nret < 2){ /* paranoia */
758 *fip = emalloc9p(sizeof(Fileinfo) * navail);
759 memset(*fip, 0, sizeof(Fileinfo) * navail);
762 for(; nret-- && ngot < navail; ngot++){
766 gconv(p, conv, tmp, sizeof tmp);
767 tmp[sizeof tmp - 1] = 0;
768 q->path = estrdup9p(tmp);
769 gconv(p, conv, tmp, sizeof tmp);
770 tmp[sizeof tmp - 1] = 0;
771 q->user = estrdup9p(tmp);