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
, const char *reqfmt
, const 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 unsigned int rdrcnt
,rprcnt
;
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 unsigned int rdrcnt
,rprcnt
;
210 char param
[WORDSIZE
/* api number */
211 +sizeof(RAP_NetGroupAdd_REQ
) /* req string */
212 +sizeof(RAP_GROUP_INFO_L1
) /* return string */
213 +WORDSIZE
/* info level */
214 +WORDSIZE
]; /* reserved word */
218 /* offset into data of free format strings. Will be updated */
219 /* by PUTSTRINGP macro and end up with total data length. */
220 int soffset
= RAP_GROUPNAME_LEN
+ 1 + DWORDSIZE
;
222 /* now send a SMBtrans command with api WGroupAdd */
224 p
= make_header(param
, RAP_WGroupAdd
,
225 RAP_NetGroupAdd_REQ
, RAP_GROUP_INFO_L1
);
226 PUTWORD(p
, 1); /* info level */
227 PUTWORD(p
, 0); /* reserved word 0 */
230 PUTSTRINGF(p
, grinfo
->group_name
, RAP_GROUPNAME_LEN
);
231 PUTBYTE(p
, 0); /* pad byte 0 */
232 PUTSTRINGP(p
, grinfo
->comment
, data
, soffset
);
235 param
, sizeof(param
), 1024, /* Param, length, maxlen */
236 data
, soffset
, sizeof(data
), /* data, length, maxlen */
237 &rparam
, &rprcnt
, /* return params, length */
238 &rdata
, &rdrcnt
)) /* return data, length */
240 res
= GETRES(rparam
);
244 } else if ((res
== 5) || (res
== 65)) {
245 DEBUG(1, ("Access Denied\n"));
247 else if (res
== 2223) {
248 DEBUG (1, ("Group already exists\n"));
251 DEBUG(4,("NetGroupAdd res=%d\n", res
));
255 DEBUG(4,("NetGroupAdd failed\n"));
264 /****************************************************************************
265 call a NetGroupEnum - try and list user groups on a different host
266 ****************************************************************************/
267 int cli_RNetGroupEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, void *), void *state
)
269 char param
[WORDSIZE
/* api number */
270 +sizeof(RAP_NetGroupEnum_REQ
) /* parm string */
271 +sizeof(RAP_GROUP_INFO_L1
) /* return string */
272 +WORDSIZE
/* info level */
273 +WORDSIZE
]; /* buffer size */
277 unsigned int rprcnt
, rdrcnt
;
281 memset(param
, '\0', sizeof(param
));
282 p
= make_header(param
, RAP_WGroupEnum
,
283 RAP_NetGroupEnum_REQ
, RAP_GROUP_INFO_L1
);
284 PUTWORD(p
,1); /* Info level 1 */ /* add level 0 */
285 PUTWORD(p
,0xFFE0); /* Return buffer size */
288 param
, PTR_DIFF(p
,param
),8,
289 NULL
, 0, 0xFFE0 /* data area size */,
292 res
= GETRES(rparam
);
293 cli
->rap_error
= res
;
294 if(cli
->rap_error
== 234)
295 DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
296 else if (cli
->rap_error
!= 0) {
297 DEBUG(1,("NetGroupEnum gave error %d\n", cli
->rap_error
));
302 if (res
== 0 || res
== ERRmoredata
) {
303 int i
, converter
, count
;
305 p
= rparam
+ WORDSIZE
; /* skip result */
306 GETWORD(p
, converter
);
309 for (i
=0,p
=rdata
;i
<count
;i
++) {
311 char groupname
[RAP_GROUPNAME_LEN
];
313 GETSTRINGF(p
, groupname
, RAP_GROUPNAME_LEN
);
315 GETSTRINGP(p
, comment
, rdata
, converter
);
317 fn(groupname
, comment
, cli
);
320 DEBUG(4,("NetGroupEnum res=%d\n", res
));
323 DEBUG(4,("NetGroupEnum no data returned\n"));
332 int cli_NetGroupDelUser(struct cli_state
* cli
, const char *group_name
, const char *user_name
)
337 unsigned int rdrcnt
,rprcnt
;
339 char param
[WORDSIZE
/* api number */
340 +sizeof(RAP_NetGroupDelUser_REQ
) /* parm string */
341 +1 /* no ret string */
342 +RAP_GROUPNAME_LEN
/* group name */
343 +RAP_USERNAME_LEN
]; /* user to del */
345 /* now send a SMBtrans command with api GroupMemberAdd */
346 p
= make_header(param
, RAP_WGroupDelUser
, RAP_NetGroupDelUser_REQ
, NULL
);
347 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
);
348 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
);
351 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
352 NULL
, 0, 200, /* data, length, maxlen */
353 &rparam
, &rprcnt
, /* return params, length */
354 &rdata
, &rdrcnt
)) /* return data, length */
356 res
= GETRES(rparam
);
363 DEBUG(1, ("Access Denied\n"));
366 DEBUG(1, ("Not supported by server\n"));
369 DEBUG(1, ("Group does not exist\n"));
372 DEBUG(1, ("User does not exist\n"));
375 DEBUG(1, ("User is not in group\n"));
378 DEBUG(4,("NetGroupDelUser res=%d\n", res
));
382 DEBUG(4,("NetGroupDelUser failed\n"));
391 int cli_NetGroupAddUser(struct cli_state
* cli
, const char *group_name
, const char *user_name
)
396 unsigned int rdrcnt
,rprcnt
;
398 char param
[WORDSIZE
/* api number */
399 +sizeof(RAP_NetGroupAddUser_REQ
) /* parm string */
400 +1 /* no ret string */
401 +RAP_GROUPNAME_LEN
/* group name */
402 +RAP_USERNAME_LEN
]; /* user to add */
404 /* now send a SMBtrans command with api GroupMemberAdd */
405 p
= make_header(param
, RAP_WGroupAddUser
, RAP_NetGroupAddUser_REQ
, NULL
);
406 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
);
407 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
);
410 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
411 NULL
, 0, 200, /* data, length, maxlen */
412 &rparam
, &rprcnt
, /* return params, length */
413 &rdata
, &rdrcnt
)) /* return data, length */
415 res
= GETRES(rparam
);
422 DEBUG(1, ("Access Denied\n"));
425 DEBUG(1, ("Not supported by server\n"));
428 DEBUG(1, ("Group does not exist\n"));
431 DEBUG(1, ("User does not exist\n"));
434 DEBUG(4,("NetGroupAddUser res=%d\n", res
));
438 DEBUG(4,("NetGroupAddUser failed\n"));
448 int cli_NetGroupGetUsers(struct cli_state
* cli
, const char *group_name
, void (*fn
)(const char *, void *), void *state
)
453 unsigned int rdrcnt
,rprcnt
;
455 char param
[WORDSIZE
/* api number */
456 +sizeof(RAP_NetGroupGetUsers_REQ
)/* parm string */
457 +sizeof(RAP_GROUP_USERS_INFO_0
) /* return string */
458 +RAP_GROUPNAME_LEN
/* group name */
459 +WORDSIZE
/* info level */
460 +WORDSIZE
]; /* buffer size */
462 /* now send a SMBtrans command with api GroupGetUsers */
463 p
= make_header(param
, RAP_WGroupGetUsers
,
464 RAP_NetGroupGetUsers_REQ
, RAP_GROUP_USERS_INFO_0
);
465 PUTSTRING(p
,group_name
,RAP_GROUPNAME_LEN
-1);
466 PUTWORD(p
,0); /* info level 0 */
467 PUTWORD(p
,0xFFE0); /* return buffer size */
470 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
471 NULL
, 0, CLI_BUFFER_SIZE
,
474 res
= GETRES(rparam
);
475 cli
->rap_error
= res
;
477 DEBUG(1,("NetGroupGetUsers gave error %d\n", res
));
481 if (res
== 0 || res
== ERRmoredata
) {
482 int i
, converter
, count
;
484 p
= rparam
+WORDSIZE
;
485 GETWORD(p
, converter
);
488 for (i
=0,p
=rdata
; i
<count
; i
++) {
489 GETSTRINGF(p
, username
, RAP_USERNAME_LEN
);
493 DEBUG(4,("NetGroupGetUsers res=%d\n", res
));
496 DEBUG(4,("NetGroupGetUsers no data returned\n"));
503 int cli_NetUserGetGroups(struct cli_state
* cli
, const char *user_name
, void (*fn
)(const char *, void *), void *state
)
508 unsigned int rdrcnt
,rprcnt
;
510 char param
[WORDSIZE
/* api number */
511 +sizeof(RAP_NetUserGetGroups_REQ
)/* parm string */
512 +sizeof(RAP_GROUP_USERS_INFO_0
) /* return string */
513 +RAP_USERNAME_LEN
/* user name */
514 +WORDSIZE
/* info level */
515 +WORDSIZE
]; /* buffer size */
517 /* now send a SMBtrans command with api GroupGetUsers */
518 p
= make_header(param
, RAP_WUserGetGroups
,
519 RAP_NetUserGetGroups_REQ
, RAP_GROUP_USERS_INFO_0
);
520 PUTSTRING(p
,user_name
,RAP_USERNAME_LEN
-1);
521 PUTWORD(p
,0); /* info level 0 */
522 PUTWORD(p
,0xFFE0); /* return buffer size */
525 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
526 NULL
, 0, CLI_BUFFER_SIZE
,
529 res
= GETRES(rparam
);
530 cli
->rap_error
= res
;
532 DEBUG(1,("NetUserGetGroups gave error %d\n", res
));
536 if (res
== 0 || res
== ERRmoredata
) {
537 int i
, converter
, count
;
539 p
= rparam
+WORDSIZE
;
540 GETWORD(p
, converter
);
543 for (i
=0,p
=rdata
; i
<count
; i
++) {
544 GETSTRINGF(p
, groupname
, RAP_USERNAME_LEN
);
545 fn(groupname
, state
);
548 DEBUG(4,("NetUserGetGroups res=%d\n", res
));
551 DEBUG(4,("NetUserGetGroups no data returned\n"));
559 /****************************************************************************
560 call a NetUserDelete - delete user from remote server
561 ****************************************************************************/
562 int cli_NetUserDelete(struct cli_state
*cli
, const char * user_name
)
567 unsigned int rdrcnt
,rprcnt
;
569 char param
[WORDSIZE
/* api number */
570 +sizeof(RAP_NetGroupDel_REQ
) /* parm string */
571 +1 /* no ret string */
572 +RAP_USERNAME_LEN
/* user to del */
573 +WORDSIZE
]; /* reserved word */
575 /* now send a SMBtrans command with api UserDel */
576 p
= make_header(param
, RAP_WUserDel
, RAP_NetGroupDel_REQ
, NULL
);
577 PUTSTRING(p
, user_name
, RAP_USERNAME_LEN
);
578 PUTWORD(p
,0); /* reserved word MBZ on input */
581 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
582 NULL
, 0, 200, /* data, length, maxlen */
583 &rparam
, &rprcnt
, /* return params, length */
584 &rdata
, &rdrcnt
)) /* return data, length */
586 res
= GETRES(rparam
);
591 else if ((res
== 5) || (res
== 65)) {
592 DEBUG(1, ("Access Denied\n"));
594 else if (res
== 2221) {
595 DEBUG (1, ("User does not exist\n"));
598 DEBUG(4,("NetUserDelete res=%d\n", res
));
602 DEBUG(4,("NetUserDelete failed\n"));
611 /****************************************************************************
612 call a NetUserAdd - add user to remote server
613 ****************************************************************************/
614 int cli_NetUserAdd(struct cli_state
*cli
, RAP_USER_INFO_1
* userinfo
)
622 unsigned int rdrcnt
,rprcnt
;
624 char param
[WORDSIZE
/* api number */
625 +sizeof(RAP_NetUserAdd2_REQ
) /* req string */
626 +sizeof(RAP_USER_INFO_L1
) /* data string */
627 +WORDSIZE
/* info level */
628 +WORDSIZE
/* buffer length */
629 +WORDSIZE
]; /* reserved */
632 /* offset into data of free format strings. Will be updated */
633 /* by PUTSTRINGP macro and end up with total data length. */
634 int soffset
=RAP_USERNAME_LEN
+1 /* user name + pad */
635 + RAP_UPASSWD_LEN
/* password */
636 + DWORDSIZE
/* password age */
637 + WORDSIZE
/* privilege */
638 + DWORDSIZE
/* home dir ptr */
639 + DWORDSIZE
/* comment ptr */
640 + WORDSIZE
/* flags */
641 + DWORDSIZE
; /* login script ptr*/
643 /* now send a SMBtrans command with api NetUserAdd */
644 p
= make_header(param
, RAP_WUserAdd2
,
645 RAP_NetUserAdd2_REQ
, RAP_USER_INFO_L1
);
646 PUTWORD(p
, 1); /* info level */
648 PUTWORD(p
, 0); /* pwencrypt */
649 if(userinfo
->passwrd
)
650 PUTWORD(p
,MIN(strlen(userinfo
->passwrd
), RAP_UPASSWD_LEN
));
652 PUTWORD(p
, 0); /* password length */
655 memset(data
, '\0', soffset
);
657 PUTSTRINGF(p
, userinfo
->user_name
, RAP_USERNAME_LEN
);
658 PUTBYTE(p
, 0); /* pad byte 0 */
659 PUTSTRINGF(p
, userinfo
->passwrd
, RAP_UPASSWD_LEN
);
660 PUTDWORD(p
, 0); /* pw age - n.a. on user add */
661 PUTWORD(p
, userinfo
->priv
);
662 PUTSTRINGP(p
, userinfo
->home_dir
, data
, soffset
);
663 PUTSTRINGP(p
, userinfo
->comment
, data
, soffset
);
664 PUTWORD(p
, userinfo
->userflags
);
665 PUTSTRINGP(p
, userinfo
->logon_script
, data
, soffset
);
668 param
, sizeof(param
), 1024, /* Param, length, maxlen */
669 data
, soffset
, sizeof(data
), /* data, length, maxlen */
670 &rparam
, &rprcnt
, /* return params, length */
671 &rdata
, &rdrcnt
)) /* return data, length */
673 res
= GETRES(rparam
);
678 else if ((res
== 5) || (res
== 65)) {
679 DEBUG(1, ("Access Denied\n"));
681 else if (res
== 2224) {
682 DEBUG (1, ("User already exists\n"));
685 DEBUG(4,("NetUserAdd res=%d\n", res
));
689 DEBUG(4,("NetUserAdd failed\n"));
698 /****************************************************************************
699 call a NetUserEnum - try and list users on a different host
700 ****************************************************************************/
701 int cli_RNetUserEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, const char *, const char *, void *), void *state
)
703 char param
[WORDSIZE
/* api number */
704 +sizeof(RAP_NetUserEnum_REQ
) /* parm string */
705 +sizeof(RAP_USER_INFO_L1
) /* return string */
706 +WORDSIZE
/* info level */
707 +WORDSIZE
]; /* buffer size */
711 unsigned int rprcnt
, rdrcnt
;
715 memset(param
, '\0', sizeof(param
));
716 p
= make_header(param
, RAP_WUserEnum
,
717 RAP_NetUserEnum_REQ
, RAP_USER_INFO_L1
);
718 PUTWORD(p
,1); /* Info level 1 */
719 PUTWORD(p
,0xFF00); /* Return buffer size */
721 /* BB Fix handling of large numbers of users to be returned */
723 param
, PTR_DIFF(p
,param
),8,
724 NULL
, 0, CLI_BUFFER_SIZE
,
727 res
= GETRES(rparam
);
728 cli
->rap_error
= res
;
729 if (cli
->rap_error
!= 0) {
730 DEBUG(1,("NetUserEnum gave error %d\n", cli
->rap_error
));
734 if (res
== 0 || res
== ERRmoredata
) {
735 int i
, converter
, count
;
736 char username
[RAP_USERNAME_LEN
];
737 char userpw
[RAP_UPASSWD_LEN
];
738 pstring comment
, homedir
, logonscript
;
739 int pwage
, priv
, flags
;
741 p
= rparam
+ WORDSIZE
; /* skip result */
742 GETWORD(p
, converter
);
745 for (i
=0,p
=rdata
;i
<count
;i
++) {
746 GETSTRINGF(p
, username
, RAP_USERNAME_LEN
);
748 GETSTRINGF(p
, userpw
, RAP_UPASSWD_LEN
);
749 GETDWORD(p
, pwage
); /* password age */
750 GETWORD(p
, priv
); /* 0=guest, 1=user, 2=admin */
751 GETSTRINGP(p
, homedir
, rdata
, converter
);
752 GETSTRINGP(p
, comment
, rdata
, converter
);
754 GETSTRINGP(p
, logonscript
, rdata
, converter
);
756 fn(username
, comment
, homedir
, logonscript
, cli
);
759 DEBUG(4,("NetUserEnum res=%d\n", res
));
762 DEBUG(4,("NetUserEnum no data returned\n"));
771 /****************************************************************************
772 call a NetFileClose2 - close open file on another session to server
773 ****************************************************************************/
774 int cli_NetFileClose(struct cli_state
*cli
, uint32 file_id
)
779 unsigned int rdrcnt
,rprcnt
;
780 char param
[WORDSIZE
/* api number */
781 +sizeof(RAP_WFileClose2_REQ
) /* req string */
782 +1 /* no ret string */
783 +DWORDSIZE
]; /* file ID */
786 /* now send a SMBtrans command with api RNetShareEnum */
787 p
= make_header(param
, RAP_WFileClose2
, RAP_WFileClose2_REQ
, NULL
);
788 PUTDWORD(p
, file_id
);
791 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
792 NULL
, 0, 200, /* data, length, maxlen */
793 &rparam
, &rprcnt
, /* return params, length */
794 &rdata
, &rdrcnt
)) /* return data, length */
796 res
= GETRES(rparam
);
800 } else if (res
== 2314){
801 DEBUG(1, ("NetFileClose2 - attempt to close non-existant file open instance\n"));
803 DEBUG(4,("NetFileClose2 res=%d\n", res
));
807 DEBUG(4,("NetFileClose2 failed\n"));
816 /****************************************************************************
817 call a NetFileGetInfo - get information about server file opened from other
819 ****************************************************************************/
820 int cli_NetFileGetInfo(struct cli_state
*cli
, uint32 file_id
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint32
))
825 unsigned int rdrcnt
,rprcnt
;
827 char param
[WORDSIZE
/* api number */
828 +sizeof(RAP_WFileGetInfo2_REQ
) /* req string */
829 +sizeof(RAP_FILE_INFO_L3
) /* return string */
830 +DWORDSIZE
/* file ID */
831 +WORDSIZE
/* info level */
832 +WORDSIZE
]; /* buffer size */
834 /* now send a SMBtrans command with api RNetShareEnum */
835 p
= make_header(param
, RAP_WFileGetInfo2
,
836 RAP_WFileGetInfo2_REQ
, RAP_FILE_INFO_L3
);
837 PUTDWORD(p
, file_id
);
838 PUTWORD(p
, 3); /* info level */
839 PUTWORD(p
, 0x1000); /* buffer size */
841 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
842 NULL
, 0, 0x1000, /* data, length, maxlen */
843 &rparam
, &rprcnt
, /* return params, length */
844 &rdata
, &rdrcnt
)) /* return data, length */
846 res
= GETRES(rparam
);
847 if (res
== 0 || res
== ERRmoredata
) {
848 int converter
,id
, perms
, locks
;
849 pstring fpath
, fuser
;
851 p
= rparam
+ WORDSIZE
; /* skip result */
852 GETWORD(p
, converter
);
858 GETSTRINGP(p
, fpath
, rdata
, converter
);
859 GETSTRINGP(p
, fuser
, rdata
, converter
);
861 fn(fpath
, fuser
, perms
, locks
, id
);
863 DEBUG(4,("NetFileGetInfo2 res=%d\n", res
));
867 DEBUG(4,("NetFileGetInfo2 failed\n"));
876 /****************************************************************************
877 * Call a NetFileEnum2 - list open files on an SMB server
879 * PURPOSE: Remotes a NetFileEnum API call to the current server or target
880 * server listing the files open via the network (and their
881 * corresponding open instance ids)
886 * cli - pointer to cli_state structure
887 * user - if present, return only files opened by this remote user
888 * base_path - if present, return only files opened below this
890 * fn - display function to invoke for each entry in the result
897 ****************************************************************************/
898 int cli_NetFileEnum(struct cli_state
*cli
, char * user
, char * base_path
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint32
))
903 unsigned int rdrcnt
,rprcnt
;
904 char param
[WORDSIZE
/* api number */
905 +sizeof(RAP_WFileEnum2_REQ
) /* req string */
906 +sizeof(RAP_FILE_INFO_L3
) /* return string */
907 +256 /* base path (opt) */
908 +RAP_USERNAME_LEN
/* user name (opt) */
909 +WORDSIZE
/* info level */
910 +WORDSIZE
/* buffer size */
911 +DWORDSIZE
/* resume key ? */
912 +DWORDSIZE
]; /* resume key ? */
915 /* now send a SMBtrans command with api RNetShareEnum */
916 p
= make_header(param
, RAP_WFileEnum2
,
917 RAP_WFileEnum2_REQ
, RAP_FILE_INFO_L3
);
919 PUTSTRING(p
, base_path
, 256);
920 PUTSTRING(p
, user
, RAP_USERNAME_LEN
);
921 PUTWORD(p
, 3); /* info level */
922 PUTWORD(p
, 0xFF00); /* buffer size */
923 PUTDWORD(p
, 0); /* zero out the resume key */
924 PUTDWORD(p
, 0); /* or is this one the resume key? */
927 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
928 NULL
, 0, 0xFF00, /* data, length, maxlen */
929 &rparam
, &rprcnt
, /* return params, length */
930 &rdata
, &rdrcnt
)) /* return data, length */
932 int res
= GETRES(rparam
);
934 if (res
== 0 || res
== ERRmoredata
) {
937 p
= rparam
+ WORDSIZE
; /* skip result */
938 GETWORD(p
, converter
);
942 for (i
=0; i
<count
; i
++) {
943 int id
, perms
, locks
;
944 pstring fpath
, fuser
;
949 GETSTRINGP(p
, fpath
, rdata
, converter
);
950 GETSTRINGP(p
, fuser
, rdata
, converter
);
952 fn(fpath
, fuser
, perms
, locks
, id
);
953 } /* BB fix ERRmoredata case to send resume request */
955 DEBUG(4,("NetFileEnum2 res=%d\n", res
));
958 DEBUG(4,("NetFileEnum2 failed\n"));
967 /****************************************************************************
968 call a NetShareAdd - share/export directory on remote server
969 ****************************************************************************/
970 int cli_NetShareAdd(struct cli_state
*cli
, RAP_SHARE_INFO_2
* sinfo
)
975 unsigned int rdrcnt
,rprcnt
;
977 char param
[WORDSIZE
/* api number */
978 +sizeof(RAP_WShareAdd_REQ
) /* req string */
979 +sizeof(RAP_SHARE_INFO_L2
) /* return string */
980 +WORDSIZE
/* info level */
981 +WORDSIZE
]; /* reserved word */
983 /* offset to free format string section following fixed length data. */
984 /* will be updated by PUTSTRINGP macro and will end up with total len */
985 int soffset
= RAP_SHARENAME_LEN
+ 1 /* share name + pad */
986 + WORDSIZE
/* share type */
987 + DWORDSIZE
/* comment pointer */
988 + WORDSIZE
/* permissions */
989 + WORDSIZE
/* max users */
990 + WORDSIZE
/* active users */
991 + DWORDSIZE
/* share path */
992 + RAP_SPASSWD_LEN
+ 1; /* share password + pad */
994 memset(param
,'\0',sizeof(param
));
995 /* now send a SMBtrans command with api RNetShareAdd */
996 p
= make_header(param
, RAP_WshareAdd
,
997 RAP_WShareAdd_REQ
, RAP_SHARE_INFO_L2
);
998 PUTWORD(p
, 2); /* info level */
999 PUTWORD(p
, 0); /* reserved word 0 */
1002 PUTSTRINGF(p
, sinfo
->share_name
, RAP_SHARENAME_LEN
);
1003 PUTBYTE(p
, 0); /* pad byte 0 */
1005 PUTWORD(p
, sinfo
->share_type
);
1006 PUTSTRINGP(p
, sinfo
->comment
, data
, soffset
);
1007 PUTWORD(p
, sinfo
->perms
);
1008 PUTWORD(p
, sinfo
->maximum_users
);
1009 PUTWORD(p
, sinfo
->active_users
);
1010 PUTSTRINGP(p
, sinfo
->path
, data
, soffset
);
1011 PUTSTRINGF(p
, sinfo
->password
, RAP_SPASSWD_LEN
);
1012 SCVAL(p
,-1,0x0A); /* required 0x0A at end of password */
1015 param
, sizeof(param
), 1024, /* Param, length, maxlen */
1016 data
, soffset
, sizeof(data
), /* data, length, maxlen */
1017 &rparam
, &rprcnt
, /* return params, length */
1018 &rdata
, &rdrcnt
)) /* return data, length */
1020 res
= rparam
? SVAL(rparam
,0) : -1;
1026 DEBUG(4,("NetShareAdd res=%d\n", res
));
1030 DEBUG(4,("NetShareAdd failed\n"));
1038 /****************************************************************************
1039 call a NetShareDelete - unshare exported directory on remote server
1040 ****************************************************************************/
1041 int cli_NetShareDelete(struct cli_state
*cli
, const char * share_name
)
1043 char *rparam
= NULL
;
1046 unsigned int rdrcnt
,rprcnt
;
1048 char param
[WORDSIZE
/* api number */
1049 +sizeof(RAP_WShareDel_REQ
) /* req string */
1050 +1 /* no ret string */
1051 +RAP_SHARENAME_LEN
/* share to del */
1052 +WORDSIZE
]; /* reserved word */
1055 /* now send a SMBtrans command with api RNetShareDelete */
1056 p
= make_header(param
, RAP_WshareDel
, RAP_WShareDel_REQ
, NULL
);
1057 PUTSTRING(p
,share_name
,RAP_SHARENAME_LEN
);
1058 PUTWORD(p
,0); /* reserved word MBZ on input */
1061 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
1062 NULL
, 0, 200, /* data, length, maxlen */
1063 &rparam
, &rprcnt
, /* return params, length */
1064 &rdata
, &rdrcnt
)) /* return data, length */
1066 res
= GETRES(rparam
);
1072 DEBUG(4,("NetShareDelete res=%d\n", res
));
1076 DEBUG(4,("NetShareDelete failed\n"));
1084 /*************************************************************************
1086 * Function Name: cli_get_pdc_name
1088 * PURPOSE: Remotes a NetServerEnum API call to the current server
1089 * requesting the name of a server matching the server
1090 * type of SV_TYPE_DOMAIN_CTRL (PDC).
1092 * Dependencies: none
1095 * cli - pointer to cli_state structure
1096 * workgroup - pointer to string containing name of domain
1097 * pdc_name - pointer to string that will contain PDC name
1098 * on successful return
1104 ************************************************************************/
1105 BOOL
cli_get_pdc_name(struct cli_state
*cli
, char *workgroup
, char *pdc_name
)
1107 char *rparam
= NULL
;
1109 unsigned int rdrcnt
,rprcnt
;
1111 char param
[WORDSIZE
/* api number */
1112 +sizeof(RAP_NetServerEnum2_REQ
) /* req string */
1113 +sizeof(RAP_SERVER_INFO_L1
) /* return string */
1114 +WORDSIZE
/* info level */
1115 +WORDSIZE
/* buffer size */
1116 +DWORDSIZE
/* server type */
1117 +RAP_MACHNAME_LEN
]; /* workgroup */
1122 /* send a SMBtrans command with api NetServerEnum */
1123 p
= make_header(param
, RAP_NetServerEnum2
,
1124 RAP_NetServerEnum2_REQ
, RAP_SERVER_INFO_L1
);
1125 PUTWORD(p
, 1); /* info level */
1126 PUTWORD(p
, CLI_BUFFER_SIZE
);
1127 PUTDWORD(p
, SV_TYPE_DOMAIN_CTRL
);
1128 PUTSTRING(p
, workgroup
, RAP_MACHNAME_LEN
);
1131 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1132 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1133 &rparam
, &rprcnt
, /* return params, return size */
1134 &rdata
, &rdrcnt
/* return data, return size */
1136 cli
->rap_error
= GETRES(rparam
);
1139 * We only really care to copy a name if the
1140 * API succeeded and we got back a name.
1142 if (cli
->rap_error
== 0) {
1143 p
= rparam
+ WORDSIZE
+ WORDSIZE
; /* skip result and converter */
1148 GETSTRING(p
, pdc_name
);
1151 DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. "
1152 "Error was : %s.\n", cli
->desthost
, cli_errstr(cli
) ));
1163 /*************************************************************************
1165 * Function Name: cli_get_server_domain
1167 * PURPOSE: Remotes a NetWkstaGetInfo API call to the current server
1168 * requesting wksta_info_10 level information to determine
1169 * the domain the server belongs to. On success, this
1170 * routine sets the server_domain field in the cli_state structure
1171 * to the server's domain name.
1173 * Dependencies: none
1176 * cli - pointer to cli_state structure
1182 * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
1184 ************************************************************************/
1185 BOOL
cli_get_server_domain(struct cli_state
*cli
)
1187 char *rparam
= NULL
;
1189 unsigned int rdrcnt
,rprcnt
;
1191 char param
[WORDSIZE
/* api number */
1192 +sizeof(RAP_WWkstaGetInfo_REQ
) /* req string */
1193 +sizeof(RAP_WKSTA_INFO_L10
) /* return string */
1194 +WORDSIZE
/* info level */
1195 +WORDSIZE
]; /* buffer size */
1198 /* send a SMBtrans command with api NetWkstaGetInfo */
1199 p
= make_header(param
, RAP_WWkstaGetInfo
,
1200 RAP_WWkstaGetInfo_REQ
, RAP_WKSTA_INFO_L10
);
1201 PUTWORD(p
, 10); /* info level */
1202 PUTWORD(p
, CLI_BUFFER_SIZE
);
1204 if (cli_api(cli
, param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1205 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1206 &rparam
, &rprcnt
, /* return params, return size */
1207 &rdata
, &rdrcnt
)) { /* return data, return size */
1208 res
= GETRES(rparam
);
1214 p
= rparam
+ WORDSIZE
;
1215 GETWORD(p
, converter
);
1217 p
= rdata
+ DWORDSIZE
+ DWORDSIZE
; /* skip computer & user names */
1218 GETSTRINGP(p
, cli
->server_domain
, rdata
, converter
);
1229 /*************************************************************************
1231 * Function Name: cli_get_server_type
1233 * PURPOSE: Remotes a NetServerGetInfo API call to the current server
1234 * requesting server_info_1 level information to retrieve
1237 * Dependencies: none
1240 * cli - pointer to cli_state structure
1241 * pstype - pointer to uint32 to contain returned server type
1247 * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
1249 ************************************************************************/
1250 BOOL
cli_get_server_type(struct cli_state
*cli
, uint32
*pstype
)
1252 char *rparam
= NULL
;
1254 unsigned int rdrcnt
,rprcnt
;
1256 char param
[WORDSIZE
/* api number */
1257 +sizeof(RAP_WserverGetInfo_REQ
) /* req string */
1258 +sizeof(RAP_SERVER_INFO_L1
) /* return string */
1259 +WORDSIZE
/* info level */
1260 +WORDSIZE
]; /* buffer size */
1263 /* send a SMBtrans command with api NetServerGetInfo */
1264 p
= make_header(param
, RAP_WserverGetInfo
,
1265 RAP_WserverGetInfo_REQ
, RAP_SERVER_INFO_L1
);
1266 PUTWORD(p
, 1); /* info level */
1267 PUTWORD(p
, CLI_BUFFER_SIZE
);
1270 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1271 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1272 &rparam
, &rprcnt
, /* return params, return size */
1273 &rdata
, &rdrcnt
/* return data, return size */
1276 res
= GETRES(rparam
);
1278 if (res
== 0 || res
== ERRmoredata
) {
1280 *pstype
= IVAL(p
,18) & ~SV_TYPE_LOCAL_LIST_ONLY
;
1287 return(res
== 0 || res
== ERRmoredata
);
1291 /*************************************************************************
1293 * Function Name: cli_ns_check_server_type
1295 * PURPOSE: Remotes a NetServerEnum2 API call to the current server
1296 * requesting server_info_0 level information of machines
1297 * matching the given server type. If the returned server
1298 * list contains the machine name contained in cli->desthost
1299 * then we conclude the server type checks out. This routine
1300 * is useful to retrieve list of server's of a certain
1301 * type when all you have is a null session connection and
1302 * can't remote API calls such as NetWkstaGetInfo or
1305 * Dependencies: none
1308 * cli - pointer to cli_state structure
1309 * workgroup - pointer to string containing domain
1310 * stype - server type
1316 ************************************************************************/
1317 BOOL
cli_ns_check_server_type(struct cli_state
*cli
, char *workgroup
, uint32 stype
)
1319 char *rparam
= NULL
;
1321 unsigned int rdrcnt
,rprcnt
;
1323 char param
[WORDSIZE
/* api number */
1324 +sizeof(RAP_NetServerEnum2_REQ
) /* req string */
1325 +sizeof(RAP_SERVER_INFO_L0
) /* return string */
1326 +WORDSIZE
/* info level */
1327 +WORDSIZE
/* buffer size */
1328 +DWORDSIZE
/* server type */
1329 +RAP_MACHNAME_LEN
]; /* workgroup */
1330 BOOL found_server
= False
;
1333 /* send a SMBtrans command with api NetServerEnum */
1334 p
= make_header(param
, RAP_NetServerEnum2
,
1335 RAP_NetServerEnum2_REQ
, RAP_SERVER_INFO_L0
);
1336 PUTWORD(p
, 0); /* info level 0 */
1337 PUTWORD(p
, CLI_BUFFER_SIZE
);
1339 PUTSTRING(p
, workgroup
, RAP_MACHNAME_LEN
);
1342 param
, PTR_DIFF(p
,param
), 8, /* params, length, max */
1343 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1344 &rparam
, &rprcnt
, /* return params, return size */
1345 &rdata
, &rdrcnt
/* return data, return size */
1348 res
= GETRES(rparam
);
1349 cli
->rap_error
= res
;
1351 if (res
== 0 || res
== ERRmoredata
) {
1352 int i
, converter
, count
;
1354 p
= rparam
+ WORDSIZE
;
1355 GETWORD(p
, converter
);
1359 for (i
= 0;i
< count
;i
++, p
+= 16) {
1360 char ret_server
[RAP_MACHNAME_LEN
];
1362 GETSTRINGF(p
, ret_server
, RAP_MACHNAME_LEN
);
1363 if (strequal(ret_server
, cli
->desthost
)) {
1364 found_server
= True
;
1370 DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. "
1371 "Error was : %s.\n", cli
->desthost
, cli_errstr(cli
) ));
1378 return found_server
;
1382 /****************************************************************************
1383 perform a NetWkstaUserLogoff
1384 ****************************************************************************/
1385 BOOL
cli_NetWkstaUserLogoff(struct cli_state
*cli
,char *user
, char *workstation
)
1387 char *rparam
= NULL
;
1390 unsigned int rdrcnt
,rprcnt
;
1391 char param
[WORDSIZE
/* api number */
1392 +sizeof(RAP_NetWkstaUserLogoff_REQ
) /* req string */
1393 +sizeof(RAP_USER_LOGOFF_INFO_L1
) /* return string */
1394 +RAP_USERNAME_LEN
+1 /* user name+pad */
1395 +RAP_MACHNAME_LEN
/* wksta name */
1396 +WORDSIZE
/* buffer size */
1397 +WORDSIZE
]; /* buffer size? */
1400 memset(param
, 0, sizeof(param
));
1402 /* send a SMBtrans command with api NetWkstaUserLogoff */
1403 p
= make_header(param
, RAP_WWkstaUserLogoff
,
1404 RAP_NetWkstaUserLogoff_REQ
, RAP_USER_LOGOFF_INFO_L1
);
1405 PUTDWORD(p
, 0); /* Null pointer */
1406 PUTDWORD(p
, 0); /* Null pointer */
1407 fstrcpy(upperbuf
, user
);
1408 strupper_m(upperbuf
);
1409 PUTSTRINGF(p
, upperbuf
, RAP_USERNAME_LEN
);
1410 p
++; /* strange format, but ok */
1411 fstrcpy(upperbuf
, workstation
);
1412 strupper_m(upperbuf
);
1413 PUTSTRINGF(p
, upperbuf
, RAP_MACHNAME_LEN
);
1414 PUTWORD(p
, CLI_BUFFER_SIZE
);
1415 PUTWORD(p
, CLI_BUFFER_SIZE
);
1418 param
, PTR_DIFF(p
,param
),1024, /* param, length, max */
1419 NULL
, 0, CLI_BUFFER_SIZE
, /* data, length, max */
1420 &rparam
, &rprcnt
, /* return params, return size */
1421 &rdata
, &rdrcnt
/* return data, return size */
1423 cli
->rap_error
= GETRES(rparam
);
1425 if (cli
->rap_error
!= 0) {
1426 DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli
->rap_error
));
1432 return (cli
->rap_error
== 0);
1435 int cli_NetPrintQEnum(struct cli_state
*cli
,
1436 void (*qfn
)(const char*,uint16
,uint16
,uint16
,const char*,const char*,const char*,const char*,const char*,uint16
,uint16
),
1437 void (*jfn
)(uint16
,const char*,const char*,const char*,const char*,uint16
,uint16
,const char*,uint
,uint
,const char*))
1439 char param
[WORDSIZE
/* api number */
1440 +sizeof(RAP_NetPrintQEnum_REQ
) /* req string */
1441 +sizeof(RAP_PRINTQ_INFO_L2
) /* return string */
1442 +WORDSIZE
/* info level */
1443 +WORDSIZE
/* buffer size */
1444 +sizeof(RAP_SMB_PRINT_JOB_L1
)]; /* more ret data */
1446 char *rparam
= NULL
;
1448 unsigned int rprcnt
, rdrcnt
;
1452 memset(param
, '\0',sizeof(param
));
1453 p
= make_header(param
, RAP_WPrintQEnum
,
1454 RAP_NetPrintQEnum_REQ
, RAP_PRINTQ_INFO_L2
);
1455 PUTWORD(p
,2); /* Info level 2 */
1456 PUTWORD(p
,0xFFE0); /* Return buffer size */
1457 PUTSTRING(p
, RAP_SMB_PRINT_JOB_L1
, 0);
1460 param
, PTR_DIFF(p
,param
),1024,
1461 NULL
, 0, CLI_BUFFER_SIZE
,
1464 res
= GETRES(rparam
);
1465 cli
->rap_error
= res
;
1467 DEBUG(1,("NetPrintQEnum gave error %d\n", res
));
1472 if (res
== 0 || res
== ERRmoredata
) {
1473 int i
, converter
, count
;
1475 p
= rparam
+ WORDSIZE
;
1476 GETWORD(p
, converter
);
1480 for (i
=0;i
<count
;i
++) {
1481 pstring qname
, sep_file
, print_proc
, dest
, parms
, comment
;
1482 uint16 jobcount
, priority
, start_time
, until_time
, status
;
1484 GETSTRINGF(p
, qname
, RAP_SHARENAME_LEN
);
1486 GETWORD(p
, priority
);
1487 GETWORD(p
, start_time
);
1488 GETWORD(p
, until_time
);
1489 GETSTRINGP(p
, sep_file
, rdata
, converter
);
1490 GETSTRINGP(p
, print_proc
, rdata
, converter
);
1491 GETSTRINGP(p
, dest
, rdata
, converter
);
1492 GETSTRINGP(p
, parms
, rdata
, converter
);
1493 GETSTRINGP(p
, parms
, comment
, converter
);
1495 GETWORD(p
, jobcount
);
1497 qfn(qname
, priority
, start_time
, until_time
, sep_file
, print_proc
,
1498 dest
, parms
, comment
, status
, jobcount
);
1502 for (j
=0;j
<jobcount
;j
++) {
1503 uint16 jid
, pos
, fsstatus
;
1504 pstring ownername
, notifyname
, datatype
, jparms
, jstatus
, jcomment
;
1505 unsigned int submitted
, jsize
;
1508 GETSTRINGF(p
, ownername
, RAP_USERNAME_LEN
);
1510 GETSTRINGF(p
, notifyname
, RAP_MACHNAME_LEN
);
1511 GETSTRINGF(p
, datatype
, RAP_DATATYPE_LEN
);
1512 GETSTRINGP(p
, jparms
, rdata
, converter
);
1514 GETWORD(p
, fsstatus
);
1515 GETSTRINGP(p
, jstatus
, rdata
, converter
);
1516 GETDWORD(p
, submitted
);
1518 GETSTRINGP(p
, jcomment
, rdata
, converter
);
1520 jfn(jid
, ownername
, notifyname
, datatype
, jparms
, pos
, fsstatus
,
1521 jstatus
, submitted
, jsize
, jcomment
);
1526 DEBUG(4,("NetPrintQEnum res=%d\n", res
));
1529 DEBUG(4,("NetPrintQEnum no data returned\n"));
1538 int cli_NetPrintQGetInfo(struct cli_state
*cli
, const char *printer
,
1539 void (*qfn
)(const char*,uint16
,uint16
,uint16
,const char*,const char*,const char*,const char*,const char*,uint16
,uint16
),
1540 void (*jfn
)(uint16
,const char*,const char*,const char*,const char*,uint16
,uint16
,const char*,uint
,uint
,const char*))
1542 char param
[WORDSIZE
/* api number */
1543 +sizeof(RAP_NetPrintQGetInfo_REQ
) /* req string */
1544 +sizeof(RAP_PRINTQ_INFO_L2
) /* return string */
1545 +RAP_SHARENAME_LEN
/* printer name */
1546 +WORDSIZE
/* info level */
1547 +WORDSIZE
/* buffer size */
1548 +sizeof(RAP_SMB_PRINT_JOB_L1
)]; /* more ret data */
1550 char *rparam
= NULL
;
1552 unsigned int rprcnt
, rdrcnt
;
1556 memset(param
, '\0',sizeof(param
));
1557 p
= make_header(param
, RAP_WPrintQGetInfo
,
1558 RAP_NetPrintQGetInfo_REQ
, RAP_PRINTQ_INFO_L2
);
1559 PUTSTRING(p
, printer
, RAP_SHARENAME_LEN
-1);
1560 PUTWORD(p
, 2); /* Info level 2 */
1561 PUTWORD(p
,0xFFE0); /* Return buffer size */
1562 PUTSTRING(p
, RAP_SMB_PRINT_JOB_L1
, 0);
1565 param
, PTR_DIFF(p
,param
),1024,
1566 NULL
, 0, CLI_BUFFER_SIZE
,
1569 res
= GETRES(rparam
);
1570 cli
->rap_error
= res
;
1572 DEBUG(1,("NetPrintQGetInfo gave error %d\n", res
));
1577 if (res
== 0 || res
== ERRmoredata
) {
1578 int rsize
, converter
;
1579 pstring qname
, sep_file
, print_proc
, dest
, parms
, comment
;
1580 uint16 jobcount
, priority
, start_time
, until_time
, status
;
1582 p
= rparam
+ WORDSIZE
;
1583 GETWORD(p
, converter
);
1587 GETSTRINGF(p
, qname
, RAP_SHARENAME_LEN
);
1589 GETWORD(p
, priority
);
1590 GETWORD(p
, start_time
);
1591 GETWORD(p
, until_time
);
1592 GETSTRINGP(p
, sep_file
, rdata
, converter
);
1593 GETSTRINGP(p
, print_proc
, rdata
, converter
);
1594 GETSTRINGP(p
, dest
, rdata
, converter
);
1595 GETSTRINGP(p
, parms
, rdata
, converter
);
1596 GETSTRINGP(p
, comment
, rdata
, converter
);
1598 GETWORD(p
, jobcount
);
1599 qfn(qname
, priority
, start_time
, until_time
, sep_file
, print_proc
,
1600 dest
, parms
, comment
, status
, jobcount
);
1603 for (j
=0;(j
<jobcount
)&&(PTR_DIFF(p
,rdata
)< rsize
);j
++) {
1604 uint16 jid
, pos
, fsstatus
;
1605 pstring ownername
, notifyname
, datatype
, jparms
, jstatus
, jcomment
;
1606 unsigned int submitted
, jsize
;
1609 GETSTRINGF(p
, ownername
, RAP_USERNAME_LEN
);
1611 GETSTRINGF(p
, notifyname
, RAP_MACHNAME_LEN
);
1612 GETSTRINGF(p
, datatype
, RAP_DATATYPE_LEN
);
1613 GETSTRINGP(p
, jparms
, rdata
, converter
);
1615 GETWORD(p
, fsstatus
);
1616 GETSTRINGP(p
, jstatus
, rdata
, converter
);
1617 GETDWORD(p
, submitted
);
1619 GETSTRINGP(p
, jcomment
, rdata
, converter
);
1621 jfn(jid
, ownername
, notifyname
, datatype
, jparms
, pos
, fsstatus
,
1622 jstatus
, submitted
, jsize
, jcomment
);
1626 DEBUG(4,("NetPrintQGetInfo res=%d\n", res
));
1629 DEBUG(4,("NetPrintQGetInfo no data returned\n"));
1638 /****************************************************************************
1639 call a NetServiceEnum - list running services on a different host
1640 ****************************************************************************/
1641 int cli_RNetServiceEnum(struct cli_state
*cli
, void (*fn
)(const char *, const char *, void *), void *state
)
1643 char param
[WORDSIZE
/* api number */
1644 +sizeof(RAP_NetServiceEnum_REQ
) /* parm string */
1645 +sizeof(RAP_SERVICE_INFO_L2
) /* return string */
1646 +WORDSIZE
/* info level */
1647 +WORDSIZE
]; /* buffer size */
1649 char *rparam
= NULL
;
1651 unsigned int rprcnt
, rdrcnt
;
1655 memset(param
, '\0', sizeof(param
));
1656 p
= make_header(param
, RAP_WServiceEnum
,
1657 RAP_NetServiceEnum_REQ
, RAP_SERVICE_INFO_L2
);
1658 PUTWORD(p
,2); /* Info level 2 */
1659 PUTWORD(p
,0xFFE0); /* Return buffer size */
1662 param
, PTR_DIFF(p
,param
),8,
1663 NULL
, 0, 0xFFE0 /* data area size */,
1666 res
= GETRES(rparam
);
1667 cli
->rap_error
= res
;
1668 if(cli
->rap_error
== 234)
1669 DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n"));
1670 else if (cli
->rap_error
!= 0) {
1671 DEBUG(1,("NetServiceEnum gave error %d\n", cli
->rap_error
));
1676 if (res
== 0 || res
== ERRmoredata
) {
1677 int i
, converter
, count
;
1679 p
= rparam
+ WORDSIZE
; /* skip result */
1680 GETWORD(p
, converter
);
1683 for (i
=0,p
=rdata
;i
<count
;i
++) {
1685 char servicename
[RAP_SRVCNAME_LEN
];
1687 GETSTRINGF(p
, servicename
, RAP_SRVCNAME_LEN
);
1688 p
+=8; /* pass status words */
1689 GETSTRINGF(p
, comment
, RAP_SRVCCMNT_LEN
);
1691 fn(servicename
, comment
, cli
); /* BB add status too */
1694 DEBUG(4,("NetServiceEnum res=%d\n", res
));
1697 DEBUG(4,("NetServiceEnum no data returned\n"));
1707 /****************************************************************************
1708 call a NetSessionEnum - list workstations with sessions to an SMB server
1709 ****************************************************************************/
1710 int cli_NetSessionEnum(struct cli_state
*cli
, void (*fn
)(char *, char *, uint16
, uint16
, uint16
, uint
, uint
, uint
, char *))
1712 char param
[WORDSIZE
/* api number */
1713 +sizeof(RAP_NetSessionEnum_REQ
) /* parm string */
1714 +sizeof(RAP_SESSION_INFO_L2
) /* return string */
1715 +WORDSIZE
/* info level */
1716 +WORDSIZE
]; /* buffer size */
1718 char *rparam
= NULL
;
1720 unsigned int rprcnt
, rdrcnt
;
1723 memset(param
, '\0', sizeof(param
));
1724 p
= make_header(param
, RAP_WsessionEnum
,
1725 RAP_NetSessionEnum_REQ
, RAP_SESSION_INFO_L2
);
1726 PUTWORD(p
,2); /* Info level 2 */
1727 PUTWORD(p
,0xFF); /* Return buffer size */
1730 param
, PTR_DIFF(p
,param
),8,
1731 NULL
, 0, CLI_BUFFER_SIZE
,
1734 res
= GETRES(rparam
);
1735 cli
->rap_error
= res
;
1737 DEBUG(1,("NetSessionEnum gave error %d\n", res
));
1742 if (res
== 0 || res
== ERRmoredata
) {
1743 int i
, converter
, count
;
1745 p
= rparam
+ WORDSIZE
;
1746 GETWORD(p
, converter
);
1749 for (i
=0,p
=rdata
;i
<count
;i
++) {
1750 pstring wsname
, username
, clitype_name
;
1751 uint16 num_conns
, num_opens
, num_users
;
1752 unsigned int sess_time
, idle_time
, user_flags
;
1754 GETSTRINGP(p
, wsname
, rdata
, converter
);
1755 GETSTRINGP(p
, username
, rdata
, converter
);
1756 GETWORD(p
, num_conns
);
1757 GETWORD(p
, num_opens
);
1758 GETWORD(p
, num_users
);
1759 GETDWORD(p
, sess_time
);
1760 GETDWORD(p
, idle_time
);
1761 GETDWORD(p
, user_flags
);
1762 GETSTRINGP(p
, clitype_name
, rdata
, converter
);
1764 fn(wsname
, username
, num_conns
, num_opens
, num_users
, sess_time
,
1765 idle_time
, user_flags
, clitype_name
);
1769 DEBUG(4,("NetSessionEnum res=%d\n", res
));
1772 DEBUG(4,("NetSesssionEnum no data returned\n"));
1781 /****************************************************************************
1782 Call a NetSessionGetInfo - get information about other session to an SMB server.
1783 ****************************************************************************/
1785 int cli_NetSessionGetInfo(struct cli_state
*cli
, const char *workstation
, void (*fn
)(const char *, const char *, uint16
, uint16
, uint16
, uint
, uint
, uint
, const char *))
1787 char param
[WORDSIZE
/* api number */
1788 +sizeof(RAP_NetSessionGetInfo_REQ
) /* req string */
1789 +sizeof(RAP_SESSION_INFO_L2
) /* return string */
1790 +RAP_MACHNAME_LEN
/* wksta name */
1791 +WORDSIZE
/* info level */
1792 +WORDSIZE
]; /* buffer size */
1794 char *rparam
= NULL
;
1796 unsigned int rprcnt
, rdrcnt
;
1800 memset(param
, '\0', sizeof(param
));
1801 p
= make_header(param
, RAP_WsessionGetInfo
,
1802 RAP_NetSessionGetInfo_REQ
, RAP_SESSION_INFO_L2
);
1803 PUTSTRING(p
, workstation
, RAP_MACHNAME_LEN
-1);
1804 PUTWORD(p
,2); /* Info level 2 */
1805 PUTWORD(p
,0xFF); /* Return buffer size */
1808 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
1809 NULL
, 0, CLI_BUFFER_SIZE
,
1812 cli
->rap_error
= SVAL(rparam
,0);
1813 if (cli
->rap_error
!= 0) {
1814 DEBUG(1,("NetSessionGetInfo gave error %d\n", cli
->rap_error
));
1819 res
= GETRES(rparam
);
1821 if (res
== 0 || res
== ERRmoredata
) {
1822 int rsize
, converter
;
1823 pstring wsname
, username
, clitype_name
;
1824 uint16 num_conns
, num_opens
, num_users
;
1825 unsigned int sess_time
, idle_time
, user_flags
;
1827 p
= rparam
+ WORDSIZE
;
1828 GETWORD(p
, converter
);
1832 GETSTRINGP(p
, wsname
, rdata
, converter
);
1833 GETSTRINGP(p
, username
, rdata
, converter
);
1834 GETWORD(p
, num_conns
);
1835 GETWORD(p
, num_opens
);
1836 GETWORD(p
, num_users
);
1837 GETDWORD(p
, sess_time
);
1838 GETDWORD(p
, idle_time
);
1839 GETDWORD(p
, user_flags
);
1840 GETSTRINGP(p
, clitype_name
, rdata
, converter
);
1842 fn(wsname
, username
, num_conns
, num_opens
, num_users
, sess_time
,
1843 idle_time
, user_flags
, clitype_name
);
1845 DEBUG(4,("NetSessionGetInfo res=%d\n", res
));
1848 DEBUG(4,("NetSessionGetInfo no data returned\n"));
1857 /****************************************************************************
1858 call a NetSessionDel - close a session to an SMB server
1859 ****************************************************************************/
1860 int cli_NetSessionDel(struct cli_state
*cli
, const char *workstation
)
1862 char param
[WORDSIZE
/* api number */
1863 +sizeof(RAP_NetSessionDel_REQ
) /* req string */
1864 +1 /* no return string */
1865 +RAP_MACHNAME_LEN
/* workstation name */
1866 +WORDSIZE
]; /* reserved (0) */
1868 char *rparam
= NULL
;
1870 unsigned int rprcnt
, rdrcnt
;
1873 memset(param
, '\0', sizeof(param
));
1874 p
= make_header(param
, RAP_WsessionDel
, RAP_NetSessionDel_REQ
, NULL
);
1875 PUTSTRING(p
, workstation
, RAP_MACHNAME_LEN
-1);
1876 PUTWORD(p
,0); /* reserved word of 0 */
1878 param
, PTR_DIFF(p
,param
), 1024, /* Param, length, maxlen */
1879 NULL
, 0, 200, /* data, length, maxlen */
1880 &rparam
, &rprcnt
, /* return params, length */
1881 &rdata
, &rdrcnt
)) /* return data, length */
1883 res
= GETRES(rparam
);
1884 cli
->rap_error
= res
;
1890 DEBUG(4,("NetFileClose2 res=%d\n", res
));
1894 DEBUG(4,("NetFileClose2 failed\n"));
1904 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
))
1906 char param
[WORDSIZE
/* api number */
1907 +sizeof(RAP_NetConnectionEnum_REQ
) /* req string */
1908 +sizeof(RAP_CONNECTION_INFO_L1
) /* return string */
1909 +RAP_MACHNAME_LEN
/* wksta name */
1910 +WORDSIZE
/* info level */
1911 +WORDSIZE
]; /* buffer size */
1913 char *rparam
= NULL
;
1915 unsigned int rprcnt
, rdrcnt
;
1918 memset(param
, '\0', sizeof(param
));
1919 p
= make_header(param
, RAP_WconnectionEnum
,
1920 RAP_NetConnectionEnum_REQ
, RAP_CONNECTION_INFO_L1
);
1921 PUTSTRING(p
, qualifier
, RAP_MACHNAME_LEN
-1);/* Workstation name */
1922 PUTWORD(p
,1); /* Info level 1 */
1923 PUTWORD(p
,0xFFE0); /* Return buffer size */
1926 param
, PTR_DIFF(p
,param
),PTR_DIFF(p
,param
),
1927 NULL
, 0, CLI_BUFFER_SIZE
,
1930 res
= GETRES(rparam
);
1931 cli
->rap_error
= res
;
1933 DEBUG(1,("NetConnectionEnum gave error %d\n", res
));
1937 if (res
== 0 || res
== ERRmoredata
) {
1938 int i
, converter
, count
;
1940 p
= rparam
+ WORDSIZE
;
1941 GETWORD(p
, converter
);
1944 for (i
=0,p
=rdata
;i
<count
;i
++) {
1945 pstring netname
, username
;
1946 uint16 conn_id
, conn_type
, num_opens
, num_users
;
1947 unsigned int conn_time
;
1950 GETWORD(p
,conn_type
);
1951 GETWORD(p
,num_opens
);
1952 GETWORD(p
,num_users
);
1953 GETDWORD(p
,conn_time
);
1954 GETSTRINGP(p
, username
, rdata
, converter
);
1955 GETSTRINGP(p
, netname
, rdata
, converter
);
1957 fn(conn_id
, conn_type
, num_opens
, num_users
, conn_time
,
1962 DEBUG(4,("NetConnectionEnum res=%d\n", res
));
1965 DEBUG(4,("NetConnectionEnum no data returned\n"));