2 Samba Unix/Linux SMB client library
4 More client RAP (SMB Remote Procedure Calls) functions
5 Copyright (C) 2001 Steve French (sfrench@us.ibm.com)
6 Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /*****************************************************/
26 /* Additional RAP functionality */
28 /* RAP is the original SMB RPC, documented */
29 /* by Microsoft and X/Open in the 1990s and */
30 /* supported by most SMB/CIFS servers although */
31 /* it is unlikely that any one implementation */
32 /* supports all RAP command codes since some */
33 /* are quite obsolete and a few are specific */
34 /* to a particular network operating system */
36 /* Although it has largely been replaced */
37 /* for complex remote admistration and management */
38 /* (of servers) by the relatively newer */
39 /* DCE/RPC based remote API (which better handles */
40 /* large >64K data structures), there are many */
41 /* important administrative and resource location */
42 /* tasks and user tasks (e.g. password change) */
43 /* that are performed via RAP. */
45 /* Although a few of the RAP calls are implemented */
46 /* in the Samba client library already (clirap.c) */
47 /* the new ones are in clirap2.c for easy patching */
48 /* and integration and a corresponding header */
49 /* file, rap.h, has been created. */
51 /* This is based on data from the CIFS spec */
52 /* and the LAN Server and LAN Manager */
53 /* Programming Reference books and published */
54 /* RAP document and CIFS forum postings and */
55 /* lots of trial and error */
57 /* Function names changed from API_ (as they are */
58 /* in the CIFS specification) to RAP_ in order */
59 /* to avoid confusion with other API calls */
60 /* sent via DCE RPC */
62 /*****************************************************/
64 /*****************************************************/
66 /* cifsrap.c already includes support for: */
68 /* WshareEnum ( API number 0, level 1) */
69 /* NetServerEnum2 (API num 104, level 1) */
70 /* WWkstaUserLogon (132) */
71 /* SamOEMchgPasswordUser2_P (214) */
73 /* cifsprint.c already includes support for: */
75 /* WPrintJobEnum (API num 76, level 2) */
76 /* WPrintJobDel (API num 81) */
78 /*****************************************************/
87 #define PUTBYTE(p,b) do {SCVAL(p,0,b); p++;} while(0)
88 #define GETBYTE(p,b) do {b = CVAL(p,0); p++;} while(0)
89 #define PUTWORD(p,w) do {SSVAL(p,0,w); p += WORDSIZE;} while(0)
90 #define GETWORD(p,w) do {w = SVAL(p,0); p += WORDSIZE;} while(0)
91 #define PUTDWORD(p,d) do {SIVAL(p,0,d); p += DWORDSIZE;} while(0)
92 #define GETDWORD(p,d) do {d = IVAL(p,0); p += DWORDSIZE;} while(0)
93 #define GETRES(p) p ? SVAL(p,0) : -1
94 /* put string s at p with max len n and increment p past string */
95 #define PUTSTRING(p,s,n) do {\
96 push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\
97 p = skip_string(p,1);\
99 /* put string s and p, using fixed len l, and increment p by l */
100 #define PUTSTRINGF(p,s,l) do {\
101 push_ascii(p,s?s:"",l,STR_TERMINATE);\
104 /* put string pointer at p, supplying offset o from rdata r, store */
105 /* dword offset at p, increment p by 4 and o by length of s. This */
106 /* means on the first call, you must calc the offset yourself! */
107 #define PUTSTRINGP(p,s,r,o) do {\
109 push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\
112 } else PUTDWORD(p,0);\
114 /* get asciiz string s from p, increment p past string */
115 #define GETSTRING(p,s) do {\
116 pull_ascii_pstring(s,p);\
117 p = skip_string(p,1);\
119 /* get fixed length l string s from p, increment p by l */
120 #define GETSTRINGF(p,s,l) do {\
121 pull_ascii_pstring(s,p);\
124 /* get string s from offset (obtained at p) from rdata r - converter c */
125 #define GETSTRINGP(p,s,r,c) do {\
128 off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */ \
129 pull_ascii_pstring(s, off?(r+off-c):"");\
132 static char *make_header(char *param
, uint16 apinum
, char *reqfmt
, char *datafmt
)
134 PUTWORD(param
,apinum
);
136 PUTSTRING(param
,reqfmt
,0);
141 PUTSTRING(param
,datafmt
,0);
149 /****************************************************************************
150 call a NetGroupDelete - delete user group from remote server
151 ****************************************************************************/
152 int cli_NetGroupDelete(struct cli_state
*cli
, const char *group_name
)
157 int rdrcnt
,rprcnt
, res
;
158 char param
[WORDSIZE
/* api number */
159 +sizeof(RAP_NetGroupDel_REQ
) /* parm string */
160 +1 /* no ret string */
161 +RAP_GROUPNAME_LEN
/* group to del */
162 +WORDSIZE
]; /* reserved word */
164 /* now send a SMBtrans command with api GroupDel */
165 p
= make_header(param
, RAP_WGroupDel
, RAP_NetGroupDel_REQ
, NULL
);
166 PUTSTRING(p
, group_name
, RAP_GROUPNAME_LEN
);
167 PUTWORD(p
,0); /* reserved word MBZ on input */
170 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
171 NULL
, 0, 200, /* data, length, maxlen */
172 &rparam
, &rprcnt
, /* return params, length */
173 &rdata
, &rdrcnt
)) /* return data, length */
175 res
= GETRES(rparam
);
180 else if ((res
== 5) || (res
== 65)) {
181 DEBUG(1, ("Access Denied\n"));
183 else if (res
== 2220) {
184 DEBUG (1, ("Group does not exist\n"));
187 DEBUG(4,("NetGroupDelete res=%d\n", res
));
191 DEBUG(4,("NetGroupDelete failed\n"));
200 /****************************************************************************
201 call a NetGroupAdd - add user group to remote server
202 ****************************************************************************/
203 int cli_NetGroupAdd(struct cli_state
*cli
, RAP_GROUP_INFO_1
* grinfo
)
208 int rdrcnt
,rprcnt
,res
;
209 char param
[WORDSIZE
/* api number */
210 +sizeof(RAP_NetGroupAdd_REQ
) /* req string */
211 +sizeof(RAP_GROUP_INFO_L1
) /* return string */
212 +WORDSIZE
/* info level */
213 +WORDSIZE
]; /* reserved word */
217 /* offset into data of free format strings. Will be updated */
218 /* by PUTSTRINGP macro and end up with total data length. */
219 int soffset
= RAP_GROUPNAME_LEN
+ 1 + DWORDSIZE
;
221 /* now send a SMBtrans command with api WGroupAdd */
223 p
= make_header(param
, RAP_WGroupAdd
,
224 RAP_NetGroupAdd_REQ
, RAP_GROUP_INFO_L1
);
225 PUTWORD(p
, 1); /* info level */
226 PUTWORD(p
, 0); /* reserved word 0 */
229 PUTSTRINGF(p
, grinfo
->group_name
, RAP_GROUPNAME_LEN
);
230 PUTBYTE(p
, 0); /* pad byte 0 */
231 PUTSTRINGP(p
, grinfo
->comment
, data
, soffset
);
234 param
, sizeof(param
), 1024, /* Param, length, maxlen */
235 data
, soffset
, sizeof(data
), /* data, length, maxlen */
236 &rparam
, &rprcnt
, /* return params, length */
237 &rdata
, &rdrcnt
)) /* return data, length */
239 res
= GETRES(rparam
);
243 } else if ((res
== 5) || (res
== 65)) {
244 DEBUG(1, ("Access Denied\n"));
246 else if (res
== 2223) {
247 DEBUG (1, ("Group already exists\n"));
250 DEBUG(4,("NetGroupAdd res=%d\n", res
));
254 DEBUG(4,("NetGroupAdd failed\n"));
263 /****************************************************************************
264 call a NetGroupEnum - try and list user groups on a different host
265 ****************************************************************************/
266 int cli_RNetGroupEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, void *), void *state
)
268 char param
[WORDSIZE
/* api number */
269 +sizeof(RAP_NetGroupEnum_REQ
) /* parm string */
270 +sizeof(RAP_GROUP_INFO_L1
) /* return string */
271 +WORDSIZE
/* info level */
272 +WORDSIZE
]; /* buffer size */
280 memset(param
, '\0', sizeof(param
));
281 p
= make_header(param
, RAP_WGroupEnum
,
282 RAP_NetGroupEnum_REQ
, RAP_GROUP_INFO_L1
);
283 PUTWORD(p
,1); /* Info level 1 */ /* add level 0 */
284 PUTWORD(p
,0xFFE0); /* Return buffer size */
287 param
, PTR_DIFF(p
,param
),8,
288 NULL
, 0, 0xFFE0 /* data area size */,
291 res
= GETRES(rparam
);
292 cli
->rap_error
= res
;
293 if(cli
->rap_error
== 234)
294 DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
295 else if (cli
->rap_error
!= 0) {
296 DEBUG(1,("NetGroupEnum gave error %d\n", cli
->rap_error
));
301 if (res
== 0 || res
== ERRmoredata
) {
302 int i
, converter
, count
;
304 p
= rparam
+ WORDSIZE
; /* skip result */
305 GETWORD(p
, converter
);
308 for (i
=0,p
=rdata
;i
<count
;i
++) {
310 char groupname
[RAP_GROUPNAME_LEN
];
312 GETSTRINGF(p
, groupname
, RAP_GROUPNAME_LEN
);
314 GETSTRINGP(p
, comment
, rdata
, converter
);
316 fn(groupname
, comment
, cli
);
319 DEBUG(4,("NetGroupEnum res=%d\n", res
));
322 DEBUG(4,("NetGroupEnum no data returned\n"));
331 int cli_NetGroupDelUser(struct cli_state
* cli
, const char *group_name
, const char *user_name
)
336 int rdrcnt
,rprcnt
,res
;
337 char param
[WORDSIZE
/* api number */
338 +sizeof(RAP_NetGroupDelUser_REQ
) /* parm string */
339 +1 /* no ret string */
340 +RAP_GROUPNAME_LEN
/* group name */
341 +RAP_USERNAME_LEN
]; /* user to del */
343 /* now send a SMBtrans command with api GroupMemberAdd */
344 p
= make_header(param
, RAP_WGroupDelUser
, RAP_NetGroupDelUser_REQ
, NULL
);
345 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
);
346 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
);
349 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
350 NULL
, 0, 200, /* data, length, maxlen */
351 &rparam
, &rprcnt
, /* return params, length */
352 &rdata
, &rdrcnt
)) /* return data, length */
354 res
= GETRES(rparam
);
361 DEBUG(1, ("Access Denied\n"));
364 DEBUG(1, ("Not supported by server\n"));
367 DEBUG(1, ("Group does not exist\n"));
370 DEBUG(1, ("User does not exist\n"));
373 DEBUG(1, ("User is not in group\n"));
376 DEBUG(4,("NetGroupDelUser res=%d\n", res
));
380 DEBUG(4,("NetGroupDelUser failed\n"));
389 int cli_NetGroupAddUser(struct cli_state
* cli
, const char *group_name
, const char *user_name
)
394 int rdrcnt
,rprcnt
,res
;
395 char param
[WORDSIZE
/* api number */
396 +sizeof(RAP_NetGroupAddUser_REQ
) /* parm string */
397 +1 /* no ret string */
398 +RAP_GROUPNAME_LEN
/* group name */
399 +RAP_USERNAME_LEN
]; /* user to add */
401 /* now send a SMBtrans command with api GroupMemberAdd */
402 p
= make_header(param
, RAP_WGroupAddUser
, RAP_NetGroupAddUser_REQ
, NULL
);
403 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
);
404 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
);
407 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
408 NULL
, 0, 200, /* data, length, maxlen */
409 &rparam
, &rprcnt
, /* return params, length */
410 &rdata
, &rdrcnt
)) /* return data, length */
412 res
= GETRES(rparam
);
419 DEBUG(1, ("Access Denied\n"));
422 DEBUG(1, ("Not supported by server\n"));
425 DEBUG(1, ("Group does not exist\n"));
428 DEBUG(1, ("User does not exist\n"));
431 DEBUG(4,("NetGroupAddUser res=%d\n", res
));
435 DEBUG(4,("NetGroupAddUser failed\n"));
445 int cli_NetGroupGetUsers(struct cli_state
* cli
, const char *group_name
, void (*fn
)(const char *, void *), void *state
)
452 char param
[WORDSIZE
/* api number */
453 +sizeof(RAP_NetGroupGetUsers_REQ
)/* parm string */
454 +sizeof(RAP_GROUP_USERS_INFO_0
) /* return string */
455 +RAP_GROUPNAME_LEN
/* group name */
456 +WORDSIZE
/* info level */
457 +WORDSIZE
]; /* buffer size */
459 /* now send a SMBtrans command with api GroupGetUsers */
460 p
= make_header(param
, RAP_WGroupGetUsers
,
461 RAP_NetGroupGetUsers_REQ
, RAP_GROUP_USERS_INFO_0
);
462 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
-1);
463 PUTWORD(p
,0); /* info level 0 */
464 PUTWORD(p
,0xFFE0); /* return buffer size */
467 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
468 NULL
, 0, CLI_BUFFER_SIZE
,
471 res
= GETRES(rparam
);
472 cli
->rap_error
= res
;
474 DEBUG(1,("NetGroupGetUsers gave error %d\n", res
));
478 if (res
== 0 || res
== ERRmoredata
) {
479 int i
, converter
, count
;
481 p
= rparam
+WORDSIZE
;
482 GETWORD(p
, converter
);
485 for (i
=0,p
=rdata
; i
<count
; i
++) {
486 GETSTRINGF(p
, username
, RAP_USERNAME_LEN
);
490 DEBUG(4,("NetGroupGetUsers res=%d\n", res
));
493 DEBUG(4,("NetGroupGetUsers no data returned\n"));
500 int cli_NetUserGetGroups(struct cli_state
* cli
, const char *user_name
, void (*fn
)(const char *, void *), void *state
)
507 char param
[WORDSIZE
/* api number */
508 +sizeof(RAP_NetUserGetGroups_REQ
)/* parm string */
509 +sizeof(RAP_GROUP_USERS_INFO_0
) /* return string */
510 +RAP_USERNAME_LEN
/* user name */
511 +WORDSIZE
/* info level */
512 +WORDSIZE
]; /* buffer size */
514 /* now send a SMBtrans command with api GroupGetUsers */
515 p
= make_header(param
, RAP_WUserGetGroups
,
516 RAP_NetUserGetGroups_REQ
, RAP_GROUP_USERS_INFO_0
);
517 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
-1);
518 PUTWORD(p
,0); /* info level 0 */
519 PUTWORD(p
,0xFFE0); /* return buffer size */
522 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
523 NULL
, 0, CLI_BUFFER_SIZE
,
526 res
= GETRES(rparam
);
527 cli
->rap_error
= res
;
529 DEBUG(1,("NetUserGetGroups gave error %d\n", res
));
533 if (res
== 0 || res
== ERRmoredata
) {
534 int i
, converter
, count
;
536 p
= rparam
+WORDSIZE
;
537 GETWORD(p
, converter
);
540 for (i
=0,p
=rdata
; i
<count
; i
++) {
541 GETSTRINGF(p
, groupname
, RAP_USERNAME_LEN
);
542 fn(groupname
, state
);
545 DEBUG(4,("NetUserGetGroups res=%d\n", res
));
548 DEBUG(4,("NetUserGetGroups no data returned\n"));
556 /****************************************************************************
557 call a NetUserDelete - delete user from remote server
558 ****************************************************************************/
559 int cli_NetUserDelete(struct cli_state
*cli
, const char * user_name
)
564 int rdrcnt
,rprcnt
, res
;
565 char param
[WORDSIZE
/* api number */
566 +sizeof(RAP_NetGroupDel_REQ
) /* parm string */
567 +1 /* no ret string */
568 +RAP_USERNAME_LEN
/* user to del */
569 +WORDSIZE
]; /* reserved word */
571 /* now send a SMBtrans command with api UserDel */
572 p
= make_header(param
, RAP_WUserDel
, RAP_NetGroupDel_REQ
, NULL
);
573 PUTSTRING(p
, user_name
, RAP_USERNAME_LEN
);
574 PUTWORD(p
,0); /* reserved word MBZ on input */
577 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
578 NULL
, 0, 200, /* data, length, maxlen */
579 &rparam
, &rprcnt
, /* return params, length */
580 &rdata
, &rdrcnt
)) /* return data, length */
582 res
= GETRES(rparam
);
587 else if ((res
== 5) || (res
== 65)) {
588 DEBUG(1, ("Access Denied\n"));
590 else if (res
== 2221) {
591 DEBUG (1, ("User does not exist\n"));
594 DEBUG(4,("NetUserDelete res=%d\n", res
));
598 DEBUG(4,("NetUserDelete failed\n"));
607 /****************************************************************************
608 call a NetUserAdd - add user to remote server
609 ****************************************************************************/
610 int cli_NetUserAdd(struct cli_state
*cli
, RAP_USER_INFO_1
* userinfo
)
618 int rdrcnt
,rprcnt
,res
;
619 char param
[WORDSIZE
/* api number */
620 +sizeof(RAP_NetUserAdd2_REQ
) /* req string */
621 +sizeof(RAP_USER_INFO_L1
) /* data string */
622 +WORDSIZE
/* info level */
623 +WORDSIZE
/* buffer length */
624 +WORDSIZE
]; /* reserved */
627 /* offset into data of free format strings. Will be updated */
628 /* by PUTSTRINGP macro and end up with total data length. */
629 int soffset
=RAP_USERNAME_LEN
+1 /* user name + pad */
630 + RAP_UPASSWD_LEN
/* password */
631 + DWORDSIZE
/* password age */
632 + WORDSIZE
/* privilege */
633 + DWORDSIZE
/* home dir ptr */
634 + DWORDSIZE
/* comment ptr */
635 + WORDSIZE
/* flags */
636 + DWORDSIZE
; /* login script ptr*/
638 /* now send a SMBtrans command with api NetUserAdd */
639 p
= make_header(param
, RAP_WUserAdd2
,
640 RAP_NetUserAdd2_REQ
, RAP_USER_INFO_L1
);
641 PUTWORD(p
, 1); /* info level */
643 PUTWORD(p
, 0); /* pwencrypt */
644 if(userinfo
->passwrd
)
645 PUTWORD(p
,MIN(strlen(userinfo
->passwrd
), RAP_UPASSWD_LEN
));
647 PUTWORD(p
, 0); /* password length */
650 memset(data
, '\0', soffset
);
652 PUTSTRINGF(p
, userinfo
->user_name
, RAP_USERNAME_LEN
);
653 PUTBYTE(p
, 0); /* pad byte 0 */
654 PUTSTRINGF(p
, userinfo
->passwrd
, RAP_UPASSWD_LEN
);
655 PUTDWORD(p
, 0); /* pw age - n.a. on user add */
656 PUTWORD(p
, userinfo
->priv
);
657 PUTSTRINGP(p
, userinfo
->home_dir
, data
, soffset
);
658 PUTSTRINGP(p
, userinfo
->comment
, data
, soffset
);
659 PUTWORD(p
, userinfo
->userflags
);
660 PUTSTRINGP(p
, userinfo
->logon_script
, data
, soffset
);
663 param
, sizeof(param
), 1024, /* Param, length, maxlen */
664 data
, soffset
, sizeof(data
), /* data, length, maxlen */
665 &rparam
, &rprcnt
, /* return params, length */
666 &rdata
, &rdrcnt
)) /* return data, length */
668 res
= GETRES(rparam
);
673 else if ((res
== 5) || (res
== 65)) {
674 DEBUG(1, ("Access Denied\n"));
676 else if (res
== 2224) {
677 DEBUG (1, ("User already exists\n"));
680 DEBUG(4,("NetUserAdd res=%d\n", res
));
684 DEBUG(4,("NetUserAdd failed\n"));
693 /****************************************************************************
694 call a NetUserEnum - try and list users on a different host
695 ****************************************************************************/
696 int cli_RNetUserEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, const char *, const char *, void *), void *state
)
698 char param
[WORDSIZE
/* api number */
699 +sizeof(RAP_NetUserEnum_REQ
) /* parm string */
700 +sizeof(RAP_USER_INFO_L1
) /* return string */
701 +WORDSIZE
/* info level */
702 +WORDSIZE
]; /* buffer size */
710 memset(param
, '\0', sizeof(param
));
711 p
= make_header(param
, RAP_WUserEnum
,
712 RAP_NetUserEnum_REQ
, RAP_USER_INFO_L1
);
713 PUTWORD(p
,1); /* Info level 1 */
714 PUTWORD(p
,0xFF00); /* Return buffer size */
716 /* BB Fix handling of large numbers of users to be returned */
718 param
, PTR_DIFF(p
,param
),8,
719 NULL
, 0, CLI_BUFFER_SIZE
,
722 res
= GETRES(rparam
);
723 cli
->rap_error
= res
;
724 if (cli
->rap_error
!= 0) {
725 DEBUG(1,("NetUserEnum gave error %d\n", cli
->rap_error
));
729 if (res
== 0 || res
== ERRmoredata
) {
730 int i
, converter
, count
;
731 char username
[RAP_USERNAME_LEN
];
732 char userpw
[RAP_UPASSWD_LEN
];
733 pstring comment
, homedir
, logonscript
;
734 int pwage
, priv
, flags
;
736 p
= rparam
+ WORDSIZE
; /* skip result */
737 GETWORD(p
, converter
);
740 for (i
=0,p
=rdata
;i
<count
;i
++) {
741 GETSTRINGF(p
, username
, RAP_USERNAME_LEN
);
743 GETSTRINGF(p
, userpw
, RAP_UPASSWD_LEN
);
744 GETDWORD(p
, pwage
); /* password age */
745 GETWORD(p
, priv
); /* 0=guest, 1=user, 2=admin */
746 GETSTRINGP(p
, homedir
, rdata
, converter
);
747 GETSTRINGP(p
, comment
, rdata
, converter
);
749 GETSTRINGP(p
, logonscript
, rdata
, converter
);
751 fn(username
, comment
, homedir
, logonscript
, cli
);
754 DEBUG(4,("NetUserEnum res=%d\n", res
));
757 DEBUG(4,("NetUserEnum no data returned\n"));
766 /****************************************************************************
767 call a NetFileClose2 - close open file on another session to server
768 ****************************************************************************/
769 int cli_NetFileClose(struct cli_state
*cli
, uint32 file_id
)
775 char param
[WORDSIZE
/* api number */
776 +sizeof(RAP_WFileClose2_REQ
) /* req string */
777 +1 /* no ret string */
778 +DWORDSIZE
]; /* file ID */
781 /* now send a SMBtrans command with api RNetShareEnum */
782 p
= make_header(param
, RAP_WFileClose2
, RAP_WFileClose2_REQ
, NULL
);
783 PUTDWORD(p
, file_id
);
786 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
787 NULL
, 0, 200, /* data, length, maxlen */
788 &rparam
, &rprcnt
, /* return params, length */
789 &rdata
, &rdrcnt
)) /* return data, length */
791 res
= GETRES(rparam
);
795 } else if (res
== 2314){
796 DEBUG(1, ("NetFileClose2 - attempt to close non-existant file open instance\n"));
798 DEBUG(4,("NetFileClose2 res=%d\n", res
));
802 DEBUG(4,("NetFileClose2 failed\n"));
811 /****************************************************************************
812 call a NetFileGetInfo - get information about server file opened from other
814 ****************************************************************************/
815 int cli_NetFileGetInfo(struct cli_state
*cli
, uint32 file_id
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint32
))
820 int rdrcnt
,rprcnt
, res
;
821 char param
[WORDSIZE
/* api number */
822 +sizeof(RAP_WFileGetInfo2_REQ
) /* req string */
823 +sizeof(RAP_FILE_INFO_L3
) /* return string */
824 +DWORDSIZE
/* file ID */
825 +WORDSIZE
/* info level */
826 +WORDSIZE
]; /* buffer size */
828 /* now send a SMBtrans command with api RNetShareEnum */
829 p
= make_header(param
, RAP_WFileGetInfo2
,
830 RAP_WFileGetInfo2_REQ
, RAP_FILE_INFO_L3
);
831 PUTDWORD(p
, file_id
);
832 PUTWORD(p
, 3); /* info level */
833 PUTWORD(p
, 0x1000); /* buffer size */
835 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
836 NULL
, 0, 0x1000, /* data, length, maxlen */
837 &rparam
, &rprcnt
, /* return params, length */
838 &rdata
, &rdrcnt
)) /* return data, length */
840 res
= GETRES(rparam
);
841 if (res
== 0 || res
== ERRmoredata
) {
842 int converter
,id
, perms
, locks
;
843 pstring fpath
, fuser
;
845 p
= rparam
+ WORDSIZE
; /* skip result */
846 GETWORD(p
, converter
);
852 GETSTRINGP(p
, fpath
, rdata
, converter
);
853 GETSTRINGP(p
, fuser
, rdata
, converter
);
855 fn(fpath
, fuser
, perms
, locks
, id
);
857 DEBUG(4,("NetFileGetInfo2 res=%d\n", res
));
861 DEBUG(4,("NetFileGetInfo2 failed\n"));
870 /****************************************************************************
871 * Call a NetFileEnum2 - list open files on an SMB server
873 * PURPOSE: Remotes a NetFileEnum API call to the current server or target
874 * server listing the files open via the network (and their
875 * corresponding open instance ids)
880 * cli - pointer to cli_state structure
881 * user - if present, return only files opened by this remote user
882 * base_path - if present, return only files opened below this
884 * fn - display function to invoke for each entry in the result
891 ****************************************************************************/
892 int cli_NetFileEnum(struct cli_state
*cli
, char * user
, char * base_path
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint32
))
898 char param
[WORDSIZE
/* api number */
899 +sizeof(RAP_WFileEnum2_REQ
) /* req string */
900 +sizeof(RAP_FILE_INFO_L3
) /* return string */
901 +256 /* base path (opt) */
902 +RAP_USERNAME_LEN
/* user name (opt) */
903 +WORDSIZE
/* info level */
904 +WORDSIZE
/* buffer size */
905 +DWORDSIZE
/* resume key ? */
906 +DWORDSIZE
]; /* resume key ? */
909 /* now send a SMBtrans command with api RNetShareEnum */
910 p
= make_header(param
, RAP_WFileEnum2
,
911 RAP_WFileEnum2_REQ
, RAP_FILE_INFO_L3
);
913 PUTSTRING(p
, base_path
, 256);
914 PUTSTRING(p
, user
, RAP_USERNAME_LEN
);
915 PUTWORD(p
, 3); /* info level */
916 PUTWORD(p
, 0xFF00); /* buffer size */
917 PUTDWORD(p
, 0); /* zero out the resume key */
918 PUTDWORD(p
, 0); /* or is this one the resume key? */
921 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
922 NULL
, 0, 0xFF00, /* data, length, maxlen */
923 &rparam
, &rprcnt
, /* return params, length */
924 &rdata
, &rdrcnt
)) /* return data, length */
926 int res
= GETRES(rparam
);
928 if (res
== 0 || res
== ERRmoredata
) {
931 p
= rparam
+ WORDSIZE
; /* skip result */
932 GETWORD(p
, converter
);
936 for (i
=0; i
<count
; i
++) {
937 int id
, perms
, locks
;
938 pstring fpath
, fuser
;
943 GETSTRINGP(p
, fpath
, rdata
, converter
);
944 GETSTRINGP(p
, fuser
, rdata
, converter
);
946 fn(fpath
, fuser
, perms
, locks
, id
);
947 } /* BB fix ERRmoredata case to send resume request */
949 DEBUG(4,("NetFileEnum2 res=%d\n", res
));
952 DEBUG(4,("NetFileEnum2 failed\n"));
961 /****************************************************************************
962 call a NetShareAdd - share/export directory on remote server
963 ****************************************************************************/
964 int cli_NetShareAdd(struct cli_state
*cli
, RAP_SHARE_INFO_2
* sinfo
)
969 int rdrcnt
,rprcnt
,res
;
970 char param
[WORDSIZE
/* api number */
971 +sizeof(RAP_WShareAdd_REQ
) /* req string */
972 +sizeof(RAP_SHARE_INFO_L2
) /* return string */
973 +WORDSIZE
/* info level */
974 +WORDSIZE
]; /* reserved word */
976 /* offset to free format string section following fixed length data. */
977 /* will be updated by PUTSTRINGP macro and will end up with total len */
978 int soffset
= RAP_SHARENAME_LEN
+ 1 /* share name + pad */
979 + WORDSIZE
/* share type */
980 + DWORDSIZE
/* comment pointer */
981 + WORDSIZE
/* permissions */
982 + WORDSIZE
/* max users */
983 + WORDSIZE
/* active users */
984 + DWORDSIZE
/* share path */
985 + RAP_SPASSWD_LEN
+ 1; /* share password + pad */
987 memset(param
,'\0',sizeof(param
));
988 /* now send a SMBtrans command with api RNetShareAdd */
989 p
= make_header(param
, RAP_WshareAdd
,
990 RAP_WShareAdd_REQ
, RAP_SHARE_INFO_L2
);
991 PUTWORD(p
, 2); /* info level */
992 PUTWORD(p
, 0); /* reserved word 0 */
995 PUTSTRINGF(p
, sinfo
->share_name
, RAP_SHARENAME_LEN
);
996 PUTBYTE(p
, 0); /* pad byte 0 */
998 PUTWORD(p
, sinfo
->share_type
);
999 PUTSTRINGP(p
, sinfo
->comment
, data
, soffset
);
1000 PUTWORD(p
, sinfo
->perms
);
1001 PUTWORD(p
, sinfo
->maximum_users
);
1002 PUTWORD(p
, sinfo
->active_users
);
1003 PUTSTRINGP(p
, sinfo
->path
, data
, soffset
);
1004 PUTSTRINGF(p
, sinfo
->password
, RAP_SPASSWD_LEN
);
1005 SCVAL(p
,-1,0x0A); /* required 0x0A at end of password */
1008 param
, sizeof(param
), 1024, /* Param, length, maxlen */
1009 data
, soffset
, sizeof(data
), /* data, length, maxlen */
1010 &rparam
, &rprcnt
, /* return params, length */
1011 &rdata
, &rdrcnt
)) /* return data, length */
1013 res
= rparam
? SVAL(rparam
,0) : -1;
1019 DEBUG(4,("NetShareAdd res=%d\n", res
));
1023 DEBUG(4,("NetShareAdd failed\n"));
1031 /****************************************************************************
1032 call a NetShareDelete - unshare exported directory on remote server
1033 ****************************************************************************/
1034 int cli_NetShareDelete(struct cli_state
*cli
, const char * share_name
)
1036 char *rparam
= NULL
;
1039 int rdrcnt
,rprcnt
, res
;
1040 char param
[WORDSIZE
/* api number */
1041 +sizeof(RAP_WShareDel_REQ
) /* req string */
1042 +1 /* no ret string */
1043 +RAP_SHARENAME_LEN
/* share to del */
1044 +WORDSIZE
]; /* reserved word */
1047 /* now send a SMBtrans command with api RNetShareDelete */
1048 p
= make_header(param
, RAP_WshareDel
, RAP_WShareDel_REQ
, NULL
);
1049 PUTSTRING(p
,share_name
,RAP_SHARENAME_LEN
);
1050 PUTWORD(p
,0); /* reserved word MBZ on input */
1053 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
1054 NULL
, 0, 200, /* data, length, maxlen */
1055 &rparam
, &rprcnt
, /* return params, length */
1056 &rdata
, &rdrcnt
)) /* return data, length */
1058 res
= GETRES(rparam
);
1064 DEBUG(4,("NetShareDelete res=%d\n", res
));
1068 DEBUG(4,("NetShareDelete failed\n"));
1076 /*************************************************************************
1078 * Function Name: cli_get_pdc_name
1080 * PURPOSE: Remotes a NetServerEnum API call to the current server
1081 * requesting the name of a server matching the server
1082 * type of SV_TYPE_DOMAIN_CTRL (PDC).
1084 * Dependencies: none
1087 * cli - pointer to cli_state structure
1088 * workgroup - pointer to string containing name of domain
1089 * pdc_name - pointer to string that will contain PDC name
1090 * on successful return
1096 ************************************************************************/
1097 BOOL
cli_get_pdc_name(struct cli_state
*cli
, char *workgroup
, char *pdc_name
)
1099 char *rparam
= NULL
;
1103 char param
[WORDSIZE
/* api number */
1104 +sizeof(RAP_NetServerEnum2_REQ
) /* req string */
1105 +sizeof(RAP_SERVER_INFO_L1
) /* return string */
1106 +WORDSIZE
/* info level */
1107 +WORDSIZE
/* buffer size */
1108 +DWORDSIZE
/* server type */
1109 +RAP_MACHNAME_LEN
]; /* workgroup */
1114 /* send a SMBtrans command with api NetServerEnum */
1115 p
= make_header(param
, RAP_NetServerEnum2
,
1116 RAP_NetServerEnum2_REQ
, RAP_SERVER_INFO_L1
);
1117 PUTWORD(p
, 1); /* info level */
1118 PUTWORD(p
, CLI_BUFFER_SIZE
);
1119 PUTDWORD(p
, SV_TYPE_DOMAIN_CTRL
);
1120 PUTSTRING(p
, workgroup
, RAP_MACHNAME_LEN
);
1123 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1124 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1125 &rparam
, &rprcnt
, /* return params, return size */
1126 &rdata
, &rdrcnt
/* return data, return size */
1128 cli
->rap_error
= GETRES(rparam
);
1131 * We only really care to copy a name if the
1132 * API succeeded and we got back a name.
1134 if (cli
->rap_error
== 0) {
1135 p
= rparam
+ WORDSIZE
+ WORDSIZE
; /* skip result and converter */
1140 GETSTRING(p
, pdc_name
);
1143 DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. "
1144 "Error was : %s.\n", cli
->desthost
, cli_errstr(cli
) ));
1155 /*************************************************************************
1157 * Function Name: cli_get_server_domain
1159 * PURPOSE: Remotes a NetWkstaGetInfo API call to the current server
1160 * requesting wksta_info_10 level information to determine
1161 * the domain the server belongs to. On success, this
1162 * routine sets the server_domain field in the cli_state structure
1163 * to the server's domain name.
1165 * Dependencies: none
1168 * cli - pointer to cli_state structure
1174 * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
1176 ************************************************************************/
1177 BOOL
cli_get_server_domain(struct cli_state
*cli
)
1179 char *rparam
= NULL
;
1183 char param
[WORDSIZE
/* api number */
1184 +sizeof(RAP_WWkstaGetInfo_REQ
) /* req string */
1185 +sizeof(RAP_WKSTA_INFO_L10
) /* return string */
1186 +WORDSIZE
/* info level */
1187 +WORDSIZE
]; /* buffer size */
1190 /* send a SMBtrans command with api NetWkstaGetInfo */
1191 p
= make_header(param
, RAP_WWkstaGetInfo
,
1192 RAP_WWkstaGetInfo_REQ
, RAP_WKSTA_INFO_L10
);
1193 PUTWORD(p
, 10); /* info level */
1194 PUTWORD(p
, CLI_BUFFER_SIZE
);
1196 if (cli_api(cli
, param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1197 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1198 &rparam
, &rprcnt
, /* return params, return size */
1199 &rdata
, &rdrcnt
)) { /* return data, return size */
1200 res
= GETRES(rparam
);
1206 p
= rparam
+ WORDSIZE
;
1207 GETWORD(p
, converter
);
1209 p
= rdata
+ DWORDSIZE
+ DWORDSIZE
; /* skip computer & user names */
1210 GETSTRINGP(p
, cli
->server_domain
, rdata
, converter
);
1221 /*************************************************************************
1223 * Function Name: cli_get_server_type
1225 * PURPOSE: Remotes a NetServerGetInfo API call to the current server
1226 * requesting server_info_1 level information to retrieve
1229 * Dependencies: none
1232 * cli - pointer to cli_state structure
1233 * pstype - pointer to uint32 to contain returned server type
1239 * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
1241 ************************************************************************/
1242 BOOL
cli_get_server_type(struct cli_state
*cli
, uint32
*pstype
)
1244 char *rparam
= NULL
;
1248 char param
[WORDSIZE
/* api number */
1249 +sizeof(RAP_WserverGetInfo_REQ
) /* req string */
1250 +sizeof(RAP_SERVER_INFO_L1
) /* return string */
1251 +WORDSIZE
/* info level */
1252 +WORDSIZE
]; /* buffer size */
1255 /* send a SMBtrans command with api NetServerGetInfo */
1256 p
= make_header(param
, RAP_WserverGetInfo
,
1257 RAP_WserverGetInfo_REQ
, RAP_SERVER_INFO_L1
);
1258 PUTWORD(p
, 1); /* info level */
1259 PUTWORD(p
, CLI_BUFFER_SIZE
);
1262 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1263 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1264 &rparam
, &rprcnt
, /* return params, return size */
1265 &rdata
, &rdrcnt
/* return data, return size */
1268 res
= GETRES(rparam
);
1270 if (res
== 0 || res
== ERRmoredata
) {
1272 *pstype
= IVAL(p
,18) & ~SV_TYPE_LOCAL_LIST_ONLY
;
1279 return(res
== 0 || res
== ERRmoredata
);
1283 /*************************************************************************
1285 * Function Name: cli_ns_check_server_type
1287 * PURPOSE: Remotes a NetServerEnum2 API call to the current server
1288 * requesting server_info_0 level information of machines
1289 * matching the given server type. If the returned server
1290 * list contains the machine name contained in cli->desthost
1291 * then we conclude the server type checks out. This routine
1292 * is useful to retrieve list of server's of a certain
1293 * type when all you have is a null session connection and
1294 * can't remote API calls such as NetWkstaGetInfo or
1297 * Dependencies: none
1300 * cli - pointer to cli_state structure
1301 * workgroup - pointer to string containing domain
1302 * stype - server type
1308 ************************************************************************/
1309 BOOL
cli_ns_check_server_type(struct cli_state
*cli
, char *workgroup
, uint32 stype
)
1311 char *rparam
= NULL
;
1315 char param
[WORDSIZE
/* api number */
1316 +sizeof(RAP_NetServerEnum2_REQ
) /* req string */
1317 +sizeof(RAP_SERVER_INFO_L0
) /* return string */
1318 +WORDSIZE
/* info level */
1319 +WORDSIZE
/* buffer size */
1320 +DWORDSIZE
/* server type */
1321 +RAP_MACHNAME_LEN
]; /* workgroup */
1322 BOOL found_server
= False
;
1325 /* send a SMBtrans command with api NetServerEnum */
1326 p
= make_header(param
, RAP_NetServerEnum2
,
1327 RAP_NetServerEnum2_REQ
, RAP_SERVER_INFO_L0
);
1328 PUTWORD(p
, 0); /* info level 0 */
1329 PUTWORD(p
, CLI_BUFFER_SIZE
);
1331 PUTSTRING(p
, workgroup
, RAP_MACHNAME_LEN
);
1334 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1335 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1336 &rparam
, &rprcnt
, /* return params, return size */
1337 &rdata
, &rdrcnt
/* return data, return size */
1340 res
= GETRES(rparam
);
1341 cli
->rap_error
= res
;
1343 if (res
== 0 || res
== ERRmoredata
) {
1344 int i
, converter
, count
;
1346 p
= rparam
+ WORDSIZE
;
1347 GETWORD(p
, converter
);
1351 for (i
= 0;i
< count
;i
++, p
+= 16) {
1352 char ret_server
[RAP_MACHNAME_LEN
];
1354 GETSTRINGF(p
, ret_server
, RAP_MACHNAME_LEN
);
1355 if (strequal(ret_server
, cli
->desthost
)) {
1356 found_server
= True
;
1362 DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. "
1363 "Error was : %s.\n", cli
->desthost
, cli_errstr(cli
) ));
1370 return found_server
;
1374 /****************************************************************************
1375 perform a NetWkstaUserLogoff
1376 ****************************************************************************/
1377 BOOL
cli_NetWkstaUserLogoff(struct cli_state
*cli
,char *user
, char *workstation
)
1379 char *rparam
= NULL
;
1383 char param
[WORDSIZE
/* api number */
1384 +sizeof(RAP_NetWkstaUserLogoff_REQ
) /* req string */
1385 +sizeof(RAP_USER_LOGOFF_INFO_L1
) /* return string */
1386 +RAP_USERNAME_LEN
+1 /* user name+pad */
1387 +RAP_MACHNAME_LEN
/* wksta name */
1388 +WORDSIZE
/* buffer size */
1389 +WORDSIZE
]; /* buffer size? */
1392 memset(param
, 0, sizeof(param
));
1394 /* send a SMBtrans command with api NetWkstaUserLogoff */
1395 p
= make_header(param
, RAP_WWkstaUserLogoff
,
1396 RAP_NetWkstaUserLogoff_REQ
, RAP_USER_LOGOFF_INFO_L1
);
1397 PUTDWORD(p
, 0); /* Null pointer */
1398 PUTDWORD(p
, 0); /* Null pointer */
1399 fstrcpy(upperbuf
, user
);
1401 PUTSTRINGF(p
, upperbuf
, RAP_USERNAME_LEN
);
1402 p
++; /* strange format, but ok */
1403 fstrcpy(upperbuf
, workstation
);
1405 PUTSTRINGF(p
, upperbuf
, RAP_MACHNAME_LEN
);
1406 PUTWORD(p
, CLI_BUFFER_SIZE
);
1407 PUTWORD(p
, CLI_BUFFER_SIZE
);
1410 param
, PTR_DIFF(p
,param
),1024, /* param, length, max */
1411 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1412 &rparam
, &rprcnt
, /* return params, return size */
1413 &rdata
, &rdrcnt
/* return data, return size */
1415 cli
->rap_error
= GETRES(rparam
);
1417 if (cli
->rap_error
!= 0) {
1418 DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli
->rap_error
));
1424 return (cli
->rap_error
== 0);
1427 int cli_NetPrintQEnum(struct cli_state
*cli
,
1428 void (*qfn
)(const char*,uint16
,uint16
,uint16
,const char*,const char*,const char*,const char*,const char*,uint16
,uint16
),
1429 void (*jfn
)(uint16
,const char*,const char*,const char*,const char*,uint16
,uint16
,const char*,uint
,uint
,const char*))
1431 char param
[WORDSIZE
/* api number */
1432 +sizeof(RAP_NetPrintQEnum_REQ
) /* req string */
1433 +sizeof(RAP_PRINTQ_INFO_L2
) /* return string */
1434 +WORDSIZE
/* info level */
1435 +WORDSIZE
/* buffer size */
1436 +sizeof(RAP_SMB_PRINT_JOB_L1
)]; /* more ret data */
1438 char *rparam
= NULL
;
1444 memset(param
, '\0',sizeof(param
));
1445 p
= make_header(param
, RAP_WPrintQEnum
,
1446 RAP_NetPrintQEnum_REQ
, RAP_PRINTQ_INFO_L2
);
1447 PUTWORD(p
,2); /* Info level 2 */
1448 PUTWORD(p
,0xFFE0); /* Return buffer size */
1449 PUTSTRING(p
, RAP_SMB_PRINT_JOB_L1
, 0);
1452 param
, PTR_DIFF(p
,param
),1024,
1453 NULL
, 0, CLI_BUFFER_SIZE
,
1456 res
= GETRES(rparam
);
1457 cli
->rap_error
= res
;
1459 DEBUG(1,("NetPrintQEnum gave error %d\n", res
));
1464 if (res
== 0 || res
== ERRmoredata
) {
1465 int i
, converter
, count
;
1467 p
= rparam
+ WORDSIZE
;
1468 GETWORD(p
, converter
);
1472 for (i
=0;i
<count
;i
++) {
1473 pstring qname
, sep_file
, print_proc
, dest
, parms
, comment
;
1474 uint16 jobcount
, priority
, start_time
, until_time
, status
;
1476 GETSTRINGF(p
, qname
, RAP_SHARENAME_LEN
);
1478 GETWORD(p
, priority
);
1479 GETWORD(p
, start_time
);
1480 GETWORD(p
, until_time
);
1481 GETSTRINGP(p
, sep_file
, rdata
, converter
);
1482 GETSTRINGP(p
, print_proc
, rdata
, converter
);
1483 GETSTRINGP(p
, dest
, rdata
, converter
);
1484 GETSTRINGP(p
, parms
, rdata
, converter
);
1485 GETSTRINGP(p
, parms
, comment
, converter
);
1487 GETWORD(p
, jobcount
);
1489 qfn(qname
, priority
, start_time
, until_time
, sep_file
, print_proc
,
1490 dest
, parms
, comment
, status
, jobcount
);
1494 for (j
=0;j
<jobcount
;j
++) {
1495 uint16 jid
, pos
, fsstatus
;
1496 pstring ownername
, notifyname
, datatype
, jparms
, jstatus
, jcomment
;
1497 uint submitted
, jsize
;
1500 GETSTRINGF(p
, ownername
, RAP_USERNAME_LEN
);
1502 GETSTRINGF(p
, notifyname
, RAP_MACHNAME_LEN
);
1503 GETSTRINGF(p
, datatype
, RAP_DATATYPE_LEN
);
1504 GETSTRINGP(p
, jparms
, rdata
, converter
);
1506 GETWORD(p
, fsstatus
);
1507 GETSTRINGP(p
, jstatus
, rdata
, converter
);
1508 GETDWORD(p
, submitted
);
1510 GETSTRINGP(p
, jcomment
, rdata
, converter
);
1512 jfn(jid
, ownername
, notifyname
, datatype
, jparms
, pos
, fsstatus
,
1513 jstatus
, submitted
, jsize
, jcomment
);
1518 DEBUG(4,("NetPrintQEnum res=%d\n", res
));
1521 DEBUG(4,("NetPrintQEnum no data returned\n"));
1530 int cli_NetPrintQGetInfo(struct cli_state
*cli
, const char *printer
,
1531 void (*qfn
)(const char*,uint16
,uint16
,uint16
,const char*,const char*,const char*,const char*,const char*,uint16
,uint16
),
1532 void (*jfn
)(uint16
,const char*,const char*,const char*,const char*,uint16
,uint16
,const char*,uint
,uint
,const char*))
1534 char param
[WORDSIZE
/* api number */
1535 +sizeof(RAP_NetPrintQGetInfo_REQ
) /* req string */
1536 +sizeof(RAP_PRINTQ_INFO_L2
) /* return string */
1537 +RAP_SHARENAME_LEN
/* printer name */
1538 +WORDSIZE
/* info level */
1539 +WORDSIZE
/* buffer size */
1540 +sizeof(RAP_SMB_PRINT_JOB_L1
)]; /* more ret data */
1542 char *rparam
= NULL
;
1548 memset(param
, '\0',sizeof(param
));
1549 p
= make_header(param
, RAP_WPrintQGetInfo
,
1550 RAP_NetPrintQGetInfo_REQ
, RAP_PRINTQ_INFO_L2
);
1551 PUTSTRING(p
, printer
, RAP_SHARENAME_LEN
-1);
1552 PUTWORD(p
, 2); /* Info level 2 */
1553 PUTWORD(p
,0xFFE0); /* Return buffer size */
1554 PUTSTRING(p
, RAP_SMB_PRINT_JOB_L1
, 0);
1557 param
, PTR_DIFF(p
,param
),1024,
1558 NULL
, 0, CLI_BUFFER_SIZE
,
1561 res
= GETRES(rparam
);
1562 cli
->rap_error
= res
;
1564 DEBUG(1,("NetPrintQGetInfo gave error %d\n", res
));
1569 if (res
== 0 || res
== ERRmoredata
) {
1570 int rsize
, converter
;
1571 pstring qname
, sep_file
, print_proc
, dest
, parms
, comment
;
1572 uint16 jobcount
, priority
, start_time
, until_time
, status
;
1574 p
= rparam
+ WORDSIZE
;
1575 GETWORD(p
, converter
);
1579 GETSTRINGF(p
, qname
, RAP_SHARENAME_LEN
);
1581 GETWORD(p
, priority
);
1582 GETWORD(p
, start_time
);
1583 GETWORD(p
, until_time
);
1584 GETSTRINGP(p
, sep_file
, rdata
, converter
);
1585 GETSTRINGP(p
, print_proc
, rdata
, converter
);
1586 GETSTRINGP(p
, dest
, rdata
, converter
);
1587 GETSTRINGP(p
, parms
, rdata
, converter
);
1588 GETSTRINGP(p
, comment
, rdata
, converter
);
1590 GETWORD(p
, jobcount
);
1591 qfn(qname
, priority
, start_time
, until_time
, sep_file
, print_proc
,
1592 dest
, parms
, comment
, status
, jobcount
);
1595 for (j
=0;(j
<jobcount
)&&(PTR_DIFF(p
,rdata
)< rsize
);j
++) {
1596 uint16 jid
, pos
, fsstatus
;
1597 pstring ownername
, notifyname
, datatype
, jparms
, jstatus
, jcomment
;
1598 uint submitted
, jsize
;
1601 GETSTRINGF(p
, ownername
, RAP_USERNAME_LEN
);
1603 GETSTRINGF(p
, notifyname
, RAP_MACHNAME_LEN
);
1604 GETSTRINGF(p
, datatype
, RAP_DATATYPE_LEN
);
1605 GETSTRINGP(p
, jparms
, rdata
, converter
);
1607 GETWORD(p
, fsstatus
);
1608 GETSTRINGP(p
, jstatus
, rdata
, converter
);
1609 GETDWORD(p
, submitted
);
1611 GETSTRINGP(p
, jcomment
, rdata
, converter
);
1613 jfn(jid
, ownername
, notifyname
, datatype
, jparms
, pos
, fsstatus
,
1614 jstatus
, submitted
, jsize
, jcomment
);
1618 DEBUG(4,("NetPrintQGetInfo res=%d\n", res
));
1621 DEBUG(4,("NetPrintQGetInfo no data returned\n"));
1630 /****************************************************************************
1631 call a NetServiceEnum - list running services on a different host
1632 ****************************************************************************/
1633 int cli_RNetServiceEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, void *), void *state
)
1635 char param
[WORDSIZE
/* api number */
1636 +sizeof(RAP_NetServiceEnum_REQ
) /* parm string */
1637 +sizeof(RAP_SERVICE_INFO_L2
) /* return string */
1638 +WORDSIZE
/* info level */
1639 +WORDSIZE
]; /* buffer size */
1641 char *rparam
= NULL
;
1647 memset(param
, '\0', sizeof(param
));
1648 p
= make_header(param
, RAP_WServiceEnum
,
1649 RAP_NetServiceEnum_REQ
, RAP_SERVICE_INFO_L2
);
1650 PUTWORD(p
,2); /* Info level 2 */
1651 PUTWORD(p
,0xFFE0); /* Return buffer size */
1654 param
, PTR_DIFF(p
,param
),8,
1655 NULL
, 0, 0xFFE0 /* data area size */,
1658 res
= GETRES(rparam
);
1659 cli
->rap_error
= res
;
1660 if(cli
->rap_error
== 234)
1661 DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n"));
1662 else if (cli
->rap_error
!= 0) {
1663 DEBUG(1,("NetServiceEnum gave error %d\n", cli
->rap_error
));
1668 if (res
== 0 || res
== ERRmoredata
) {
1669 int i
, converter
, count
;
1671 p
= rparam
+ WORDSIZE
; /* skip result */
1672 GETWORD(p
, converter
);
1675 for (i
=0,p
=rdata
;i
<count
;i
++) {
1677 char servicename
[RAP_SRVCNAME_LEN
];
1679 GETSTRINGF(p
, servicename
, RAP_SRVCNAME_LEN
);
1680 p
+=8; /* pass status words */
1681 GETSTRINGF(p
, comment
, RAP_SRVCCMNT_LEN
);
1683 fn(servicename
, comment
, cli
); /* BB add status too */
1686 DEBUG(4,("NetServiceEnum res=%d\n", res
));
1689 DEBUG(4,("NetServiceEnum no data returned\n"));
1699 /****************************************************************************
1700 call a NetSessionEnum - list workstations with sessions to an SMB server
1701 ****************************************************************************/
1702 int cli_NetSessionEnum(struct cli_state
*cli
, void (*fn
)(char *, char *, uint16
, uint16
, uint16
, uint
, uint
, uint
, char *))
1704 char param
[WORDSIZE
/* api number */
1705 +sizeof(RAP_NetSessionEnum_REQ
) /* parm string */
1706 +sizeof(RAP_SESSION_INFO_L2
) /* return string */
1707 +WORDSIZE
/* info level */
1708 +WORDSIZE
]; /* buffer size */
1710 char *rparam
= NULL
;
1715 memset(param
, '\0', sizeof(param
));
1716 p
= make_header(param
, RAP_WsessionEnum
,
1717 RAP_NetSessionEnum_REQ
, RAP_SESSION_INFO_L2
);
1718 PUTWORD(p
,2); /* Info level 2 */
1719 PUTWORD(p
,0xFF); /* Return buffer size */
1722 param
, PTR_DIFF(p
,param
),8,
1723 NULL
, 0, CLI_BUFFER_SIZE
,
1726 res
= GETRES(rparam
);
1727 cli
->rap_error
= res
;
1729 DEBUG(1,("NetSessionEnum gave error %d\n", res
));
1734 if (res
== 0 || res
== ERRmoredata
) {
1735 int i
, converter
, count
;
1737 p
= rparam
+ WORDSIZE
;
1738 GETWORD(p
, converter
);
1741 for (i
=0,p
=rdata
;i
<count
;i
++) {
1742 pstring wsname
, username
, clitype_name
;
1743 uint16 num_conns
, num_opens
, num_users
;
1744 uint sess_time
, idle_time
, user_flags
;
1746 GETSTRINGP(p
, wsname
, rdata
, converter
);
1747 GETSTRINGP(p
, username
, rdata
, converter
);
1748 GETWORD(p
, num_conns
);
1749 GETWORD(p
, num_opens
);
1750 GETWORD(p
, num_users
);
1751 GETDWORD(p
, sess_time
);
1752 GETDWORD(p
, idle_time
);
1753 GETDWORD(p
, user_flags
);
1754 GETSTRINGP(p
, clitype_name
, rdata
, converter
);
1756 fn(wsname
, username
, num_conns
, num_opens
, num_users
, sess_time
,
1757 idle_time
, user_flags
, clitype_name
);
1761 DEBUG(4,("NetSessionEnum res=%d\n", res
));
1764 DEBUG(4,("NetSesssionEnum no data returned\n"));
1773 /****************************************************************************
1774 Call a NetSessionGetInfo - get information about other session to an SMB server.
1775 ****************************************************************************/
1777 int cli_NetSessionGetInfo(struct cli_state
*cli
, const char *workstation
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint16
, uint
, uint
, uint
, const char *))
1779 char param
[WORDSIZE
/* api number */
1780 +sizeof(RAP_NetSessionGetInfo_REQ
) /* req string */
1781 +sizeof(RAP_SESSION_INFO_L2
) /* return string */
1782 +RAP_MACHNAME_LEN
/* wksta name */
1783 +WORDSIZE
/* info level */
1784 +WORDSIZE
]; /* buffer size */
1786 char *rparam
= NULL
;
1792 memset(param
, '\0', sizeof(param
));
1793 p
= make_header(param
, RAP_WsessionGetInfo
,
1794 RAP_NetSessionGetInfo_REQ
, RAP_SESSION_INFO_L2
);
1795 PUTSTRING(p
, workstation
, RAP_MACHNAME_LEN
-1);
1796 PUTWORD(p
,2); /* Info level 2 */
1797 PUTWORD(p
,0xFF); /* Return buffer size */
1800 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
1801 NULL
, 0, CLI_BUFFER_SIZE
,
1804 cli
->rap_error
= SVAL(rparam
,0);
1805 if (cli
->rap_error
!= 0) {
1806 DEBUG(1,("NetSessionGetInfo gave error %d\n", cli
->rap_error
));
1811 res
= GETRES(rparam
);
1813 if (res
== 0 || res
== ERRmoredata
) {
1814 int rsize
, converter
;
1815 pstring wsname
, username
, clitype_name
;
1816 uint16 num_conns
, num_opens
, num_users
;
1817 uint sess_time
, idle_time
, user_flags
;
1819 p
= rparam
+ WORDSIZE
;
1820 GETWORD(p
, converter
);
1824 GETSTRINGP(p
, wsname
, rdata
, converter
);
1825 GETSTRINGP(p
, username
, rdata
, converter
);
1826 GETWORD(p
, num_conns
);
1827 GETWORD(p
, num_opens
);
1828 GETWORD(p
, num_users
);
1829 GETDWORD(p
, sess_time
);
1830 GETDWORD(p
, idle_time
);
1831 GETDWORD(p
, user_flags
);
1832 GETSTRINGP(p
, clitype_name
, rdata
, converter
);
1834 fn(wsname
, username
, num_conns
, num_opens
, num_users
, sess_time
,
1835 idle_time
, user_flags
, clitype_name
);
1837 DEBUG(4,("NetSessionGetInfo res=%d\n", res
));
1840 DEBUG(4,("NetSessionGetInfo no data returned\n"));
1849 /****************************************************************************
1850 call a NetSessionDel - close a session to an SMB server
1851 ****************************************************************************/
1852 int cli_NetSessionDel(struct cli_state
*cli
, const char *workstation
)
1854 char param
[WORDSIZE
/* api number */
1855 +sizeof(RAP_NetSessionDel_REQ
) /* req string */
1856 +1 /* no return string */
1857 +RAP_MACHNAME_LEN
/* workstation name */
1858 +WORDSIZE
]; /* reserved (0) */
1860 char *rparam
= NULL
;
1865 memset(param
, '\0', sizeof(param
));
1866 p
= make_header(param
, RAP_WsessionDel
, RAP_NetSessionDel_REQ
, NULL
);
1867 PUTSTRING(p
, workstation
, RAP_MACHNAME_LEN
-1);
1868 PUTWORD(p
,0); /* reserved word of 0 */
1870 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
1871 NULL
, 0, 200, /* data, length, maxlen */
1872 &rparam
, &rprcnt
, /* return params, length */
1873 &rdata
, &rdrcnt
)) /* return data, length */
1875 res
= GETRES(rparam
);
1876 cli
->rap_error
= res
;
1882 DEBUG(4,("NetFileClose2 res=%d\n", res
));
1886 DEBUG(4,("NetFileClose2 failed\n"));
1896 int cli_NetConnectionEnum(struct cli_state
*cli
, const char *qualifier
, void (*fn
)(uint16 conid
, uint16 contype
, uint16 numopens
, uint16 numusers
, uint32 contime
, const char *username
, const char *netname
))
1898 char param
[WORDSIZE
/* api number */
1899 +sizeof(RAP_NetConnectionEnum_REQ
) /* req string */
1900 +sizeof(RAP_CONNECTION_INFO_L1
) /* return string */
1901 +RAP_MACHNAME_LEN
/* wksta name */
1902 +WORDSIZE
/* info level */
1903 +WORDSIZE
]; /* buffer size */
1905 char *rparam
= NULL
;
1910 memset(param
, '\0', sizeof(param
));
1911 p
= make_header(param
, RAP_WconnectionEnum
,
1912 RAP_NetConnectionEnum_REQ
, RAP_CONNECTION_INFO_L1
);
1913 PUTSTRING(p
, qualifier
, RAP_MACHNAME_LEN
-1);/* Workstation name */
1914 PUTWORD(p
,1); /* Info level 1 */
1915 PUTWORD(p
,0xFFE0); /* Return buffer size */
1918 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
1919 NULL
, 0, CLI_BUFFER_SIZE
,
1922 res
= GETRES(rparam
);
1923 cli
->rap_error
= res
;
1925 DEBUG(1,("NetConnectionEnum gave error %d\n", res
));
1929 if (res
== 0 || res
== ERRmoredata
) {
1930 int i
, converter
, count
;
1932 p
= rparam
+ WORDSIZE
;
1933 GETWORD(p
, converter
);
1936 for (i
=0,p
=rdata
;i
<count
;i
++) {
1937 pstring netname
, username
;
1938 uint16 conn_id
, conn_type
, num_opens
, num_users
;
1942 GETWORD(p
,conn_type
);
1943 GETWORD(p
,num_opens
);
1944 GETWORD(p
,num_users
);
1945 GETDWORD(p
,conn_time
);
1946 GETSTRINGP(p
, username
, rdata
, converter
);
1947 GETSTRINGP(p
, netname
, rdata
, converter
);
1949 fn(conn_id
, conn_type
, num_opens
, num_users
, conn_time
,
1954 DEBUG(4,("NetConnectionEnum res=%d\n", res
));
1957 DEBUG(4,("NetConnectionEnum no data returned\n"));