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"));