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 */
114 RAPshareenum(Session *s, Share *sp, Share **ent)
116 int ngot = 0, err, navail, nret;
122 pstr(p, "\\PIPE\\LANMAN");
125 pl16(p, API_WShareEnum);
126 pascii(p, REMSmb_NetShareEnum_P); /* request descriptor */
127 pascii(p, REMSmb_share_info_0); /* reply descriptor */
128 pl16(p, 0); /* detail level */
129 pl16(p, s->mtu - 1024); /* receive buffer length */
138 err = gl16(p); /* error code */
139 gl16(p); /* rx buffer offset */
140 nret = gl16(p); /* number of entries returned */
141 navail = gl16(p); /* number of entries available */
143 if(err && err != RAP_ERR_MOREINFO){
144 werrstr("%s", raperrstr(err));
150 *ent = emalloc9p(sizeof(Share) * navail);
151 memset(*ent, 0, sizeof(Share) * navail);
155 for (; ngot < navail && nret--; ngot++){
156 gmem(p, tmp, 13); /* name */
158 q->name = estrdup9p(tmp);
163 fprint(2, "%s: %d/%d - share list incomplete\n", argv0, ngot, navail);
171 RAPshareinfo(Session *s, Share *sp, char *share, Shareinfo2 *si2p)
178 pstr(p, "\\PIPE\\LANMAN");
181 pl16(p, API_WShareGetInfo);
182 pascii(p, REMSmb_NetShareGetInfo_P); /* request descriptor */
183 pascii(p, REMSmb_share_info_2); /* reply descriptor */
185 pl16(p, 1); /* detail level */
186 pl16(p, s->mtu - 1024); /* receive buffer length */
196 err = gl16(p); /* error code */
197 conv = gl16(p); /* rx buffer offset */
198 gl16(p); /* number of entries returned */
199 gl16(p); /* number of entries available */
202 werrstr("%s", raperrstr(err));
207 memset(si2p, 0, sizeof(Shareinfo2));
212 si2p->name = estrdup9p(tmp);
213 si2p->type = gl16(p);
214 gconv(p, conv, tmp, sizeof tmp);
215 si2p->comment = estrdup9p(tmp);
216 gl16(p); /* comment offset high (unused) */
217 si2p->perms = gl16(p);
218 si2p->maxusrs = gl16(p);
219 si2p->activeusrs = gl16(p);
220 gconv(p, conv, tmp, sizeof tmp);
221 si2p->path = estrdup9p(tmp);
222 gl16(p); /* path offset high (unused) */
225 si2p->passwd = estrdup9p(tmp);
232 * Tried to split sessionenum into two passes, one getting the names
233 * of the connected workstations and the other collecting the detailed info,
234 * however API_WSessionGetInfo doesn't seem to work agains win2k3 for infolevel
235 * ten and infolevel one and two are priviledged calls. This means this code
236 * will work for small numbers of sessions agains win2k3 and fail for samba 3.0
237 * as it supports info levels zero and two only.
240 RAPsessionenum(Session *s, Share *sp, Sessinfo **sip)
242 int ngot = 0, conv, err, navail, nret;
248 pstr(p, "\\PIPE\\LANMAN");
251 pl16(p, API_WSessionEnum);
252 pascii(p, REMSmb_NetSessionEnum_P); /* request descriptor */
253 pascii(p, REMSmb_session_info_10); /* reply descriptor */
254 pl16(p, 10); /* detail level */
255 pl16(p, s->mtu - 1024); /* receive buffer length */
264 err = gl16(p); /* error code */
265 conv = gl16(p); /* rx buffer offset */
266 nret = gl16(p); /* number of entries returned */
267 navail = gl16(p); /* number of entries available */
269 if(err && err != RAP_ERR_MOREINFO){
270 werrstr("%s", raperrstr(err));
276 *sip = emalloc9p(sizeof(Sessinfo) * navail);
277 memset(*sip, 0, sizeof(Sessinfo) * navail);
282 gconv(p, conv, tmp, sizeof tmp);
283 q->wrkstn = estrdup9p(tmp);
284 gconv(p, conv, tmp, sizeof tmp);
285 q->user = estrdup9p(tmp);
286 q->sesstime = gl32(p);
287 q->idletime = gl32(p);
292 // fprint(2, "warning: %d/%d - session list incomplete\n", ngot, navail);
299 RAPgroupenum(Session *s, Share *sp, Namelist **nlp)
301 int ngot, err, navail, nret;
308 pstr(p, "\\PIPE\\LANMAN");
311 pl16(p, API_WGroupEnum);
312 pascii(p, REMSmb_NetGroupEnum_P); /* request descriptor */
313 pascii(p, REMSmb_group_info_0); /* reply descriptor */
314 pl16(p, 0); /* detail level */
315 pl16(p, s->mtu - 1024); /* receive buffer length */
324 err = gl16(p); /* error code */
325 gl16(p); /* rx buffer offset */
326 nret = gl16(p); /* number of entries returned */
327 navail = gl16(p); /* number of entries available */
329 if(err && err != RAP_ERR_MOREINFO){
330 werrstr("%s", raperrstr(err));
335 *nlp = emalloc9p(sizeof(Namelist) * navail);
336 memset(*nlp, 0, sizeof(Namelist) * navail);
339 while(ngot < navail && nret--){
342 q->name = estrdup9p(tmp);
345 if(p->pos >= p->eop) /* Windows seems to lie somtimes */
354 RAPgroupusers(Session *s, Share *sp, char *group, Namelist **nlp)
356 int ngot, err, navail, nret;
363 pstr(p, "\\PIPE\\LANMAN");
366 pl16(p, API_WGroupGetUsers);
367 pascii(p, REMSmb_NetGroupGetUsers_P); /* request descriptor */
368 pascii(p, REMSmb_user_info_0); /* reply descriptor */
369 pascii(p, group); /* group name for list */
370 pl16(p, 0); /* detail level */
371 pl16(p, s->mtu - 1024); /* receive buffer length */
380 err = gl16(p); /* error code */
381 gl16(p); /* rx buffer offset */
382 nret = gl16(p); /* number of entries returned */
383 navail = gl16(p); /* number of entries available */
385 if(err && err != RAP_ERR_MOREINFO){
386 werrstr("%s", raperrstr(err));
391 *nlp = emalloc9p(sizeof(Namelist) * navail);
392 memset(*nlp, 0, sizeof(Namelist) * navail);
395 while(ngot < navail && nret--){
398 q->name = estrdup9p(tmp);
401 if(p->pos >= p->eop) /* Windows seems to lie somtimes */
409 RAPuserenum(Session *s, Share *sp, Namelist **nlp)
411 int ngot, err, navail, nret;
418 pstr(p, "\\PIPE\\LANMAN");
421 pl16(p, API_WUserEnum);
422 pascii(p, REMSmb_NetUserEnum_P); /* request descriptor */
423 pascii(p, REMSmb_user_info_0); /* reply descriptor */
424 pl16(p, 0); /* detail level */
425 pl16(p, s->mtu - 1024); /* receive buffer length */
434 err = gl16(p); /* error code */
435 gl16(p); /* rx buffer offset */
436 nret = gl16(p); /* number of entries returned */
437 navail = gl16(p); /* number of entries available */
439 if(err && err != RAP_ERR_MOREINFO){
440 werrstr("%s", raperrstr(err));
445 *nlp = emalloc9p(sizeof(Namelist) * navail);
446 memset(*nlp, 0, sizeof(Namelist) * navail);
449 while(ngot < navail && nret--){
452 q->name = estrdup9p(tmp);
455 if(p->pos >= p->eop) /* Windows seems to lie somtimes */
463 RAPuserenum2(Session *s, Share *sp, Namelist **nlp)
465 int ngot, resume, err, navail, nret;
474 pstr(p, "\\PIPE\\LANMAN");
477 pl16(p, API_WUserEnum2);
478 pascii(p, REMSmb_NetUserEnum2_P); /* request descriptor */
479 pascii(p, REMSmb_user_info_0); /* reply descriptor */
480 pl16(p, 0); /* detail level */
481 pl16(p, s->mtu - 1024); /* receive buffer length */
482 pl32(p, resume); /* resume key to allow multiple fetches */
491 err = gl16(p); /* error code */
492 gl16(p); /* rx buffer offset */
493 resume = gl32(p); /* resume key returned */
494 nret = gl16(p); /* number of entries returned */
495 navail = gl16(p); /* number of entries available */
497 if(err && err != RAP_ERR_MOREINFO){
498 werrstr("%s", raperrstr(err));
504 *nlp = emalloc9p(sizeof(Namelist) * navail);
505 memset(*nlp, 0, sizeof(Namelist) * navail);
508 while(ngot < navail && nret--){
511 q->name = estrdup9p(tmp);
514 if(p->pos >= p->eop) /* Windows seems to lie somtimes */
524 RAPuserinfo(Session *s, Share *sp, char *user, Userinfo *uip)
531 pstr(p, "\\PIPE\\LANMAN");
534 pl16(p, API_WUserGetInfo);
535 pascii(p, REMSmb_NetUserGetInfo_P); /* request descriptor */
536 pascii(p, REMSmb_user_info_10); /* reply descriptor */
537 pascii(p, user); /* username */
538 pl16(p, 10); /* detail level */
539 pl16(p, s->mtu - 1024); /* receive buffer length */
548 err = gl16(p); /* error code */
549 conv = gl16(p); /* rx buffer offset */
550 gl16(p); /* number of entries returned */
551 gl16(p); /* number of entries available */
553 if(err && err != RAP_ERR_MOREINFO){
554 werrstr("%s", raperrstr(err));
561 uip->user = estrdup9p(tmp);
563 gconv(p, conv, tmp, sizeof tmp);
564 uip->comment = estrdup9p(tmp);
565 gconv(p, conv, tmp, sizeof tmp);
566 uip->user_comment = estrdup9p(tmp);
567 gconv(p, conv, tmp, sizeof tmp);
568 uip->fullname = estrdup9p(tmp);
575 * This works agains win2k3 but fails
576 * against XP with the undocumented error 71/0x47
579 RAPServerenum2(Session *s, Share *sp, char *workgroup, int type, int *more,
582 int ngot = 0, conv, err, nret, navail;
588 pstr(p, "\\PIPE\\LANMAN");
591 pl16(p, API_NetServerEnum2);
592 pascii(p, REMSmb_NetServerEnum2_P); /* request descriptor */
593 pascii(p, REMSmb_server_info_1); /* reply descriptor */
594 pl16(p, 1); /* detail level */
595 pl16(p, s->mtu - 1024); /* receive buffer length */
597 pascii(p, workgroup);
607 err = gl16(p); /* error code */
608 conv = gl16(p); /* rx buffer offset */
609 nret = gl16(p); /* number of entries returned */
610 navail = gl16(p); /* number of entries available */
612 if(err && err != RAP_ERR_MOREINFO){
613 werrstr("%s", raperrstr(err));
618 *si = emalloc9p(sizeof(Serverinfo) * navail);
619 memset(*si, 0, sizeof(Serverinfo) * navail);
622 for (; nret-- != 0 && ngot < navail; ngot++){
625 q->name = estrdup9p(tmp);
629 gconv(p, conv, tmp, sizeof tmp);
630 q->comment = estrdup9p(tmp);
634 *more = err == RAP_ERR_MOREINFO;
639 RAPServerenum3(Session *s, Share *sp, char *workgroup, int type, int last,
642 int conv, err, ngot, nret, navail;
643 char *first, tmp[1024];
648 first = si[last].name;
651 pstr(p, "\\PIPE\\LANMAN");
654 pl16(p, API_NetServerEnum3);
655 pascii(p, REMSmb_NetServerEnum3_P); /* request descriptor */
656 pascii(p, REMSmb_server_info_1); /* reply descriptor */
657 pl16(p, 1); /* detail level */
658 pl16(p, s->mtu - 1024); /* receive buffer length */
660 pascii(p, workgroup);
671 err = gl16(p); /* error code */
672 conv = gl16(p); /* rx buffer offset */
673 nret = gl16(p); /* number of entries returned */
674 navail = gl16(p); /* number of entries available */
676 if(err && err != RAP_ERR_MOREINFO){
677 werrstr("%s", raperrstr(err));
682 if(nret < 2){ /* paranoia */
688 while(nret-- != 0 && ngot < navail){
691 q->name = estrdup9p(tmp);
695 gconv(p, conv, tmp, sizeof tmp);
696 tmp[sizeof tmp - 1] = 0;
697 q->comment = estrdup9p(tmp);
698 if(strcmp(first, tmp) == 0){ /* 1st one thru _may_ be a repeat */
712 /* Only the Administrator has permission to do this */
714 RAPFileenum2(Session *s, Share *sp, char *user, char *path, Fileinfo **fip)
716 int conv, err, ngot, resume, nret, navail;
725 pstr(p, "\\PIPE\\LANMAN");
728 pl16(p, API_WFileEnum2);
729 pascii(p, REMSmb_NetFileEnum2_P); /* request descriptor */
730 pascii(p, REMSmb_file_info_1); /* reply descriptor */
733 pl16(p, 1); /* detail level */
734 pl16(p, s->mtu - 1024); /* receive buffer length */
735 pl32(p, resume); /* resume key */
736 /* FIXME: maybe the padding and resume key are the wrong way around? */
737 pl32(p, 0); /* padding ? */
747 err = gl16(p); /* error code */
748 conv = gl16(p); /* rx buffer offset */
749 resume = gl32(p); /* resume key returned */
750 nret = gl16(p); /* number of entries returned */
751 navail = gl16(p); /* number of entries available */
753 if(err && err != RAP_ERR_MOREINFO){
754 werrstr("%s", raperrstr(err));
759 if(nret < 2){ /* paranoia */
765 *fip = emalloc9p(sizeof(Fileinfo) * navail);
766 memset(*fip, 0, sizeof(Fileinfo) * navail);
769 for(; nret-- && ngot < navail; ngot++){
773 gconv(p, conv, tmp, sizeof tmp);
774 tmp[sizeof tmp - 1] = 0;
775 q->path = estrdup9p(tmp);
776 gconv(p, conv, tmp, sizeof tmp);
777 tmp[sizeof tmp - 1] = 0;
778 q->user = estrdup9p(tmp);