2 Samba Unix/Linux SMB client library
3 More client RAP (SMB Remote Procedure Calls) functions
4 Copyright (C) 2001 Steve French (sfrench@us.ibm.com)
5 Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /*****************************************************/
25 /* Additional RAP functionality */
27 /* RAP is the original SMB RPC, documented */
28 /* by Microsoft and X/Open in the 1990s and */
29 /* supported by most SMB/CIFS servers although */
30 /* it is unlikely that any one implementation */
31 /* supports all RAP command codes since some */
32 /* are quite obsolete and a few are specific */
33 /* to a particular network operating system */
35 /* Although it has largely been replaced */
36 /* for complex remote admistration and management */
37 /* (of servers) by the relatively newer */
38 /* DCE/RPC based remote API (which better handles */
39 /* large >64K data structures), there are many */
40 /* important administrative and resource location */
41 /* tasks and user tasks (e.g. password change) */
42 /* that are performed via RAP. */
44 /* Although a few of the RAP calls are implemented */
45 /* in the Samba client library already (clirap.c) */
46 /* the new ones are in clirap2.c for easy patching */
47 /* and integration and a corresponding header */
48 /* file, rap.h, has been created. */
50 /* This is based on data from the CIFS spec */
51 /* and the LAN Server and LAN Manager */
52 /* Programming Reference books and published */
53 /* RAP document and CIFS forum postings and */
54 /* lots of trial and error */
56 /* Function names changed from API_ (as they are */
57 /* in the CIFS specification) to RAP_ in order */
58 /* to avoid confusion with other API calls */
59 /* sent via DCE RPC */
61 /*****************************************************/
63 /*****************************************************/
65 /* cifsrap.c already includes support for: */
67 /* WshareEnum ( API number 0, level 1) */
68 /* NetServerEnum2 (API num 104, level 1) */
69 /* WWkstaUserLogon (132) */
70 /* SamOEMchgPasswordUser2_P (214) */
72 /* cifsprint.c already includes support for: */
74 /* WPrintJobEnum (API num 76, level 2) */
75 /* WPrintJobDel (API num 81) */
77 /*****************************************************/
86 #define PUTBYTE(p,b) do {SCVAL(p,0,b); p++;} while(0)
87 #define GETBYTE(p,b) do {b = CVAL(p,0); p++;} while(0)
88 #define PUTWORD(p,w) do {SSVAL(p,0,w); p += WORDSIZE;} while(0)
89 #define GETWORD(p,w) do {w = SVAL(p,0); p += WORDSIZE;} while(0)
90 #define PUTDWORD(p,d) do {SIVAL(p,0,d); p += DWORDSIZE;} while(0)
91 #define GETDWORD(p,d) do {d = IVAL(p,0); p += DWORDSIZE;} while(0)
92 #define GETRES(p) p ? SVAL(p,0) : -1
93 /* put string s at p with max len n and increment p past string */
94 #define PUTSTRING(p,s,n) do {\
95 push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\
96 p = skip_string(p,1);\
98 /* put string s and p, using fixed len l, and increment p by l */
99 #define PUTSTRINGF(p,s,l) do {\
100 push_ascii(p,s?s:"",l,STR_TERMINATE);\
103 /* put string pointer at p, supplying offset o from rdata r, store */
104 /* dword offset at p, increment p by 4 and o by length of s. This */
105 /* means on the first call, you must calc the offset yourself! */
106 #define PUTSTRINGP(p,s,r,o) do {\
108 push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\
111 } else PUTDWORD(p,0);\
113 /* get asciiz string s from p, increment p past string */
114 #define GETSTRING(p,s) do {\
115 pull_ascii_pstring(s,p);\
116 p = skip_string(p,1);\
118 /* get fixed length l string s from p, increment p by l */
119 #define GETSTRINGF(p,s,l) do {\
120 pull_ascii_pstring(s,p);\
123 /* get string s from offset (obtained at p) from rdata r - converter c */
124 #define GETSTRINGP(p,s,r,c) do {\
127 off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */ \
128 pull_ascii_pstring(s, off?(r+off-c):"");\
131 static char *make_header(char *param
, uint16 apinum
, char *reqfmt
, char *datafmt
)
133 PUTWORD(param
,apinum
);
135 PUTSTRING(param
,reqfmt
,0);
140 PUTSTRING(param
,datafmt
,0);
148 /****************************************************************************
149 call a NetGroupDelete - delete user group from remote server
150 ****************************************************************************/
151 int cli_NetGroupDelete(struct cli_state
*cli
, const char *group_name
)
156 int rdrcnt
,rprcnt
, res
;
157 char param
[WORDSIZE
/* api number */
158 +sizeof(RAP_NetGroupDel_REQ
) /* parm string */
159 +1 /* no ret string */
160 +RAP_GROUPNAME_LEN
/* group to del */
161 +WORDSIZE
]; /* reserved word */
163 /* now send a SMBtrans command with api GroupDel */
164 p
= make_header(param
, RAP_WGroupDel
, RAP_NetGroupDel_REQ
, NULL
);
165 PUTSTRING(p
, group_name
, RAP_GROUPNAME_LEN
);
166 PUTWORD(p
,0); /* reserved word MBZ on input */
169 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
170 NULL
, 0, 200, /* data, length, maxlen */
171 &rparam
, &rprcnt
, /* return params, length */
172 &rdata
, &rdrcnt
)) /* return data, length */
174 res
= GETRES(rparam
);
179 else if ((res
== 5) || (res
== 65)) {
180 DEBUG(1, ("Access Denied\n"));
182 else if (res
== 2220) {
183 DEBUG (1, ("Group does not exist\n"));
186 DEBUG(4,("NetGroupDelete res=%d\n", res
));
190 DEBUG(4,("NetGroupDelete failed\n"));
199 /****************************************************************************
200 call a NetGroupAdd - add user group to remote server
201 ****************************************************************************/
202 int cli_NetGroupAdd(struct cli_state
*cli
, RAP_GROUP_INFO_1
* grinfo
)
207 int rdrcnt
,rprcnt
,res
;
208 char param
[WORDSIZE
/* api number */
209 +sizeof(RAP_NetGroupAdd_REQ
) /* req string */
210 +sizeof(RAP_GROUP_INFO_L1
) /* return string */
211 +WORDSIZE
/* info level */
212 +WORDSIZE
]; /* reserved word */
216 /* offset into data of free format strings. Will be updated */
217 /* by PUTSTRINGP macro and end up with total data length. */
218 int soffset
= RAP_GROUPNAME_LEN
+ 1 + DWORDSIZE
;
220 /* now send a SMBtrans command with api WGroupAdd */
222 p
= make_header(param
, RAP_WGroupAdd
,
223 RAP_NetGroupAdd_REQ
, RAP_GROUP_INFO_L1
);
224 PUTWORD(p
, 1); /* info level */
225 PUTWORD(p
, 0); /* reserved word 0 */
228 PUTSTRINGF(p
, grinfo
->group_name
, RAP_GROUPNAME_LEN
);
229 PUTBYTE(p
, 0); /* pad byte 0 */
230 PUTSTRINGP(p
, grinfo
->comment
, data
, soffset
);
233 param
, sizeof(param
), 1024, /* Param, length, maxlen */
234 data
, soffset
, sizeof(data
), /* data, length, maxlen */
235 &rparam
, &rprcnt
, /* return params, length */
236 &rdata
, &rdrcnt
)) /* return data, length */
238 res
= GETRES(rparam
);
242 } else if ((res
== 5) || (res
== 65)) {
243 DEBUG(1, ("Access Denied\n"));
245 else if (res
== 2223) {
246 DEBUG (1, ("Group already exists\n"));
249 DEBUG(4,("NetGroupAdd res=%d\n", res
));
253 DEBUG(4,("NetGroupAdd failed\n"));
262 /****************************************************************************
263 call a NetGroupEnum - try and list user groups on a different host
264 ****************************************************************************/
265 int cli_RNetGroupEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, void *), void *state
)
267 char param
[WORDSIZE
/* api number */
268 +sizeof(RAP_NetGroupEnum_REQ
) /* parm string */
269 +sizeof(RAP_GROUP_INFO_L1
) /* return string */
270 +WORDSIZE
/* info level */
271 +WORDSIZE
]; /* buffer size */
279 memset(param
, '\0', sizeof(param
));
280 p
= make_header(param
, RAP_WGroupEnum
,
281 RAP_NetGroupEnum_REQ
, RAP_GROUP_INFO_L1
);
282 PUTWORD(p
,1); /* Info level 1 */ /* add level 0 */
283 PUTWORD(p
,0xFFE0); /* Return buffer size */
286 param
, PTR_DIFF(p
,param
),8,
287 NULL
, 0, 0xFFE0 /* data area size */,
290 res
= GETRES(rparam
);
291 cli
->rap_error
= res
;
292 if(cli
->rap_error
== 234)
293 DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
294 else if (cli
->rap_error
!= 0) {
295 DEBUG(1,("NetGroupEnum gave error %d\n", cli
->rap_error
));
300 if (res
== 0 || res
== ERRmoredata
) {
301 int i
, converter
, count
;
303 p
= rparam
+ WORDSIZE
; /* skip result */
304 GETWORD(p
, converter
);
307 for (i
=0,p
=rdata
;i
<count
;i
++) {
309 char groupname
[RAP_GROUPNAME_LEN
];
311 GETSTRINGF(p
, groupname
, RAP_GROUPNAME_LEN
);
313 GETSTRINGP(p
, comment
, rdata
, converter
);
315 fn(groupname
, comment
, cli
);
318 DEBUG(4,("NetGroupEnum res=%d\n", res
));
321 DEBUG(4,("NetGroupEnum no data returned\n"));
330 int cli_NetGroupDelUser(struct cli_state
* cli
, const char *group_name
, const char *user_name
)
335 int rdrcnt
,rprcnt
,res
;
336 char param
[WORDSIZE
/* api number */
337 +sizeof(RAP_NetGroupDelUser_REQ
) /* parm string */
338 +1 /* no ret string */
339 +RAP_GROUPNAME_LEN
/* group name */
340 +RAP_USERNAME_LEN
]; /* user to del */
342 /* now send a SMBtrans command with api GroupMemberAdd */
343 p
= make_header(param
, RAP_WGroupDelUser
, RAP_NetGroupDelUser_REQ
, NULL
);
344 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
);
345 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
);
348 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
349 NULL
, 0, 200, /* data, length, maxlen */
350 &rparam
, &rprcnt
, /* return params, length */
351 &rdata
, &rdrcnt
)) /* return data, length */
353 res
= GETRES(rparam
);
360 DEBUG(1, ("Access Denied\n"));
363 DEBUG(1, ("Not supported by server\n"));
366 DEBUG(1, ("Group does not exist\n"));
369 DEBUG(1, ("User does not exist\n"));
372 DEBUG(1, ("User is not in group\n"));
375 DEBUG(4,("NetGroupDelUser res=%d\n", res
));
379 DEBUG(4,("NetGroupDelUser failed\n"));
388 int cli_NetGroupAddUser(struct cli_state
* cli
, const char *group_name
, const char *user_name
)
393 int rdrcnt
,rprcnt
,res
;
394 char param
[WORDSIZE
/* api number */
395 +sizeof(RAP_NetGroupAddUser_REQ
) /* parm string */
396 +1 /* no ret string */
397 +RAP_GROUPNAME_LEN
/* group name */
398 +RAP_USERNAME_LEN
]; /* user to add */
400 /* now send a SMBtrans command with api GroupMemberAdd */
401 p
= make_header(param
, RAP_WGroupAddUser
, RAP_NetGroupAddUser_REQ
, NULL
);
402 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
);
403 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
);
406 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
407 NULL
, 0, 200, /* data, length, maxlen */
408 &rparam
, &rprcnt
, /* return params, length */
409 &rdata
, &rdrcnt
)) /* return data, length */
411 res
= GETRES(rparam
);
418 DEBUG(1, ("Access Denied\n"));
421 DEBUG(1, ("Not supported by server\n"));
424 DEBUG(1, ("Group does not exist\n"));
427 DEBUG(1, ("User does not exist\n"));
430 DEBUG(4,("NetGroupAddUser res=%d\n", res
));
434 DEBUG(4,("NetGroupAddUser failed\n"));
444 int cli_NetGroupGetUsers(struct cli_state
* cli
, const char *group_name
, void (*fn
)(const char *, void *), void *state
)
451 char param
[WORDSIZE
/* api number */
452 +sizeof(RAP_NetGroupGetUsers_REQ
)/* parm string */
453 +sizeof(RAP_GROUP_USERS_INFO_0
) /* return string */
454 +RAP_GROUPNAME_LEN
/* group name */
455 +WORDSIZE
/* info level */
456 +WORDSIZE
]; /* buffer size */
458 /* now send a SMBtrans command with api GroupGetUsers */
459 p
= make_header(param
, RAP_WGroupGetUsers
,
460 RAP_NetGroupGetUsers_REQ
, RAP_GROUP_USERS_INFO_0
);
461 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
-1);
462 PUTWORD(p
,0); /* info level 0 */
463 PUTWORD(p
,0xFFE0); /* return buffer size */
466 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
467 NULL
, 0, CLI_BUFFER_SIZE
,
470 res
= GETRES(rparam
);
471 cli
->rap_error
= res
;
473 DEBUG(1,("NetGroupGetUsers gave error %d\n", res
));
477 if (res
== 0 || res
== ERRmoredata
) {
478 int i
, converter
, count
;
480 p
= rparam
+WORDSIZE
;
481 GETWORD(p
, converter
);
484 for (i
=0,p
=rdata
; i
<count
; i
++) {
485 GETSTRINGF(p
, username
, RAP_USERNAME_LEN
);
489 DEBUG(4,("NetGroupGetUsers res=%d\n", res
));
492 DEBUG(4,("NetGroupGetUsers no data returned\n"));
499 int cli_NetUserGetGroups(struct cli_state
* cli
, const char *user_name
, void (*fn
)(const char *, void *), void *state
)
506 char param
[WORDSIZE
/* api number */
507 +sizeof(RAP_NetUserGetGroups_REQ
)/* parm string */
508 +sizeof(RAP_GROUP_USERS_INFO_0
) /* return string */
509 +RAP_USERNAME_LEN
/* user name */
510 +WORDSIZE
/* info level */
511 +WORDSIZE
]; /* buffer size */
513 /* now send a SMBtrans command with api GroupGetUsers */
514 p
= make_header(param
, RAP_WUserGetGroups
,
515 RAP_NetUserGetGroups_REQ
, RAP_GROUP_USERS_INFO_0
);
516 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
-1);
517 PUTWORD(p
,0); /* info level 0 */
518 PUTWORD(p
,0xFFE0); /* return buffer size */
521 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
522 NULL
, 0, CLI_BUFFER_SIZE
,
525 res
= GETRES(rparam
);
526 cli
->rap_error
= res
;
528 DEBUG(1,("NetUserGetGroups gave error %d\n", res
));
532 if (res
== 0 || res
== ERRmoredata
) {
533 int i
, converter
, count
;
535 p
= rparam
+WORDSIZE
;
536 GETWORD(p
, converter
);
539 for (i
=0,p
=rdata
; i
<count
; i
++) {
540 GETSTRINGF(p
, groupname
, RAP_USERNAME_LEN
);
541 fn(groupname
, state
);
544 DEBUG(4,("NetUserGetGroups res=%d\n", res
));
547 DEBUG(4,("NetUserGetGroups no data returned\n"));
555 /****************************************************************************
556 call a NetUserDelete - delete user from remote server
557 ****************************************************************************/
558 int cli_NetUserDelete(struct cli_state
*cli
, const char * user_name
)
563 int rdrcnt
,rprcnt
, res
;
564 char param
[WORDSIZE
/* api number */
565 +sizeof(RAP_NetGroupDel_REQ
) /* parm string */
566 +1 /* no ret string */
567 +RAP_USERNAME_LEN
/* user to del */
568 +WORDSIZE
]; /* reserved word */
570 /* now send a SMBtrans command with api UserDel */
571 p
= make_header(param
, RAP_WUserDel
, RAP_NetGroupDel_REQ
, NULL
);
572 PUTSTRING(p
, user_name
, RAP_USERNAME_LEN
);
573 PUTWORD(p
,0); /* reserved word MBZ on input */
576 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
577 NULL
, 0, 200, /* data, length, maxlen */
578 &rparam
, &rprcnt
, /* return params, length */
579 &rdata
, &rdrcnt
)) /* return data, length */
581 res
= GETRES(rparam
);
586 else if ((res
== 5) || (res
== 65)) {
587 DEBUG(1, ("Access Denied\n"));
589 else if (res
== 2221) {
590 DEBUG (1, ("User does not exist\n"));
593 DEBUG(4,("NetUserDelete res=%d\n", res
));
597 DEBUG(4,("NetUserDelete failed\n"));
606 /****************************************************************************
607 call a NetUserAdd - add user to remote server
608 ****************************************************************************/
609 int cli_NetUserAdd(struct cli_state
*cli
, RAP_USER_INFO_1
* userinfo
)
617 int rdrcnt
,rprcnt
,res
;
618 char param
[WORDSIZE
/* api number */
619 +sizeof(RAP_NetUserAdd2_REQ
) /* req string */
620 +sizeof(RAP_USER_INFO_L1
) /* data string */
621 +WORDSIZE
/* info level */
622 +WORDSIZE
/* buffer length */
623 +WORDSIZE
]; /* reserved */
626 /* offset into data of free format strings. Will be updated */
627 /* by PUTSTRINGP macro and end up with total data length. */
628 int soffset
=RAP_USERNAME_LEN
+1 /* user name + pad */
629 + RAP_UPASSWD_LEN
/* password */
630 + DWORDSIZE
/* password age */
631 + WORDSIZE
/* privilege */
632 + DWORDSIZE
/* home dir ptr */
633 + DWORDSIZE
/* comment ptr */
634 + WORDSIZE
/* flags */
635 + DWORDSIZE
; /* login script ptr*/
637 /* now send a SMBtrans command with api NetUserAdd */
638 p
= make_header(param
, RAP_WUserAdd2
,
639 RAP_NetUserAdd2_REQ
, RAP_USER_INFO_L1
);
640 PUTWORD(p
, 1); /* info level */
642 PUTWORD(p
, 0); /* pwencrypt */
643 if(userinfo
->passwrd
)
644 PUTWORD(p
,MIN(strlen(userinfo
->passwrd
), RAP_UPASSWD_LEN
));
646 PUTWORD(p
, 0); /* password length */
649 memset(data
, '\0', soffset
);
651 PUTSTRINGF(p
, userinfo
->user_name
, RAP_USERNAME_LEN
);
652 PUTBYTE(p
, 0); /* pad byte 0 */
653 PUTSTRINGF(p
, userinfo
->passwrd
, RAP_UPASSWD_LEN
);
654 PUTDWORD(p
, 0); /* pw age - n.a. on user add */
655 PUTWORD(p
, userinfo
->priv
);
656 PUTSTRINGP(p
, userinfo
->home_dir
, data
, soffset
);
657 PUTSTRINGP(p
, userinfo
->comment
, data
, soffset
);
658 PUTWORD(p
, userinfo
->userflags
);
659 PUTSTRINGP(p
, userinfo
->logon_script
, data
, soffset
);
662 param
, sizeof(param
), 1024, /* Param, length, maxlen */
663 data
, soffset
, sizeof(data
), /* data, length, maxlen */
664 &rparam
, &rprcnt
, /* return params, length */
665 &rdata
, &rdrcnt
)) /* return data, length */
667 res
= GETRES(rparam
);
672 else if ((res
== 5) || (res
== 65)) {
673 DEBUG(1, ("Access Denied\n"));
675 else if (res
== 2224) {
676 DEBUG (1, ("User already exists\n"));
679 DEBUG(4,("NetUserAdd res=%d\n", res
));
683 DEBUG(4,("NetUserAdd failed\n"));
692 /****************************************************************************
693 call a NetUserEnum - try and list users on a different host
694 ****************************************************************************/
695 int cli_RNetUserEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, const char *, const char *, void *), void *state
)
697 char param
[WORDSIZE
/* api number */
698 +sizeof(RAP_NetUserEnum_REQ
) /* parm string */
699 +sizeof(RAP_USER_INFO_L1
) /* return string */
700 +WORDSIZE
/* info level */
701 +WORDSIZE
]; /* buffer size */
709 memset(param
, '\0', sizeof(param
));
710 p
= make_header(param
, RAP_WUserEnum
,
711 RAP_NetUserEnum_REQ
, RAP_USER_INFO_L1
);
712 PUTWORD(p
,1); /* Info level 1 */
713 PUTWORD(p
,0xFF00); /* Return buffer size */
715 /* BB Fix handling of large numbers of users to be returned */
717 param
, PTR_DIFF(p
,param
),8,
718 NULL
, 0, CLI_BUFFER_SIZE
,
721 res
= GETRES(rparam
);
722 cli
->rap_error
= res
;
723 if (cli
->rap_error
!= 0) {
724 DEBUG(1,("NetUserEnum gave error %d\n", cli
->rap_error
));
728 if (res
== 0 || res
== ERRmoredata
) {
729 int i
, converter
, count
;
730 char username
[RAP_USERNAME_LEN
];
731 char userpw
[RAP_UPASSWD_LEN
];
732 pstring comment
, homedir
, logonscript
;
733 int pwage
, priv
, flags
;
735 p
= rparam
+ WORDSIZE
; /* skip result */
736 GETWORD(p
, converter
);
739 for (i
=0,p
=rdata
;i
<count
;i
++) {
740 GETSTRINGF(p
, username
, RAP_USERNAME_LEN
);
742 GETSTRINGF(p
, userpw
, RAP_UPASSWD_LEN
);
743 GETDWORD(p
, pwage
); /* password age */
744 GETWORD(p
, priv
); /* 0=guest, 1=user, 2=admin */
745 GETSTRINGP(p
, homedir
, rdata
, converter
);
746 GETSTRINGP(p
, comment
, rdata
, converter
);
748 GETSTRINGP(p
, logonscript
, rdata
, converter
);
750 fn(username
, comment
, homedir
, logonscript
, cli
);
753 DEBUG(4,("NetUserEnum res=%d\n", res
));
756 DEBUG(4,("NetUserEnum no data returned\n"));
765 /****************************************************************************
766 call a NetFileClose2 - close open file on another session to server
767 ****************************************************************************/
768 int cli_NetFileClose(struct cli_state
*cli
, uint32 file_id
)
774 char param
[WORDSIZE
/* api number */
775 +sizeof(RAP_WFileClose2_REQ
) /* req string */
776 +1 /* no ret string */
777 +DWORDSIZE
]; /* file ID */
780 /* now send a SMBtrans command with api RNetShareEnum */
781 p
= make_header(param
, RAP_WFileClose2
, RAP_WFileClose2_REQ
, NULL
);
782 PUTDWORD(p
, file_id
);
785 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
786 NULL
, 0, 200, /* data, length, maxlen */
787 &rparam
, &rprcnt
, /* return params, length */
788 &rdata
, &rdrcnt
)) /* return data, length */
790 res
= GETRES(rparam
);
794 } else if (res
== 2314){
795 DEBUG(1, ("NetFileClose2 - attempt to close non-existant file open instance\n"));
797 DEBUG(4,("NetFileClose2 res=%d\n", res
));
801 DEBUG(4,("NetFileClose2 failed\n"));
810 /****************************************************************************
811 call a NetFileGetInfo - get information about server file opened from other
813 ****************************************************************************/
814 int cli_NetFileGetInfo(struct cli_state
*cli
, uint32 file_id
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint32
))
819 int rdrcnt
,rprcnt
, res
;
820 char param
[WORDSIZE
/* api number */
821 +sizeof(RAP_WFileGetInfo2_REQ
) /* req string */
822 +sizeof(RAP_FILE_INFO_L3
) /* return string */
823 +DWORDSIZE
/* file ID */
824 +WORDSIZE
/* info level */
825 +WORDSIZE
]; /* buffer size */
827 /* now send a SMBtrans command with api RNetShareEnum */
828 p
= make_header(param
, RAP_WFileGetInfo2
,
829 RAP_WFileGetInfo2_REQ
, RAP_FILE_INFO_L3
);
830 PUTDWORD(p
, file_id
);
831 PUTWORD(p
, 3); /* info level */
832 PUTWORD(p
, 0x1000); /* buffer size */
834 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
835 NULL
, 0, 0x1000, /* data, length, maxlen */
836 &rparam
, &rprcnt
, /* return params, length */
837 &rdata
, &rdrcnt
)) /* return data, length */
839 res
= GETRES(rparam
);
840 if (res
== 0 || res
== ERRmoredata
) {
841 int converter
,id
, perms
, locks
;
842 pstring fpath
, fuser
;
844 p
= rparam
+ WORDSIZE
; /* skip result */
845 GETWORD(p
, converter
);
851 GETSTRINGP(p
, fpath
, rdata
, converter
);
852 GETSTRINGP(p
, fuser
, rdata
, converter
);
854 fn(fpath
, fuser
, perms
, locks
, id
);
856 DEBUG(4,("NetFileGetInfo2 res=%d\n", res
));
860 DEBUG(4,("NetFileGetInfo2 failed\n"));
869 /****************************************************************************
870 * Call a NetFileEnum2 - list open files on an SMB server
872 * PURPOSE: Remotes a NetFileEnum API call to the current server or target
873 * server listing the files open via the network (and their
874 * corresponding open instance ids)
879 * cli - pointer to cli_state structure
880 * user - if present, return only files opened by this remote user
881 * base_path - if present, return only files opened below this
883 * fn - display function to invoke for each entry in the result
890 ****************************************************************************/
891 int cli_NetFileEnum(struct cli_state
*cli
, char * user
, char * base_path
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint32
))
897 char param
[WORDSIZE
/* api number */
898 +sizeof(RAP_WFileEnum2_REQ
) /* req string */
899 +sizeof(RAP_FILE_INFO_L3
) /* return string */
900 +256 /* base path (opt) */
901 +RAP_USERNAME_LEN
/* user name (opt) */
902 +WORDSIZE
/* info level */
903 +WORDSIZE
/* buffer size */
904 +DWORDSIZE
/* resume key ? */
905 +DWORDSIZE
]; /* resume key ? */
908 /* now send a SMBtrans command with api RNetShareEnum */
909 p
= make_header(param
, RAP_WFileEnum2
,
910 RAP_WFileEnum2_REQ
, RAP_FILE_INFO_L3
);
912 PUTSTRING(p
, base_path
, 256);
913 PUTSTRING(p
, user
, RAP_USERNAME_LEN
);
914 PUTWORD(p
, 3); /* info level */
915 PUTWORD(p
, 0xFF00); /* buffer size */
916 PUTDWORD(p
, 0); /* zero out the resume key */
917 PUTDWORD(p
, 0); /* or is this one the resume key? */
920 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
921 NULL
, 0, 0xFF00, /* data, length, maxlen */
922 &rparam
, &rprcnt
, /* return params, length */
923 &rdata
, &rdrcnt
)) /* return data, length */
925 int res
= GETRES(rparam
);
927 if (res
== 0 || res
== ERRmoredata
) {
930 p
= rparam
+ WORDSIZE
; /* skip result */
931 GETWORD(p
, converter
);
935 for (i
=0; i
<count
; i
++) {
936 int id
, perms
, locks
;
937 pstring fpath
, fuser
;
942 GETSTRINGP(p
, fpath
, rdata
, converter
);
943 GETSTRINGP(p
, fuser
, rdata
, converter
);
945 fn(fpath
, fuser
, perms
, locks
, id
);
946 } /* BB fix ERRmoredata case to send resume request */
948 DEBUG(4,("NetFileEnum2 res=%d\n", res
));
951 DEBUG(4,("NetFileEnum2 failed\n"));
960 /****************************************************************************
961 call a NetShareAdd - share/export directory on remote server
962 ****************************************************************************/
963 int cli_NetShareAdd(struct cli_state
*cli
, RAP_SHARE_INFO_2
* sinfo
)
968 int rdrcnt
,rprcnt
,res
;
969 char param
[WORDSIZE
/* api number */
970 +sizeof(RAP_WShareAdd_REQ
) /* req string */
971 +sizeof(RAP_SHARE_INFO_L2
) /* return string */
972 +WORDSIZE
/* info level */
973 +WORDSIZE
]; /* reserved word */
975 /* offset to free format string section following fixed length data. */
976 /* will be updated by PUTSTRINGP macro and will end up with total len */
977 int soffset
= RAP_SHARENAME_LEN
+ 1 /* share name + pad */
978 + WORDSIZE
/* share type */
979 + DWORDSIZE
/* comment pointer */
980 + WORDSIZE
/* permissions */
981 + WORDSIZE
/* max users */
982 + WORDSIZE
/* active users */
983 + DWORDSIZE
/* share path */
984 + RAP_SPASSWD_LEN
+ 1; /* share password + pad */
986 memset(param
,'\0',sizeof(param
));
987 /* now send a SMBtrans command with api RNetShareAdd */
988 p
= make_header(param
, RAP_WshareAdd
,
989 RAP_WShareAdd_REQ
, RAP_SHARE_INFO_L2
);
990 PUTWORD(p
, 2); /* info level */
991 PUTWORD(p
, 0); /* reserved word 0 */
994 PUTSTRINGF(p
, sinfo
->share_name
, RAP_SHARENAME_LEN
);
995 PUTBYTE(p
, 0); /* pad byte 0 */
997 PUTWORD(p
, sinfo
->share_type
);
998 PUTSTRINGP(p
, sinfo
->comment
, data
, soffset
);
999 PUTWORD(p
, sinfo
->perms
);
1000 PUTWORD(p
, sinfo
->maximum_users
);
1001 PUTWORD(p
, sinfo
->active_users
);
1002 PUTSTRINGP(p
, sinfo
->path
, data
, soffset
);
1003 PUTSTRINGF(p
, sinfo
->password
, RAP_SPASSWD_LEN
);
1004 SCVAL(p
,-1,0x0A); /* required 0x0A at end of password */
1007 param
, sizeof(param
), 1024, /* Param, length, maxlen */
1008 data
, soffset
, sizeof(data
), /* data, length, maxlen */
1009 &rparam
, &rprcnt
, /* return params, length */
1010 &rdata
, &rdrcnt
)) /* return data, length */
1012 res
= rparam
? SVAL(rparam
,0) : -1;
1018 DEBUG(4,("NetShareAdd res=%d\n", res
));
1022 DEBUG(4,("NetShareAdd failed\n"));
1030 /****************************************************************************
1031 call a NetShareDelete - unshare exported directory on remote server
1032 ****************************************************************************/
1033 int cli_NetShareDelete(struct cli_state
*cli
, const char * share_name
)
1035 char *rparam
= NULL
;
1038 int rdrcnt
,rprcnt
, res
;
1039 char param
[WORDSIZE
/* api number */
1040 +sizeof(RAP_WShareDel_REQ
) /* req string */
1041 +1 /* no ret string */
1042 +RAP_SHARENAME_LEN
/* share to del */
1043 +WORDSIZE
]; /* reserved word */
1046 /* now send a SMBtrans command with api RNetShareDelete */
1047 p
= make_header(param
, RAP_WshareDel
, RAP_WShareDel_REQ
, NULL
);
1048 PUTSTRING(p
,share_name
,RAP_SHARENAME_LEN
);
1049 PUTWORD(p
,0); /* reserved word MBZ on input */
1052 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
1053 NULL
, 0, 200, /* data, length, maxlen */
1054 &rparam
, &rprcnt
, /* return params, length */
1055 &rdata
, &rdrcnt
)) /* return data, length */
1057 res
= GETRES(rparam
);
1063 DEBUG(4,("NetShareDelete res=%d\n", res
));
1067 DEBUG(4,("NetShareDelete failed\n"));
1075 /*************************************************************************
1077 * Function Name: cli_get_pdc_name
1079 * PURPOSE: Remotes a NetServerEnum API call to the current server
1080 * requesting the name of a server matching the server
1081 * type of SV_TYPE_DOMAIN_CTRL (PDC).
1083 * Dependencies: none
1086 * cli - pointer to cli_state structure
1087 * workgroup - pointer to string containing name of domain
1088 * pdc_name - pointer to string that will contain PDC name
1089 * on successful return
1095 ************************************************************************/
1096 BOOL
cli_get_pdc_name(struct cli_state
*cli
, char *workgroup
, char *pdc_name
)
1098 char *rparam
= NULL
;
1102 char param
[WORDSIZE
/* api number */
1103 +sizeof(RAP_NetServerEnum2_REQ
) /* req string */
1104 +sizeof(RAP_SERVER_INFO_L1
) /* return string */
1105 +WORDSIZE
/* info level */
1106 +WORDSIZE
/* buffer size */
1107 +DWORDSIZE
/* server type */
1108 +RAP_MACHNAME_LEN
]; /* workgroup */
1113 /* send a SMBtrans command with api NetServerEnum */
1114 p
= make_header(param
, RAP_NetServerEnum2
,
1115 RAP_NetServerEnum2_REQ
, RAP_SERVER_INFO_L1
);
1116 PUTWORD(p
, 1); /* info level */
1117 PUTWORD(p
, CLI_BUFFER_SIZE
);
1118 PUTDWORD(p
, SV_TYPE_DOMAIN_CTRL
);
1119 PUTSTRING(p
, workgroup
, RAP_MACHNAME_LEN
);
1122 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1123 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1124 &rparam
, &rprcnt
, /* return params, return size */
1125 &rdata
, &rdrcnt
/* return data, return size */
1127 cli
->rap_error
= GETRES(rparam
);
1130 * We only really care to copy a name if the
1131 * API succeeded and we got back a name.
1133 if (cli
->rap_error
== 0) {
1134 p
= rparam
+ WORDSIZE
+ WORDSIZE
; /* skip result and converter */
1139 GETSTRING(p
, pdc_name
);
1142 DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. "
1143 "Error was : %s.\n", cli
->desthost
, cli_errstr(cli
) ));
1154 /*************************************************************************
1156 * Function Name: cli_get_server_domain
1158 * PURPOSE: Remotes a NetWkstaGetInfo API call to the current server
1159 * requesting wksta_info_10 level information to determine
1160 * the domain the server belongs to. On success, this
1161 * routine sets the server_domain field in the cli_state structure
1162 * to the server's domain name.
1164 * Dependencies: none
1167 * cli - pointer to cli_state structure
1173 * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
1175 ************************************************************************/
1176 BOOL
cli_get_server_domain(struct cli_state
*cli
)
1178 char *rparam
= NULL
;
1182 char param
[WORDSIZE
/* api number */
1183 +sizeof(RAP_WWkstaGetInfo_REQ
) /* req string */
1184 +sizeof(RAP_WKSTA_INFO_L10
) /* return string */
1185 +WORDSIZE
/* info level */
1186 +WORDSIZE
]; /* buffer size */
1189 /* send a SMBtrans command with api NetWkstaGetInfo */
1190 p
= make_header(param
, RAP_WWkstaGetInfo
,
1191 RAP_WWkstaGetInfo_REQ
, RAP_WKSTA_INFO_L10
);
1192 PUTWORD(p
, 10); /* info level */
1193 PUTWORD(p
, CLI_BUFFER_SIZE
);
1195 if (cli_api(cli
, param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1196 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1197 &rparam
, &rprcnt
, /* return params, return size */
1198 &rdata
, &rdrcnt
)) { /* return data, return size */
1199 res
= GETRES(rparam
);
1205 p
= rparam
+ WORDSIZE
;
1206 GETWORD(p
, converter
);
1208 p
= rdata
+ DWORDSIZE
+ DWORDSIZE
; /* skip computer & user names */
1209 GETSTRINGP(p
, cli
->server_domain
, rdata
, converter
);
1220 /*************************************************************************
1222 * Function Name: cli_get_server_type
1224 * PURPOSE: Remotes a NetServerGetInfo API call to the current server
1225 * requesting server_info_1 level information to retrieve
1228 * Dependencies: none
1231 * cli - pointer to cli_state structure
1232 * pstype - pointer to uint32 to contain returned server type
1238 * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
1240 ************************************************************************/
1241 BOOL
cli_get_server_type(struct cli_state
*cli
, uint32
*pstype
)
1243 char *rparam
= NULL
;
1247 char param
[WORDSIZE
/* api number */
1248 +sizeof(RAP_WserverGetInfo_REQ
) /* req string */
1249 +sizeof(RAP_SERVER_INFO_L1
) /* return string */
1250 +WORDSIZE
/* info level */
1251 +WORDSIZE
]; /* buffer size */
1254 /* send a SMBtrans command with api NetServerGetInfo */
1255 p
= make_header(param
, RAP_WserverGetInfo
,
1256 RAP_WserverGetInfo_REQ
, RAP_SERVER_INFO_L1
);
1257 PUTWORD(p
, 1); /* info level */
1258 PUTWORD(p
, CLI_BUFFER_SIZE
);
1261 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1262 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1263 &rparam
, &rprcnt
, /* return params, return size */
1264 &rdata
, &rdrcnt
/* return data, return size */
1267 res
= GETRES(rparam
);
1269 if (res
== 0 || res
== ERRmoredata
) {
1271 *pstype
= IVAL(p
,18) & ~SV_TYPE_LOCAL_LIST_ONLY
;
1278 return(res
== 0 || res
== ERRmoredata
);
1282 /*************************************************************************
1284 * Function Name: cli_ns_check_server_type
1286 * PURPOSE: Remotes a NetServerEnum2 API call to the current server
1287 * requesting server_info_0 level information of machines
1288 * matching the given server type. If the returned server
1289 * list contains the machine name contained in cli->desthost
1290 * then we conclude the server type checks out. This routine
1291 * is useful to retrieve list of server's of a certain
1292 * type when all you have is a null session connection and
1293 * can't remote API calls such as NetWkstaGetInfo or
1296 * Dependencies: none
1299 * cli - pointer to cli_state structure
1300 * workgroup - pointer to string containing domain
1301 * stype - server type
1307 ************************************************************************/
1308 BOOL
cli_ns_check_server_type(struct cli_state
*cli
, char *workgroup
, uint32 stype
)
1310 char *rparam
= NULL
;
1314 char param
[WORDSIZE
/* api number */
1315 +sizeof(RAP_NetServerEnum2_REQ
) /* req string */
1316 +sizeof(RAP_SERVER_INFO_L0
) /* return string */
1317 +WORDSIZE
/* info level */
1318 +WORDSIZE
/* buffer size */
1319 +DWORDSIZE
/* server type */
1320 +RAP_MACHNAME_LEN
]; /* workgroup */
1321 BOOL found_server
= False
;
1324 /* send a SMBtrans command with api NetServerEnum */
1325 p
= make_header(param
, RAP_NetServerEnum2
,
1326 RAP_NetServerEnum2_REQ
, RAP_SERVER_INFO_L0
);
1327 PUTWORD(p
, 0); /* info level 0 */
1328 PUTWORD(p
, CLI_BUFFER_SIZE
);
1330 PUTSTRING(p
, workgroup
, RAP_MACHNAME_LEN
);
1333 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1334 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1335 &rparam
, &rprcnt
, /* return params, return size */
1336 &rdata
, &rdrcnt
/* return data, return size */
1339 res
= GETRES(rparam
);
1340 cli
->rap_error
= res
;
1342 if (res
== 0 || res
== ERRmoredata
) {
1343 int i
, converter
, count
;
1345 p
= rparam
+ WORDSIZE
;
1346 GETWORD(p
, converter
);
1350 for (i
= 0;i
< count
;i
++, p
+= 16) {
1351 char ret_server
[RAP_MACHNAME_LEN
];
1353 GETSTRINGF(p
, ret_server
, RAP_MACHNAME_LEN
);
1354 if (strequal(ret_server
, cli
->desthost
)) {
1355 found_server
= True
;
1361 DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. "
1362 "Error was : %s.\n", cli
->desthost
, cli_errstr(cli
) ));
1369 return found_server
;
1373 /****************************************************************************
1374 perform a NetWkstaUserLogoff
1375 ****************************************************************************/
1376 BOOL
cli_NetWkstaUserLogoff(struct cli_state
*cli
,char *user
, char *workstation
)
1378 char *rparam
= NULL
;
1382 char param
[WORDSIZE
/* api number */
1383 +sizeof(RAP_NetWkstaUserLogoff_REQ
) /* req string */
1384 +sizeof(RAP_USER_LOGOFF_INFO_L1
) /* return string */
1385 +RAP_USERNAME_LEN
+1 /* user name+pad */
1386 +RAP_MACHNAME_LEN
/* wksta name */
1387 +WORDSIZE
/* buffer size */
1388 +WORDSIZE
]; /* buffer size? */
1391 memset(param
, 0, sizeof(param
));
1393 /* send a SMBtrans command with api NetWkstaUserLogoff */
1394 p
= make_header(param
, RAP_WWkstaUserLogoff
,
1395 RAP_NetWkstaUserLogoff_REQ
, RAP_USER_LOGOFF_INFO_L1
);
1396 PUTDWORD(p
, 0); /* Null pointer */
1397 PUTDWORD(p
, 0); /* Null pointer */
1398 fstrcpy(upperbuf
, user
);
1400 PUTSTRINGF(p
, upperbuf
, RAP_USERNAME_LEN
);
1401 p
++; /* strange format, but ok */
1402 fstrcpy(upperbuf
, workstation
);
1404 PUTSTRINGF(p
, upperbuf
, RAP_MACHNAME_LEN
);
1405 PUTWORD(p
, CLI_BUFFER_SIZE
);
1406 PUTWORD(p
, CLI_BUFFER_SIZE
);
1409 param
, PTR_DIFF(p
,param
),1024, /* param, length, max */
1410 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1411 &rparam
, &rprcnt
, /* return params, return size */
1412 &rdata
, &rdrcnt
/* return data, return size */
1414 cli
->rap_error
= GETRES(rparam
);
1416 if (cli
->rap_error
!= 0) {
1417 DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli
->rap_error
));
1423 return (cli
->rap_error
== 0);
1426 int cli_NetPrintQEnum(struct cli_state
*cli
,
1427 void (*qfn
)(const char*,uint16
,uint16
,uint16
,const char*,const char*,const char*,const char*,const char*,uint16
,uint16
),
1428 void (*jfn
)(uint16
,const char*,const char*,const char*,const char*,uint16
,uint16
,const char*,uint
,uint
,const char*))
1430 char param
[WORDSIZE
/* api number */
1431 +sizeof(RAP_NetPrintQEnum_REQ
) /* req string */
1432 +sizeof(RAP_PRINTQ_INFO_L2
) /* return string */
1433 +WORDSIZE
/* info level */
1434 +WORDSIZE
/* buffer size */
1435 +sizeof(RAP_SMB_PRINT_JOB_L1
)]; /* more ret data */
1437 char *rparam
= NULL
;
1443 memset(param
, '\0',sizeof(param
));
1444 p
= make_header(param
, RAP_WPrintQEnum
,
1445 RAP_NetPrintQEnum_REQ
, RAP_PRINTQ_INFO_L2
);
1446 PUTWORD(p
,2); /* Info level 2 */
1447 PUTWORD(p
,0xFFE0); /* Return buffer size */
1448 PUTSTRING(p
, RAP_SMB_PRINT_JOB_L1
, 0);
1451 param
, PTR_DIFF(p
,param
),1024,
1452 NULL
, 0, CLI_BUFFER_SIZE
,
1455 res
= GETRES(rparam
);
1456 cli
->rap_error
= res
;
1458 DEBUG(1,("NetPrintQEnum gave error %d\n", res
));
1463 if (res
== 0 || res
== ERRmoredata
) {
1464 int i
, converter
, count
;
1466 p
= rparam
+ WORDSIZE
;
1467 GETWORD(p
, converter
);
1471 for (i
=0;i
<count
;i
++) {
1472 pstring qname
, sep_file
, print_proc
, dest
, parms
, comment
;
1473 uint16 jobcount
, priority
, start_time
, until_time
, status
;
1475 GETSTRINGF(p
, qname
, RAP_SHARENAME_LEN
);
1477 GETWORD(p
, priority
);
1478 GETWORD(p
, start_time
);
1479 GETWORD(p
, until_time
);
1480 GETSTRINGP(p
, sep_file
, rdata
, converter
);
1481 GETSTRINGP(p
, print_proc
, rdata
, converter
);
1482 GETSTRINGP(p
, dest
, rdata
, converter
);
1483 GETSTRINGP(p
, parms
, rdata
, converter
);
1484 GETSTRINGP(p
, parms
, comment
, converter
);
1486 GETWORD(p
, jobcount
);
1488 qfn(qname
, priority
, start_time
, until_time
, sep_file
, print_proc
,
1489 dest
, parms
, comment
, status
, jobcount
);
1493 for (j
=0;j
<jobcount
;j
++) {
1494 uint16 jid
, pos
, fsstatus
;
1495 pstring ownername
, notifyname
, datatype
, jparms
, jstatus
, jcomment
;
1496 uint submitted
, jsize
;
1499 GETSTRINGF(p
, ownername
, RAP_USERNAME_LEN
);
1501 GETSTRINGF(p
, notifyname
, RAP_MACHNAME_LEN
);
1502 GETSTRINGF(p
, datatype
, RAP_DATATYPE_LEN
);
1503 GETSTRINGP(p
, jparms
, rdata
, converter
);
1505 GETWORD(p
, fsstatus
);
1506 GETSTRINGP(p
, jstatus
, rdata
, converter
);
1507 GETDWORD(p
, submitted
);
1509 GETSTRINGP(p
, jcomment
, rdata
, converter
);
1511 jfn(jid
, ownername
, notifyname
, datatype
, jparms
, pos
, fsstatus
,
1512 jstatus
, submitted
, jsize
, jcomment
);
1517 DEBUG(4,("NetPrintQEnum res=%d\n", res
));
1520 DEBUG(4,("NetPrintQEnum no data returned\n"));
1529 int cli_NetPrintQGetInfo(struct cli_state
*cli
, const char *printer
,
1530 void (*qfn
)(const char*,uint16
,uint16
,uint16
,const char*,const char*,const char*,const char*,const char*,uint16
,uint16
),
1531 void (*jfn
)(uint16
,const char*,const char*,const char*,const char*,uint16
,uint16
,const char*,uint
,uint
,const char*))
1533 char param
[WORDSIZE
/* api number */
1534 +sizeof(RAP_NetPrintQGetInfo_REQ
) /* req string */
1535 +sizeof(RAP_PRINTQ_INFO_L2
) /* return string */
1536 +RAP_SHARENAME_LEN
/* printer name */
1537 +WORDSIZE
/* info level */
1538 +WORDSIZE
/* buffer size */
1539 +sizeof(RAP_SMB_PRINT_JOB_L1
)]; /* more ret data */
1541 char *rparam
= NULL
;
1547 memset(param
, '\0',sizeof(param
));
1548 p
= make_header(param
, RAP_WPrintQGetInfo
,
1549 RAP_NetPrintQGetInfo_REQ
, RAP_PRINTQ_INFO_L2
);
1550 PUTSTRING(p
, printer
, RAP_SHARENAME_LEN
-1);
1551 PUTWORD(p
, 2); /* Info level 2 */
1552 PUTWORD(p
,0xFFE0); /* Return buffer size */
1553 PUTSTRING(p
, RAP_SMB_PRINT_JOB_L1
, 0);
1556 param
, PTR_DIFF(p
,param
),1024,
1557 NULL
, 0, CLI_BUFFER_SIZE
,
1560 res
= GETRES(rparam
);
1561 cli
->rap_error
= res
;
1563 DEBUG(1,("NetPrintQGetInfo gave error %d\n", res
));
1568 if (res
== 0 || res
== ERRmoredata
) {
1569 int rsize
, converter
;
1570 pstring qname
, sep_file
, print_proc
, dest
, parms
, comment
;
1571 uint16 jobcount
, priority
, start_time
, until_time
, status
;
1573 p
= rparam
+ WORDSIZE
;
1574 GETWORD(p
, converter
);
1578 GETSTRINGF(p
, qname
, RAP_SHARENAME_LEN
);
1580 GETWORD(p
, priority
);
1581 GETWORD(p
, start_time
);
1582 GETWORD(p
, until_time
);
1583 GETSTRINGP(p
, sep_file
, rdata
, converter
);
1584 GETSTRINGP(p
, print_proc
, rdata
, converter
);
1585 GETSTRINGP(p
, dest
, rdata
, converter
);
1586 GETSTRINGP(p
, parms
, rdata
, converter
);
1587 GETSTRINGP(p
, comment
, rdata
, converter
);
1589 GETWORD(p
, jobcount
);
1590 qfn(qname
, priority
, start_time
, until_time
, sep_file
, print_proc
,
1591 dest
, parms
, comment
, status
, jobcount
);
1594 for (j
=0;(j
<jobcount
)&&(PTR_DIFF(p
,rdata
)< rsize
);j
++) {
1595 uint16 jid
, pos
, fsstatus
;
1596 pstring ownername
, notifyname
, datatype
, jparms
, jstatus
, jcomment
;
1597 uint submitted
, jsize
;
1600 GETSTRINGF(p
, ownername
, RAP_USERNAME_LEN
);
1602 GETSTRINGF(p
, notifyname
, RAP_MACHNAME_LEN
);
1603 GETSTRINGF(p
, datatype
, RAP_DATATYPE_LEN
);
1604 GETSTRINGP(p
, jparms
, rdata
, converter
);
1606 GETWORD(p
, fsstatus
);
1607 GETSTRINGP(p
, jstatus
, rdata
, converter
);
1608 GETDWORD(p
, submitted
);
1610 GETSTRINGP(p
, jcomment
, rdata
, converter
);
1612 jfn(jid
, ownername
, notifyname
, datatype
, jparms
, pos
, fsstatus
,
1613 jstatus
, submitted
, jsize
, jcomment
);
1617 DEBUG(4,("NetPrintQGetInfo res=%d\n", res
));
1620 DEBUG(4,("NetPrintQGetInfo no data returned\n"));
1629 /****************************************************************************
1630 call a NetServiceEnum - list running services on a different host
1631 ****************************************************************************/
1632 int cli_RNetServiceEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, void *), void *state
)
1634 char param
[WORDSIZE
/* api number */
1635 +sizeof(RAP_NetServiceEnum_REQ
) /* parm string */
1636 +sizeof(RAP_SERVICE_INFO_L2
) /* return string */
1637 +WORDSIZE
/* info level */
1638 +WORDSIZE
]; /* buffer size */
1640 char *rparam
= NULL
;
1646 memset(param
, '\0', sizeof(param
));
1647 p
= make_header(param
, RAP_WServiceEnum
,
1648 RAP_NetServiceEnum_REQ
, RAP_SERVICE_INFO_L2
);
1649 PUTWORD(p
,2); /* Info level 2 */
1650 PUTWORD(p
,0xFFE0); /* Return buffer size */
1653 param
, PTR_DIFF(p
,param
),8,
1654 NULL
, 0, 0xFFE0 /* data area size */,
1657 res
= GETRES(rparam
);
1658 cli
->rap_error
= res
;
1659 if(cli
->rap_error
== 234)
1660 DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n"));
1661 else if (cli
->rap_error
!= 0) {
1662 DEBUG(1,("NetServiceEnum gave error %d\n", cli
->rap_error
));
1667 if (res
== 0 || res
== ERRmoredata
) {
1668 int i
, converter
, count
;
1670 p
= rparam
+ WORDSIZE
; /* skip result */
1671 GETWORD(p
, converter
);
1674 for (i
=0,p
=rdata
;i
<count
;i
++) {
1676 char servicename
[RAP_SRVCNAME_LEN
];
1678 GETSTRINGF(p
, servicename
, RAP_SRVCNAME_LEN
);
1679 p
+=8; /* pass status words */
1680 GETSTRINGF(p
, comment
, RAP_SRVCCMNT_LEN
);
1682 fn(servicename
, comment
, cli
); /* BB add status too */
1685 DEBUG(4,("NetServiceEnum res=%d\n", res
));
1688 DEBUG(4,("NetServiceEnum no data returned\n"));
1698 /****************************************************************************
1699 call a NetSessionEnum - list workstations with sessions to an SMB server
1700 ****************************************************************************/
1701 int cli_NetSessionEnum(struct cli_state
*cli
, void (*fn
)(char *, char *, uint16
, uint16
, uint16
, uint
, uint
, uint
, char *))
1703 char param
[WORDSIZE
/* api number */
1704 +sizeof(RAP_NetSessionEnum_REQ
) /* parm string */
1705 +sizeof(RAP_SESSION_INFO_L2
) /* return string */
1706 +WORDSIZE
/* info level */
1707 +WORDSIZE
]; /* buffer size */
1709 char *rparam
= NULL
;
1714 memset(param
, '\0', sizeof(param
));
1715 p
= make_header(param
, RAP_WsessionEnum
,
1716 RAP_NetSessionEnum_REQ
, RAP_SESSION_INFO_L2
);
1717 PUTWORD(p
,2); /* Info level 2 */
1718 PUTWORD(p
,0xFF); /* Return buffer size */
1721 param
, PTR_DIFF(p
,param
),8,
1722 NULL
, 0, CLI_BUFFER_SIZE
,
1725 res
= GETRES(rparam
);
1726 cli
->rap_error
= res
;
1728 DEBUG(1,("NetSessionEnum gave error %d\n", res
));
1733 if (res
== 0 || res
== ERRmoredata
) {
1734 int i
, converter
, count
;
1736 p
= rparam
+ WORDSIZE
;
1737 GETWORD(p
, converter
);
1740 for (i
=0,p
=rdata
;i
<count
;i
++) {
1741 pstring wsname
, username
, clitype_name
;
1742 uint16 num_conns
, num_opens
, num_users
;
1743 uint sess_time
, idle_time
, user_flags
;
1745 GETSTRINGP(p
, wsname
, rdata
, converter
);
1746 GETSTRINGP(p
, username
, rdata
, converter
);
1747 GETWORD(p
, num_conns
);
1748 GETWORD(p
, num_opens
);
1749 GETWORD(p
, num_users
);
1750 GETDWORD(p
, sess_time
);
1751 GETDWORD(p
, idle_time
);
1752 GETDWORD(p
, user_flags
);
1753 GETSTRINGP(p
, clitype_name
, rdata
, converter
);
1755 fn(wsname
, username
, num_conns
, num_opens
, num_users
, sess_time
,
1756 idle_time
, user_flags
, clitype_name
);
1760 DEBUG(4,("NetSessionEnum res=%d\n", res
));
1763 DEBUG(4,("NetSesssionEnum no data returned\n"));
1772 /****************************************************************************
1773 Call a NetSessionGetInfo - get information about other session to an SMB server.
1774 ****************************************************************************/
1776 int cli_NetSessionGetInfo(struct cli_state
*cli
, const char *workstation
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint16
, uint
, uint
, uint
, const char *))
1778 char param
[WORDSIZE
/* api number */
1779 +sizeof(RAP_NetSessionGetInfo_REQ
) /* req string */
1780 +sizeof(RAP_SESSION_INFO_L2
) /* return string */
1781 +RAP_MACHNAME_LEN
/* wksta name */
1782 +WORDSIZE
/* info level */
1783 +WORDSIZE
]; /* buffer size */
1785 char *rparam
= NULL
;
1791 memset(param
, '\0', sizeof(param
));
1792 p
= make_header(param
, RAP_WsessionGetInfo
,
1793 RAP_NetSessionGetInfo_REQ
, RAP_SESSION_INFO_L2
);
1794 PUTSTRING(p
, workstation
, RAP_MACHNAME_LEN
-1);
1795 PUTWORD(p
,2); /* Info level 2 */
1796 PUTWORD(p
,0xFF); /* Return buffer size */
1799 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
1800 NULL
, 0, CLI_BUFFER_SIZE
,
1803 cli
->rap_error
= SVAL(rparam
,0);
1804 if (cli
->rap_error
!= 0) {
1805 DEBUG(1,("NetSessionGetInfo gave error %d\n", cli
->rap_error
));
1810 res
= GETRES(rparam
);
1812 if (res
== 0 || res
== ERRmoredata
) {
1813 int rsize
, converter
;
1814 pstring wsname
, username
, clitype_name
;
1815 uint16 num_conns
, num_opens
, num_users
;
1816 uint sess_time
, idle_time
, user_flags
;
1818 p
= rparam
+ WORDSIZE
;
1819 GETWORD(p
, converter
);
1823 GETSTRINGP(p
, wsname
, rdata
, converter
);
1824 GETSTRINGP(p
, username
, rdata
, converter
);
1825 GETWORD(p
, num_conns
);
1826 GETWORD(p
, num_opens
);
1827 GETWORD(p
, num_users
);
1828 GETDWORD(p
, sess_time
);
1829 GETDWORD(p
, idle_time
);
1830 GETDWORD(p
, user_flags
);
1831 GETSTRINGP(p
, clitype_name
, rdata
, converter
);
1833 fn(wsname
, username
, num_conns
, num_opens
, num_users
, sess_time
,
1834 idle_time
, user_flags
, clitype_name
);
1836 DEBUG(4,("NetSessionGetInfo res=%d\n", res
));
1839 DEBUG(4,("NetSessionGetInfo no data returned\n"));
1848 /****************************************************************************
1849 call a NetSessionDel - close a session to an SMB server
1850 ****************************************************************************/
1851 int cli_NetSessionDel(struct cli_state
*cli
, const char *workstation
)
1853 char param
[WORDSIZE
/* api number */
1854 +sizeof(RAP_NetSessionDel_REQ
) /* req string */
1855 +1 /* no return string */
1856 +RAP_MACHNAME_LEN
/* workstation name */
1857 +WORDSIZE
]; /* reserved (0) */
1859 char *rparam
= NULL
;
1864 memset(param
, '\0', sizeof(param
));
1865 p
= make_header(param
, RAP_WsessionDel
, RAP_NetSessionDel_REQ
, NULL
);
1866 PUTSTRING(p
, workstation
, RAP_MACHNAME_LEN
-1);
1867 PUTWORD(p
,0); /* reserved word of 0 */
1869 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
1870 NULL
, 0, 200, /* data, length, maxlen */
1871 &rparam
, &rprcnt
, /* return params, length */
1872 &rdata
, &rdrcnt
)) /* return data, length */
1874 res
= GETRES(rparam
);
1875 cli
->rap_error
= res
;
1881 DEBUG(4,("NetFileClose2 res=%d\n", res
));
1885 DEBUG(4,("NetFileClose2 failed\n"));
1895 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
))
1897 char param
[WORDSIZE
/* api number */
1898 +sizeof(RAP_NetConnectionEnum_REQ
) /* req string */
1899 +sizeof(RAP_CONNECTION_INFO_L1
) /* return string */
1900 +RAP_MACHNAME_LEN
/* wksta name */
1901 +WORDSIZE
/* info level */
1902 +WORDSIZE
]; /* buffer size */
1904 char *rparam
= NULL
;
1909 memset(param
, '\0', sizeof(param
));
1910 p
= make_header(param
, RAP_WconnectionEnum
,
1911 RAP_NetConnectionEnum_REQ
, RAP_CONNECTION_INFO_L1
);
1912 PUTSTRING(p
, qualifier
, RAP_MACHNAME_LEN
-1);/* Workstation name */
1913 PUTWORD(p
,1); /* Info level 1 */
1914 PUTWORD(p
,0xFFE0); /* Return buffer size */
1917 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
1918 NULL
, 0, CLI_BUFFER_SIZE
,
1921 res
= GETRES(rparam
);
1922 cli
->rap_error
= res
;
1924 DEBUG(1,("NetConnectionEnum gave error %d\n", res
));
1928 if (res
== 0 || res
== ERRmoredata
) {
1929 int i
, converter
, count
;
1931 p
= rparam
+ WORDSIZE
;
1932 GETWORD(p
, converter
);
1935 for (i
=0,p
=rdata
;i
<count
;i
++) {
1936 pstring netname
, username
;
1937 uint16 conn_id
, conn_type
, num_opens
, num_users
;
1941 GETWORD(p
,conn_type
);
1942 GETWORD(p
,num_opens
);
1943 GETWORD(p
,num_users
);
1944 GETDWORD(p
,conn_time
);
1945 GETSTRINGP(p
, username
, rdata
, converter
);
1946 GETSTRINGP(p
, netname
, rdata
, converter
);
1948 fn(conn_id
, conn_type
, num_opens
, num_users
, conn_time
,
1953 DEBUG(4,("NetConnectionEnum res=%d\n", res
));
1956 DEBUG(4,("NetConnectionEnum no data returned\n"));