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
/*****************************************************/
84
#define PUTBYTE(p,b) do {SCVAL(p,0,b); p++;} while(0)
85
#define GETBYTE(p,b) do {b = CVAL(p,0); p++;} while(0)
86
#define PUTWORD(p,w) do {SSVAL(p,0,w); p += WORDSIZE;} while(0)
87
#define GETWORD(p,w) do {w = SVAL(p,0); p += WORDSIZE;} while(0)
88
#define PUTDWORD(p,d) do {SIVAL(p,0,d); p += DWORDSIZE;} while(0)
89
#define GETDWORD(p,d) do {d = IVAL(p,0); p += DWORDSIZE;} while(0)
90
#define GETRES(p) p ? SVAL(p,0) : -1
91
/* put string s at p with max len n and increment p past string */
92
#define PUTSTRING(p,s,n) do {\
93
push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\
94
p = skip_string(p,1);\
96
/* put string s and p, using fixed len l, and increment p by l */
97
#define PUTSTRINGF(p,s,l) do {\
98
push_ascii(p,s?s:"",l,STR_TERMINATE);\
101
/* put string pointer at p, supplying offset o from rdata r, store */
102
/* dword offset at p, increment p by 4 and o by length of s. This */
103
/* means on the first call, you must calc the offset yourself! */
104
#define PUTSTRINGP(p,s,r,o) do {\
106
push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\
109
} else PUTDWORD(p,0);\
111
/* get asciiz string s from p, increment p past string */
112
#define GETSTRING(p,s) do {\
113
pull_ascii_pstring(s,p);\
114
p = skip_string(p,1);\
116
/* get fixed length l string s from p, increment p by l */
117
#define GETSTRINGF(p,s,l) do {\
118
pull_ascii_pstring(s,p);\
121
/* get string s from offset (obtained at p) from rdata r - converter c */
122
#define GETSTRINGP(p,s,r,c) do {\
125
off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */ \
126
pull_ascii_pstring(s, off?(r+off-c):"");\
129
static char *make_header(char *param, uint16 apinum, const char *reqfmt, const char *datafmt)
131
PUTWORD(param,apinum);
133
PUTSTRING(param,reqfmt,0);
138
PUTSTRING(param,datafmt,0);
146
/****************************************************************************
147
call a NetGroupDelete - delete user group from remote server
148
****************************************************************************/
149
int cli_NetGroupDelete(struct cli_state *cli, const char *group_name )
154
unsigned int rdrcnt,rprcnt;
156
char param[WORDSIZE /* api number */
157
+sizeof(RAP_NetGroupDel_REQ) /* parm string */
158
+1 /* no ret string */
159
+RAP_GROUPNAME_LEN /* group to del */
160
+WORDSIZE]; /* reserved word */
162
/* now send a SMBtrans command with api GroupDel */
163
p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL);
164
PUTSTRING(p, group_name, RAP_GROUPNAME_LEN);
165
PUTWORD(p,0); /* reserved word MBZ on input */
168
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
169
NULL, 0, 200, /* data, length, maxlen */
170
&rparam, &rprcnt, /* return params, length */
171
&rdata, &rdrcnt)) /* return data, length */
173
res = GETRES(rparam);
178
else if ((res == 5) || (res == 65)) {
179
DEBUG(1, ("Access Denied\n"));
181
else if (res == 2220) {
182
DEBUG (1, ("Group does not exist\n"));
185
DEBUG(4,("NetGroupDelete res=%d\n", res));
189
DEBUG(4,("NetGroupDelete failed\n"));
198
/****************************************************************************
199
call a NetGroupAdd - add user group to remote server
200
****************************************************************************/
201
int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo )
206
unsigned int rdrcnt,rprcnt;
208
char param[WORDSIZE /* api number */
209
+sizeof(RAP_NetGroupAdd_REQ) /* req string */
210
+sizeof(RAP_GROUP_INFO_L1) /* return string */
211
+WORDSIZE /* info level */
212
+WORDSIZE]; /* reserved word */
214
/* offset into data of free format strings. Will be updated */
215
/* by PUTSTRINGP macro and end up with total data length. */
216
int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE;
221
data_size = MAX(soffset + strlen(grinfo->comment) + 1, 1024);
223
data = SMB_MALLOC_ARRAY(char, data_size);
225
DEBUG (1, ("Malloc fail\n"));
229
/* now send a SMBtrans command with api WGroupAdd */
231
p = make_header(param, RAP_WGroupAdd,
232
RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1);
233
PUTWORD(p, 1); /* info level */
234
PUTWORD(p, 0); /* reserved word 0 */
237
PUTSTRINGF(p, grinfo->group_name, RAP_GROUPNAME_LEN);
238
PUTBYTE(p, 0); /* pad byte 0 */
239
PUTSTRINGP(p, grinfo->comment, data, soffset);
242
param, sizeof(param), 1024, /* Param, length, maxlen */
243
data, soffset, sizeof(data), /* data, length, maxlen */
244
&rparam, &rprcnt, /* return params, length */
245
&rdata, &rdrcnt)) /* return data, length */
247
res = GETRES(rparam);
251
} else if ((res == 5) || (res == 65)) {
252
DEBUG(1, ("Access Denied\n"));
254
else if (res == 2223) {
255
DEBUG (1, ("Group already exists\n"));
258
DEBUG(4,("NetGroupAdd res=%d\n", res));
262
DEBUG(4,("NetGroupAdd failed\n"));
272
/****************************************************************************
273
call a NetGroupEnum - try and list user groups on a different host
274
****************************************************************************/
275
int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state)
277
char param[WORDSIZE /* api number */
278
+sizeof(RAP_NetGroupEnum_REQ) /* parm string */
279
+sizeof(RAP_GROUP_INFO_L1) /* return string */
280
+WORDSIZE /* info level */
281
+WORDSIZE]; /* buffer size */
285
unsigned int rprcnt, rdrcnt;
289
memset(param, '\0', sizeof(param));
290
p = make_header(param, RAP_WGroupEnum,
291
RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L1);
292
PUTWORD(p,1); /* Info level 1 */ /* add level 0 */
293
PUTWORD(p,0xFFE0); /* Return buffer size */
296
param, PTR_DIFF(p,param),8,
297
NULL, 0, 0xFFE0 /* data area size */,
300
res = GETRES(rparam);
301
cli->rap_error = res;
302
if(cli->rap_error == 234)
303
DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
304
else if (cli->rap_error != 0) {
305
DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
310
if (res == 0 || res == ERRmoredata) {
311
int i, converter, count;
313
p = rparam + WORDSIZE; /* skip result */
314
GETWORD(p, converter);
317
for (i=0,p=rdata;i<count;i++) {
319
char groupname[RAP_GROUPNAME_LEN];
321
GETSTRINGF(p, groupname, RAP_GROUPNAME_LEN);
323
GETSTRINGP(p, comment, rdata, converter);
325
fn(groupname, comment, cli);
328
DEBUG(4,("NetGroupEnum res=%d\n", res));
331
DEBUG(4,("NetGroupEnum no data returned\n"));
340
int cli_RNetGroupEnum0(struct cli_state *cli,
341
void (*fn)(const char *, void *),
344
char param[WORDSIZE /* api number */
345
+sizeof(RAP_NetGroupEnum_REQ) /* parm string */
346
+sizeof(RAP_GROUP_INFO_L0) /* return string */
347
+WORDSIZE /* info level */
348
+WORDSIZE]; /* buffer size */
352
unsigned int rprcnt, rdrcnt;
356
memset(param, '\0', sizeof(param));
357
p = make_header(param, RAP_WGroupEnum,
358
RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L0);
359
PUTWORD(p,0); /* Info level 0 */ /* Hmmm. I *very* much suspect this
360
is the resume count, at least
361
that's what smbd believes... */
362
PUTWORD(p,0xFFE0); /* Return buffer size */
365
param, PTR_DIFF(p,param),8,
366
NULL, 0, 0xFFE0 /* data area size */,
369
res = GETRES(rparam);
370
cli->rap_error = res;
371
if(cli->rap_error == 234)
372
DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
373
else if (cli->rap_error != 0) {
374
DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
379
if (res == 0 || res == ERRmoredata) {
382
p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
385
for (i=0,p=rdata;i<count;i++) {
386
char groupname[RAP_GROUPNAME_LEN];
387
GETSTRINGF(p, groupname, RAP_GROUPNAME_LEN);
391
DEBUG(4,("NetGroupEnum res=%d\n", res));
394
DEBUG(4,("NetGroupEnum no data returned\n"));
403
int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const char *user_name)
408
unsigned int rdrcnt,rprcnt;
410
char param[WORDSIZE /* api number */
411
+sizeof(RAP_NetGroupDelUser_REQ) /* parm string */
412
+1 /* no ret string */
413
+RAP_GROUPNAME_LEN /* group name */
414
+RAP_USERNAME_LEN]; /* user to del */
416
/* now send a SMBtrans command with api GroupMemberAdd */
417
p = make_header(param, RAP_WGroupDelUser, RAP_NetGroupDelUser_REQ, NULL);
418
PUTSTRING(p,group_name,RAP_GROUPNAME_LEN);
419
PUTSTRING(p,user_name,RAP_USERNAME_LEN);
422
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
423
NULL, 0, 200, /* data, length, maxlen */
424
&rparam, &rprcnt, /* return params, length */
425
&rdata, &rdrcnt)) /* return data, length */
427
res = GETRES(rparam);
434
DEBUG(1, ("Access Denied\n"));
437
DEBUG(1, ("Not supported by server\n"));
440
DEBUG(1, ("Group does not exist\n"));
443
DEBUG(1, ("User does not exist\n"));
446
DEBUG(1, ("User is not in group\n"));
449
DEBUG(4,("NetGroupDelUser res=%d\n", res));
453
DEBUG(4,("NetGroupDelUser failed\n"));
462
int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const char *user_name)
467
unsigned int rdrcnt,rprcnt;
469
char param[WORDSIZE /* api number */
470
+sizeof(RAP_NetGroupAddUser_REQ) /* parm string */
471
+1 /* no ret string */
472
+RAP_GROUPNAME_LEN /* group name */
473
+RAP_USERNAME_LEN]; /* user to add */
475
/* now send a SMBtrans command with api GroupMemberAdd */
476
p = make_header(param, RAP_WGroupAddUser, RAP_NetGroupAddUser_REQ, NULL);
477
PUTSTRING(p,group_name,RAP_GROUPNAME_LEN);
478
PUTSTRING(p,user_name,RAP_USERNAME_LEN);
481
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
482
NULL, 0, 200, /* data, length, maxlen */
483
&rparam, &rprcnt, /* return params, length */
484
&rdata, &rdrcnt)) /* return data, length */
486
res = GETRES(rparam);
493
DEBUG(1, ("Access Denied\n"));
496
DEBUG(1, ("Not supported by server\n"));
499
DEBUG(1, ("Group does not exist\n"));
502
DEBUG(1, ("User does not exist\n"));
505
DEBUG(4,("NetGroupAddUser res=%d\n", res));
509
DEBUG(4,("NetGroupAddUser failed\n"));
519
int cli_NetGroupGetUsers(struct cli_state * cli, const char *group_name, void (*fn)(const char *, void *), void *state )
524
unsigned int rdrcnt,rprcnt;
526
char param[WORDSIZE /* api number */
527
+sizeof(RAP_NetGroupGetUsers_REQ)/* parm string */
528
+sizeof(RAP_GROUP_USERS_INFO_0) /* return string */
529
+RAP_GROUPNAME_LEN /* group name */
530
+WORDSIZE /* info level */
531
+WORDSIZE]; /* buffer size */
533
/* now send a SMBtrans command with api GroupGetUsers */
534
p = make_header(param, RAP_WGroupGetUsers,
535
RAP_NetGroupGetUsers_REQ, RAP_GROUP_USERS_INFO_0);
536
PUTSTRING(p,group_name,RAP_GROUPNAME_LEN-1);
537
PUTWORD(p,0); /* info level 0 */
538
PUTWORD(p,0xFFE0); /* return buffer size */
541
param, PTR_DIFF(p,param),PTR_DIFF(p,param),
542
NULL, 0, CLI_BUFFER_SIZE,
545
res = GETRES(rparam);
546
cli->rap_error = res;
548
DEBUG(1,("NetGroupGetUsers gave error %d\n", res));
552
if (res == 0 || res == ERRmoredata) {
555
p = rparam + WORDSIZE + WORDSIZE;
558
for (i=0,p=rdata; i<count; i++) {
559
GETSTRINGF(p, username, RAP_USERNAME_LEN);
563
DEBUG(4,("NetGroupGetUsers res=%d\n", res));
566
DEBUG(4,("NetGroupGetUsers no data returned\n"));
573
int cli_NetUserGetGroups(struct cli_state * cli, const char *user_name, void (*fn)(const char *, void *), void *state )
578
unsigned int rdrcnt,rprcnt;
580
char param[WORDSIZE /* api number */
581
+sizeof(RAP_NetUserGetGroups_REQ)/* parm string */
582
+sizeof(RAP_GROUP_USERS_INFO_0) /* return string */
583
+RAP_USERNAME_LEN /* user name */
584
+WORDSIZE /* info level */
585
+WORDSIZE]; /* buffer size */
587
/* now send a SMBtrans command with api GroupGetUsers */
588
p = make_header(param, RAP_WUserGetGroups,
589
RAP_NetUserGetGroups_REQ, RAP_GROUP_USERS_INFO_0);
590
PUTSTRING(p,user_name,RAP_USERNAME_LEN-1);
591
PUTWORD(p,0); /* info level 0 */
592
PUTWORD(p,0xFFE0); /* return buffer size */
595
param, PTR_DIFF(p,param),PTR_DIFF(p,param),
596
NULL, 0, CLI_BUFFER_SIZE,
599
res = GETRES(rparam);
600
cli->rap_error = res;
602
DEBUG(1,("NetUserGetGroups gave error %d\n", res));
606
if (res == 0 || res == ERRmoredata) {
609
p = rparam + WORDSIZE + WORDSIZE;
612
for (i=0,p=rdata; i<count; i++) {
613
GETSTRINGF(p, groupname, RAP_USERNAME_LEN);
614
fn(groupname, state);
617
DEBUG(4,("NetUserGetGroups res=%d\n", res));
620
DEBUG(4,("NetUserGetGroups no data returned\n"));
628
/****************************************************************************
629
call a NetUserDelete - delete user from remote server
630
****************************************************************************/
631
int cli_NetUserDelete(struct cli_state *cli, const char * user_name )
636
unsigned int rdrcnt,rprcnt;
638
char param[WORDSIZE /* api number */
639
+sizeof(RAP_NetGroupDel_REQ) /* parm string */
640
+1 /* no ret string */
641
+RAP_USERNAME_LEN /* user to del */
642
+WORDSIZE]; /* reserved word */
644
/* now send a SMBtrans command with api UserDel */
645
p = make_header(param, RAP_WUserDel, RAP_NetGroupDel_REQ, NULL);
646
PUTSTRING(p, user_name, RAP_USERNAME_LEN);
647
PUTWORD(p,0); /* reserved word MBZ on input */
650
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
651
NULL, 0, 200, /* data, length, maxlen */
652
&rparam, &rprcnt, /* return params, length */
653
&rdata, &rdrcnt)) /* return data, length */
655
res = GETRES(rparam);
660
else if ((res == 5) || (res == 65)) {
661
DEBUG(1, ("Access Denied\n"));
663
else if (res == 2221) {
664
DEBUG (1, ("User does not exist\n"));
667
DEBUG(4,("NetUserDelete res=%d\n", res));
671
DEBUG(4,("NetUserDelete failed\n"));
680
/****************************************************************************
681
call a NetUserAdd - add user to remote server
682
****************************************************************************/
683
int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo )
691
unsigned int rdrcnt,rprcnt;
693
char param[WORDSIZE /* api number */
694
+sizeof(RAP_NetUserAdd2_REQ) /* req string */
695
+sizeof(RAP_USER_INFO_L1) /* data string */
696
+WORDSIZE /* info level */
697
+WORDSIZE /* buffer length */
698
+WORDSIZE]; /* reserved */
701
/* offset into data of free format strings. Will be updated */
702
/* by PUTSTRINGP macro and end up with total data length. */
703
int soffset=RAP_USERNAME_LEN+1 /* user name + pad */
704
+ RAP_UPASSWD_LEN /* password */
705
+ DWORDSIZE /* password age */
706
+ WORDSIZE /* privilege */
707
+ DWORDSIZE /* home dir ptr */
708
+ DWORDSIZE /* comment ptr */
709
+ WORDSIZE /* flags */
710
+ DWORDSIZE; /* login script ptr*/
712
/* now send a SMBtrans command with api NetUserAdd */
713
p = make_header(param, RAP_WUserAdd2,
714
RAP_NetUserAdd2_REQ, RAP_USER_INFO_L1);
715
PUTWORD(p, 1); /* info level */
717
PUTWORD(p, 0); /* pwencrypt */
718
if(userinfo->passwrd)
719
PUTWORD(p,MIN(strlen(userinfo->passwrd), RAP_UPASSWD_LEN));
721
PUTWORD(p, 0); /* password length */
724
memset(data, '\0', soffset);
726
PUTSTRINGF(p, userinfo->user_name, RAP_USERNAME_LEN);
727
PUTBYTE(p, 0); /* pad byte 0 */
728
PUTSTRINGF(p, userinfo->passwrd, RAP_UPASSWD_LEN);
729
PUTDWORD(p, 0); /* pw age - n.a. on user add */
730
PUTWORD(p, userinfo->priv);
731
PUTSTRINGP(p, userinfo->home_dir, data, soffset);
732
PUTSTRINGP(p, userinfo->comment, data, soffset);
733
PUTWORD(p, userinfo->userflags);
734
PUTSTRINGP(p, userinfo->logon_script, data, soffset);
737
param, sizeof(param), 1024, /* Param, length, maxlen */
738
data, soffset, sizeof(data), /* data, length, maxlen */
739
&rparam, &rprcnt, /* return params, length */
740
&rdata, &rdrcnt)) /* return data, length */
742
res = GETRES(rparam);
747
else if ((res == 5) || (res == 65)) {
748
DEBUG(1, ("Access Denied\n"));
750
else if (res == 2224) {
751
DEBUG (1, ("User already exists\n"));
754
DEBUG(4,("NetUserAdd res=%d\n", res));
758
DEBUG(4,("NetUserAdd failed\n"));
767
/****************************************************************************
768
call a NetUserEnum - try and list users on a different host
769
****************************************************************************/
770
int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char *, const char *, const char *, void *), void *state)
772
char param[WORDSIZE /* api number */
773
+sizeof(RAP_NetUserEnum_REQ) /* parm string */
774
+sizeof(RAP_USER_INFO_L1) /* return string */
775
+WORDSIZE /* info level */
776
+WORDSIZE]; /* buffer size */
780
unsigned int rprcnt, rdrcnt;
784
memset(param, '\0', sizeof(param));
785
p = make_header(param, RAP_WUserEnum,
786
RAP_NetUserEnum_REQ, RAP_USER_INFO_L1);
787
PUTWORD(p,1); /* Info level 1 */
788
PUTWORD(p,0xFF00); /* Return buffer size */
790
/* BB Fix handling of large numbers of users to be returned */
792
param, PTR_DIFF(p,param),8,
793
NULL, 0, CLI_BUFFER_SIZE,
796
res = GETRES(rparam);
797
cli->rap_error = res;
798
if (cli->rap_error != 0) {
799
DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
803
if (res == 0 || res == ERRmoredata) {
804
int i, converter, count;
805
char username[RAP_USERNAME_LEN];
806
char userpw[RAP_UPASSWD_LEN];
807
pstring comment, homedir, logonscript;
809
p = rparam + WORDSIZE; /* skip result */
810
GETWORD(p, converter);
813
for (i=0,p=rdata;i<count;i++) {
814
GETSTRINGF(p, username, RAP_USERNAME_LEN);
816
GETSTRINGF(p, userpw, RAP_UPASSWD_LEN);
817
p += DWORDSIZE; /* skip password age */
818
p += WORDSIZE; /* skip priv: 0=guest, 1=user, 2=admin */
819
GETSTRINGP(p, homedir, rdata, converter);
820
GETSTRINGP(p, comment, rdata, converter);
821
p += WORDSIZE; /* skip flags */
822
GETSTRINGP(p, logonscript, rdata, converter);
824
fn(username, comment, homedir, logonscript, cli);
827
DEBUG(4,("NetUserEnum res=%d\n", res));
830
DEBUG(4,("NetUserEnum no data returned\n"));
839
int cli_RNetUserEnum0(struct cli_state *cli,
840
void (*fn)(const char *, void *),
843
char param[WORDSIZE /* api number */
844
+sizeof(RAP_NetUserEnum_REQ) /* parm string */
845
+sizeof(RAP_USER_INFO_L0) /* return string */
846
+WORDSIZE /* info level */
847
+WORDSIZE]; /* buffer size */
851
unsigned int rprcnt, rdrcnt;
855
memset(param, '\0', sizeof(param));
856
p = make_header(param, RAP_WUserEnum,
857
RAP_NetUserEnum_REQ, RAP_USER_INFO_L0);
858
PUTWORD(p,0); /* Info level 1 */
859
PUTWORD(p,0xFF00); /* Return buffer size */
861
/* BB Fix handling of large numbers of users to be returned */
863
param, PTR_DIFF(p,param),8,
864
NULL, 0, CLI_BUFFER_SIZE,
867
res = GETRES(rparam);
868
cli->rap_error = res;
869
if (cli->rap_error != 0) {
870
DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
874
if (res == 0 || res == ERRmoredata) {
876
char username[RAP_USERNAME_LEN];
878
p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
881
for (i=0,p=rdata;i<count;i++) {
882
GETSTRINGF(p, username, RAP_USERNAME_LEN);
886
DEBUG(4,("NetUserEnum res=%d\n", res));
889
DEBUG(4,("NetUserEnum no data returned\n"));
898
/****************************************************************************
899
call a NetFileClose2 - close open file on another session to server
900
****************************************************************************/
901
int cli_NetFileClose(struct cli_state *cli, uint32 file_id )
906
unsigned int rdrcnt,rprcnt;
907
char param[WORDSIZE /* api number */
908
+sizeof(RAP_WFileClose2_REQ) /* req string */
909
+1 /* no ret string */
910
+DWORDSIZE]; /* file ID */
913
/* now send a SMBtrans command with api RNetShareEnum */
914
p = make_header(param, RAP_WFileClose2, RAP_WFileClose2_REQ, NULL);
915
PUTDWORD(p, file_id);
918
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
919
NULL, 0, 200, /* data, length, maxlen */
920
&rparam, &rprcnt, /* return params, length */
921
&rdata, &rdrcnt)) /* return data, length */
923
res = GETRES(rparam);
927
} else if (res == 2314){
928
DEBUG(1, ("NetFileClose2 - attempt to close non-existant file open instance\n"));
930
DEBUG(4,("NetFileClose2 res=%d\n", res));
934
DEBUG(4,("NetFileClose2 failed\n"));
943
/****************************************************************************
944
call a NetFileGetInfo - get information about server file opened from other
946
****************************************************************************/
947
int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const char *, const char *, uint16, uint16, uint32))
952
unsigned int rdrcnt,rprcnt;
954
char param[WORDSIZE /* api number */
955
+sizeof(RAP_WFileGetInfo2_REQ) /* req string */
956
+sizeof(RAP_FILE_INFO_L3) /* return string */
957
+DWORDSIZE /* file ID */
958
+WORDSIZE /* info level */
959
+WORDSIZE]; /* buffer size */
961
/* now send a SMBtrans command with api RNetShareEnum */
962
p = make_header(param, RAP_WFileGetInfo2,
963
RAP_WFileGetInfo2_REQ, RAP_FILE_INFO_L3);
964
PUTDWORD(p, file_id);
965
PUTWORD(p, 3); /* info level */
966
PUTWORD(p, 0x1000); /* buffer size */
968
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
969
NULL, 0, 0x1000, /* data, length, maxlen */
970
&rparam, &rprcnt, /* return params, length */
971
&rdata, &rdrcnt)) /* return data, length */
973
res = GETRES(rparam);
974
if (res == 0 || res == ERRmoredata) {
975
int converter,id, perms, locks;
976
pstring fpath, fuser;
978
p = rparam + WORDSIZE; /* skip result */
979
GETWORD(p, converter);
985
GETSTRINGP(p, fpath, rdata, converter);
986
GETSTRINGP(p, fuser, rdata, converter);
988
fn(fpath, fuser, perms, locks, id);
990
DEBUG(4,("NetFileGetInfo2 res=%d\n", res));
994
DEBUG(4,("NetFileGetInfo2 failed\n"));
1003
/****************************************************************************
1004
* Call a NetFileEnum2 - list open files on an SMB server
1006
* PURPOSE: Remotes a NetFileEnum API call to the current server or target
1007
* server listing the files open via the network (and their
1008
* corresponding open instance ids)
1010
* Dependencies: none
1013
* cli - pointer to cli_state structure
1014
* user - if present, return only files opened by this remote user
1015
* base_path - if present, return only files opened below this
1017
* fn - display function to invoke for each entry in the result
1024
****************************************************************************/
1025
int cli_NetFileEnum(struct cli_state *cli, char * user, char * base_path, void (*fn)(const char *, const char *, uint16, uint16, uint32))
1027
char *rparam = NULL;
1030
unsigned int rdrcnt,rprcnt;
1031
char param[WORDSIZE /* api number */
1032
+sizeof(RAP_WFileEnum2_REQ) /* req string */
1033
+sizeof(RAP_FILE_INFO_L3) /* return string */
1034
+256 /* base path (opt) */
1035
+RAP_USERNAME_LEN /* user name (opt) */
1036
+WORDSIZE /* info level */
1037
+WORDSIZE /* buffer size */
1038
+DWORDSIZE /* resume key ? */
1039
+DWORDSIZE]; /* resume key ? */
1042
/* now send a SMBtrans command with api RNetShareEnum */
1043
p = make_header(param, RAP_WFileEnum2,
1044
RAP_WFileEnum2_REQ, RAP_FILE_INFO_L3);
1046
PUTSTRING(p, base_path, 256);
1047
PUTSTRING(p, user, RAP_USERNAME_LEN);
1048
PUTWORD(p, 3); /* info level */
1049
PUTWORD(p, 0xFF00); /* buffer size */
1050
PUTDWORD(p, 0); /* zero out the resume key */
1051
PUTDWORD(p, 0); /* or is this one the resume key? */
1054
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
1055
NULL, 0, 0xFF00, /* data, length, maxlen */
1056
&rparam, &rprcnt, /* return params, length */
1057
&rdata, &rdrcnt)) /* return data, length */
1059
int res = GETRES(rparam);
1061
if (res == 0 || res == ERRmoredata) {
1064
p = rparam + WORDSIZE; /* skip result */
1065
GETWORD(p, converter);
1069
for (i=0; i<count; i++) {
1070
int id, perms, locks;
1071
pstring fpath, fuser;
1076
GETSTRINGP(p, fpath, rdata, converter);
1077
GETSTRINGP(p, fuser, rdata, converter);
1079
fn(fpath, fuser, perms, locks, id);
1080
} /* BB fix ERRmoredata case to send resume request */
1082
DEBUG(4,("NetFileEnum2 res=%d\n", res));
1085
DEBUG(4,("NetFileEnum2 failed\n"));
1094
/****************************************************************************
1095
call a NetShareAdd - share/export directory on remote server
1096
****************************************************************************/
1097
int cli_NetShareAdd(struct cli_state *cli, RAP_SHARE_INFO_2 * sinfo )
1099
char *rparam = NULL;
1102
unsigned int rdrcnt,rprcnt;
1104
char param[WORDSIZE /* api number */
1105
+sizeof(RAP_WShareAdd_REQ) /* req string */
1106
+sizeof(RAP_SHARE_INFO_L2) /* return string */
1107
+WORDSIZE /* info level */
1108
+WORDSIZE]; /* reserved word */
1110
/* offset to free format string section following fixed length data. */
1111
/* will be updated by PUTSTRINGP macro and will end up with total len */
1112
int soffset = RAP_SHARENAME_LEN + 1 /* share name + pad */
1113
+ WORDSIZE /* share type */
1114
+ DWORDSIZE /* comment pointer */
1115
+ WORDSIZE /* permissions */
1116
+ WORDSIZE /* max users */
1117
+ WORDSIZE /* active users */
1118
+ DWORDSIZE /* share path */
1119
+ RAP_SPASSWD_LEN + 1; /* share password + pad */
1121
memset(param,'\0',sizeof(param));
1122
/* now send a SMBtrans command with api RNetShareAdd */
1123
p = make_header(param, RAP_WshareAdd,
1124
RAP_WShareAdd_REQ, RAP_SHARE_INFO_L2);
1125
PUTWORD(p, 2); /* info level */
1126
PUTWORD(p, 0); /* reserved word 0 */
1129
PUTSTRINGF(p, sinfo->share_name, RAP_SHARENAME_LEN);
1130
PUTBYTE(p, 0); /* pad byte 0 */
1132
PUTWORD(p, sinfo->share_type);
1133
PUTSTRINGP(p, sinfo->comment, data, soffset);
1134
PUTWORD(p, sinfo->perms);
1135
PUTWORD(p, sinfo->maximum_users);
1136
PUTWORD(p, sinfo->active_users);
1137
PUTSTRINGP(p, sinfo->path, data, soffset);
1138
PUTSTRINGF(p, sinfo->password, RAP_SPASSWD_LEN);
1139
SCVAL(p,-1,0x0A); /* required 0x0A at end of password */
1142
param, sizeof(param), 1024, /* Param, length, maxlen */
1143
data, soffset, sizeof(data), /* data, length, maxlen */
1144
&rparam, &rprcnt, /* return params, length */
1145
&rdata, &rdrcnt)) /* return data, length */
1147
res = rparam? SVAL(rparam,0) : -1;
1153
DEBUG(4,("NetShareAdd res=%d\n", res));
1157
DEBUG(4,("NetShareAdd failed\n"));
1165
/****************************************************************************
1166
call a NetShareDelete - unshare exported directory on remote server
1167
****************************************************************************/
1168
int cli_NetShareDelete(struct cli_state *cli, const char * share_name )
1170
char *rparam = NULL;
1173
unsigned int rdrcnt,rprcnt;
1175
char param[WORDSIZE /* api number */
1176
+sizeof(RAP_WShareDel_REQ) /* req string */
1177
+1 /* no ret string */
1178
+RAP_SHARENAME_LEN /* share to del */
1179
+WORDSIZE]; /* reserved word */
1182
/* now send a SMBtrans command with api RNetShareDelete */
1183
p = make_header(param, RAP_WshareDel, RAP_WShareDel_REQ, NULL);
1184
PUTSTRING(p,share_name,RAP_SHARENAME_LEN);
1185
PUTWORD(p,0); /* reserved word MBZ on input */
1188
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
1189
NULL, 0, 200, /* data, length, maxlen */
1190
&rparam, &rprcnt, /* return params, length */
1191
&rdata, &rdrcnt)) /* return data, length */
1193
res = GETRES(rparam);
1199
DEBUG(4,("NetShareDelete res=%d\n", res));
1203
DEBUG(4,("NetShareDelete failed\n"));
1211
/*************************************************************************
1213
* Function Name: cli_get_pdc_name
1215
* PURPOSE: Remotes a NetServerEnum API call to the current server
1216
* requesting the name of a server matching the server
1217
* type of SV_TYPE_DOMAIN_CTRL (PDC).
1219
* Dependencies: none
1222
* cli - pointer to cli_state structure
1223
* workgroup - pointer to string containing name of domain
1224
* pdc_name - pointer to string that will contain PDC name
1225
* on successful return
1231
************************************************************************/
1232
BOOL cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name)
1234
char *rparam = NULL;
1236
unsigned int rdrcnt,rprcnt;
1238
char param[WORDSIZE /* api number */
1239
+sizeof(RAP_NetServerEnum2_REQ) /* req string */
1240
+sizeof(RAP_SERVER_INFO_L1) /* return string */
1241
+WORDSIZE /* info level */
1242
+WORDSIZE /* buffer size */
1243
+DWORDSIZE /* server type */
1244
+RAP_MACHNAME_LEN]; /* workgroup */
1249
/* send a SMBtrans command with api NetServerEnum */
1250
p = make_header(param, RAP_NetServerEnum2,
1251
RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L1);
1252
PUTWORD(p, 1); /* info level */
1253
PUTWORD(p, CLI_BUFFER_SIZE);
1254
PUTDWORD(p, SV_TYPE_DOMAIN_CTRL);
1255
PUTSTRING(p, workgroup, RAP_MACHNAME_LEN);
1258
param, PTR_DIFF(p,param), 8, /* params, length, max */
1259
NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
1260
&rparam, &rprcnt, /* return params, return size */
1261
&rdata, &rdrcnt /* return data, return size */
1263
cli->rap_error = GETRES(rparam);
1266
* We only really care to copy a name if the
1267
* API succeeded and we got back a name.
1269
if (cli->rap_error == 0) {
1270
p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
1275
GETSTRING(p, pdc_name);
1278
DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. "
1279
"Error was : %s.\n", cli->desthost, cli_errstr(cli) ));
1290
/*************************************************************************
1292
* Function Name: cli_get_server_domain
1294
* PURPOSE: Remotes a NetWkstaGetInfo API call to the current server
1295
* requesting wksta_info_10 level information to determine
1296
* the domain the server belongs to. On success, this
1297
* routine sets the server_domain field in the cli_state structure
1298
* to the server's domain name.
1300
* Dependencies: none
1303
* cli - pointer to cli_state structure
1309
* Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
1311
************************************************************************/
1312
BOOL cli_get_server_domain(struct cli_state *cli)
1314
char *rparam = NULL;
1316
unsigned int rdrcnt,rprcnt;
1318
char param[WORDSIZE /* api number */
1319
+sizeof(RAP_WWkstaGetInfo_REQ) /* req string */
1320
+sizeof(RAP_WKSTA_INFO_L10) /* return string */
1321
+WORDSIZE /* info level */
1322
+WORDSIZE]; /* buffer size */
1325
/* send a SMBtrans command with api NetWkstaGetInfo */
1326
p = make_header(param, RAP_WWkstaGetInfo,
1327
RAP_WWkstaGetInfo_REQ, RAP_WKSTA_INFO_L10);
1328
PUTWORD(p, 10); /* info level */
1329
PUTWORD(p, CLI_BUFFER_SIZE);
1331
if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */
1332
NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
1333
&rparam, &rprcnt, /* return params, return size */
1334
&rdata, &rdrcnt)) { /* return data, return size */
1335
res = GETRES(rparam);
1341
p = rparam + WORDSIZE;
1342
GETWORD(p, converter);
1344
p = rdata + DWORDSIZE + DWORDSIZE; /* skip computer & user names */
1345
GETSTRINGP(p, cli->server_domain, rdata, converter);
1356
/*************************************************************************
1358
* Function Name: cli_get_server_type
1360
* PURPOSE: Remotes a NetServerGetInfo API call to the current server
1361
* requesting server_info_1 level information to retrieve
1364
* Dependencies: none
1367
* cli - pointer to cli_state structure
1368
* pstype - pointer to uint32 to contain returned server type
1374
* Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
1376
************************************************************************/
1377
BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype)
1379
char *rparam = NULL;
1381
unsigned int rdrcnt,rprcnt;
1383
char param[WORDSIZE /* api number */
1384
+sizeof(RAP_WserverGetInfo_REQ) /* req string */
1385
+sizeof(RAP_SERVER_INFO_L1) /* return string */
1386
+WORDSIZE /* info level */
1387
+WORDSIZE]; /* buffer size */
1390
/* send a SMBtrans command with api NetServerGetInfo */
1391
p = make_header(param, RAP_WserverGetInfo,
1392
RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1);
1393
PUTWORD(p, 1); /* info level */
1394
PUTWORD(p, CLI_BUFFER_SIZE);
1397
param, PTR_DIFF(p,param), 8, /* params, length, max */
1398
NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
1399
&rparam, &rprcnt, /* return params, return size */
1400
&rdata, &rdrcnt /* return data, return size */
1403
res = GETRES(rparam);
1405
if (res == 0 || res == ERRmoredata) {
1407
*pstype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
1414
return(res == 0 || res == ERRmoredata);
1418
/*************************************************************************
1420
* Function Name: cli_ns_check_server_type
1422
* PURPOSE: Remotes a NetServerEnum2 API call to the current server
1423
* requesting server_info_0 level information of machines
1424
* matching the given server type. If the returned server
1425
* list contains the machine name contained in cli->desthost
1426
* then we conclude the server type checks out. This routine
1427
* is useful to retrieve list of server's of a certain
1428
* type when all you have is a null session connection and
1429
* can't remote API calls such as NetWkstaGetInfo or
1432
* Dependencies: none
1435
* cli - pointer to cli_state structure
1436
* workgroup - pointer to string containing domain
1437
* stype - server type
1443
************************************************************************/
1444
BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype)
1446
char *rparam = NULL;
1448
unsigned int rdrcnt,rprcnt;
1450
char param[WORDSIZE /* api number */
1451
+sizeof(RAP_NetServerEnum2_REQ) /* req string */
1452
+sizeof(RAP_SERVER_INFO_L0) /* return string */
1453
+WORDSIZE /* info level */
1454
+WORDSIZE /* buffer size */
1455
+DWORDSIZE /* server type */
1456
+RAP_MACHNAME_LEN]; /* workgroup */
1457
BOOL found_server = False;
1460
/* send a SMBtrans command with api NetServerEnum */
1461
p = make_header(param, RAP_NetServerEnum2,
1462
RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L0);
1463
PUTWORD(p, 0); /* info level 0 */
1464
PUTWORD(p, CLI_BUFFER_SIZE);
1466
PUTSTRING(p, workgroup, RAP_MACHNAME_LEN);
1469
param, PTR_DIFF(p,param), 8, /* params, length, max */
1470
NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
1471
&rparam, &rprcnt, /* return params, return size */
1472
&rdata, &rdrcnt /* return data, return size */
1475
res = GETRES(rparam);
1476
cli->rap_error = res;
1478
if (res == 0 || res == ERRmoredata) {
1481
p = rparam + WORDSIZE + WORDSIZE;
1485
for (i = 0;i < count;i++, p += 16) {
1486
char ret_server[RAP_MACHNAME_LEN];
1488
GETSTRINGF(p, ret_server, RAP_MACHNAME_LEN);
1489
if (strequal(ret_server, cli->desthost)) {
1490
found_server = True;
1496
DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. "
1497
"Error was : %s.\n", cli->desthost, cli_errstr(cli) ));
1504
return found_server;
1508
/****************************************************************************
1509
perform a NetWkstaUserLogoff
1510
****************************************************************************/
1511
BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation)
1513
char *rparam = NULL;
1516
unsigned int rdrcnt,rprcnt;
1517
char param[WORDSIZE /* api number */
1518
+sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string */
1519
+sizeof(RAP_USER_LOGOFF_INFO_L1) /* return string */
1520
+RAP_USERNAME_LEN+1 /* user name+pad */
1521
+RAP_MACHNAME_LEN /* wksta name */
1522
+WORDSIZE /* buffer size */
1523
+WORDSIZE]; /* buffer size? */
1526
memset(param, 0, sizeof(param));
1528
/* send a SMBtrans command with api NetWkstaUserLogoff */
1529
p = make_header(param, RAP_WWkstaUserLogoff,
1530
RAP_NetWkstaUserLogoff_REQ, RAP_USER_LOGOFF_INFO_L1);
1531
PUTDWORD(p, 0); /* Null pointer */
1532
PUTDWORD(p, 0); /* Null pointer */
1533
fstrcpy(upperbuf, user);
1534
strupper_m(upperbuf);
1535
PUTSTRINGF(p, upperbuf, RAP_USERNAME_LEN);
1536
p++; /* strange format, but ok */
1537
fstrcpy(upperbuf, workstation);
1538
strupper_m(upperbuf);
1539
PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN);
1540
PUTWORD(p, CLI_BUFFER_SIZE);
1541
PUTWORD(p, CLI_BUFFER_SIZE);
1544
param, PTR_DIFF(p,param),1024, /* param, length, max */
1545
NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
1546
&rparam, &rprcnt, /* return params, return size */
1547
&rdata, &rdrcnt /* return data, return size */
1549
cli->rap_error = GETRES(rparam);
1551
if (cli->rap_error != 0) {
1552
DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli->rap_error));
1558
return (cli->rap_error == 0);
1561
int cli_NetPrintQEnum(struct cli_state *cli,
1562
void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16),
1563
void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*))
1565
char param[WORDSIZE /* api number */
1566
+sizeof(RAP_NetPrintQEnum_REQ) /* req string */
1567
+sizeof(RAP_PRINTQ_INFO_L2) /* return string */
1568
+WORDSIZE /* info level */
1569
+WORDSIZE /* buffer size */
1570
+sizeof(RAP_SMB_PRINT_JOB_L1)]; /* more ret data */
1572
char *rparam = NULL;
1574
unsigned int rprcnt, rdrcnt;
1578
memset(param, '\0',sizeof(param));
1579
p = make_header(param, RAP_WPrintQEnum,
1580
RAP_NetPrintQEnum_REQ, RAP_PRINTQ_INFO_L2);
1581
PUTWORD(p,2); /* Info level 2 */
1582
PUTWORD(p,0xFFE0); /* Return buffer size */
1583
PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0);
1586
param, PTR_DIFF(p,param),1024,
1587
NULL, 0, CLI_BUFFER_SIZE,
1590
res = GETRES(rparam);
1591
cli->rap_error = res;
1593
DEBUG(1,("NetPrintQEnum gave error %d\n", res));
1598
if (res == 0 || res == ERRmoredata) {
1599
int i, converter, count;
1601
p = rparam + WORDSIZE;
1602
GETWORD(p, converter);
1606
for (i=0;i<count;i++) {
1607
pstring qname, sep_file, print_proc, dest, parms, comment;
1608
uint16 jobcount, priority, start_time, until_time, status;
1610
GETSTRINGF(p, qname, RAP_SHARENAME_LEN);
1612
GETWORD(p, priority);
1613
GETWORD(p, start_time);
1614
GETWORD(p, until_time);
1615
GETSTRINGP(p, sep_file, rdata, converter);
1616
GETSTRINGP(p, print_proc, rdata, converter);
1617
GETSTRINGP(p, dest, rdata, converter);
1618
GETSTRINGP(p, parms, rdata, converter);
1619
GETSTRINGP(p, parms, comment, converter);
1621
GETWORD(p, jobcount);
1623
qfn(qname, priority, start_time, until_time, sep_file, print_proc,
1624
dest, parms, comment, status, jobcount);
1628
for (j=0;j<jobcount;j++) {
1629
uint16 jid, pos, fsstatus;
1630
pstring ownername, notifyname, datatype, jparms, jstatus, jcomment;
1631
unsigned int submitted, jsize;
1634
GETSTRINGF(p, ownername, RAP_USERNAME_LEN);
1636
GETSTRINGF(p, notifyname, RAP_MACHNAME_LEN);
1637
GETSTRINGF(p, datatype, RAP_DATATYPE_LEN);
1638
GETSTRINGP(p, jparms, rdata, converter);
1640
GETWORD(p, fsstatus);
1641
GETSTRINGP(p, jstatus, rdata, converter);
1642
GETDWORD(p, submitted);
1644
GETSTRINGP(p, jcomment, rdata, converter);
1646
jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus,
1647
jstatus, submitted, jsize, jcomment);
1652
DEBUG(4,("NetPrintQEnum res=%d\n", res));
1655
DEBUG(4,("NetPrintQEnum no data returned\n"));
1664
int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer,
1665
void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16),
1666
void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*))
1668
char param[WORDSIZE /* api number */
1669
+sizeof(RAP_NetPrintQGetInfo_REQ) /* req string */
1670
+sizeof(RAP_PRINTQ_INFO_L2) /* return string */
1671
+RAP_SHARENAME_LEN /* printer name */
1672
+WORDSIZE /* info level */
1673
+WORDSIZE /* buffer size */
1674
+sizeof(RAP_SMB_PRINT_JOB_L1)]; /* more ret data */
1676
char *rparam = NULL;
1678
unsigned int rprcnt, rdrcnt;
1682
memset(param, '\0',sizeof(param));
1683
p = make_header(param, RAP_WPrintQGetInfo,
1684
RAP_NetPrintQGetInfo_REQ, RAP_PRINTQ_INFO_L2);
1685
PUTSTRING(p, printer, RAP_SHARENAME_LEN-1);
1686
PUTWORD(p, 2); /* Info level 2 */
1687
PUTWORD(p,0xFFE0); /* Return buffer size */
1688
PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0);
1691
param, PTR_DIFF(p,param),1024,
1692
NULL, 0, CLI_BUFFER_SIZE,
1695
res = GETRES(rparam);
1696
cli->rap_error = res;
1698
DEBUG(1,("NetPrintQGetInfo gave error %d\n", res));
1703
if (res == 0 || res == ERRmoredata) {
1704
int rsize, converter;
1705
pstring qname, sep_file, print_proc, dest, parms, comment;
1706
uint16 jobcount, priority, start_time, until_time, status;
1708
p = rparam + WORDSIZE;
1709
GETWORD(p, converter);
1713
GETSTRINGF(p, qname, RAP_SHARENAME_LEN);
1715
GETWORD(p, priority);
1716
GETWORD(p, start_time);
1717
GETWORD(p, until_time);
1718
GETSTRINGP(p, sep_file, rdata, converter);
1719
GETSTRINGP(p, print_proc, rdata, converter);
1720
GETSTRINGP(p, dest, rdata, converter);
1721
GETSTRINGP(p, parms, rdata, converter);
1722
GETSTRINGP(p, comment, rdata, converter);
1724
GETWORD(p, jobcount);
1725
qfn(qname, priority, start_time, until_time, sep_file, print_proc,
1726
dest, parms, comment, status, jobcount);
1729
for (j=0;(j<jobcount)&&(PTR_DIFF(p,rdata)< rsize);j++) {
1730
uint16 jid, pos, fsstatus;
1731
pstring ownername, notifyname, datatype, jparms, jstatus, jcomment;
1732
unsigned int submitted, jsize;
1735
GETSTRINGF(p, ownername, RAP_USERNAME_LEN);
1737
GETSTRINGF(p, notifyname, RAP_MACHNAME_LEN);
1738
GETSTRINGF(p, datatype, RAP_DATATYPE_LEN);
1739
GETSTRINGP(p, jparms, rdata, converter);
1741
GETWORD(p, fsstatus);
1742
GETSTRINGP(p, jstatus, rdata, converter);
1743
GETDWORD(p, submitted);
1745
GETSTRINGP(p, jcomment, rdata, converter);
1747
jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus,
1748
jstatus, submitted, jsize, jcomment);
1752
DEBUG(4,("NetPrintQGetInfo res=%d\n", res));
1755
DEBUG(4,("NetPrintQGetInfo no data returned\n"));
1764
/****************************************************************************
1765
call a NetServiceEnum - list running services on a different host
1766
****************************************************************************/
1767
int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state)
1769
char param[WORDSIZE /* api number */
1770
+sizeof(RAP_NetServiceEnum_REQ) /* parm string */
1771
+sizeof(RAP_SERVICE_INFO_L2) /* return string */
1772
+WORDSIZE /* info level */
1773
+WORDSIZE]; /* buffer size */
1775
char *rparam = NULL;
1777
unsigned int rprcnt, rdrcnt;
1781
memset(param, '\0', sizeof(param));
1782
p = make_header(param, RAP_WServiceEnum,
1783
RAP_NetServiceEnum_REQ, RAP_SERVICE_INFO_L2);
1784
PUTWORD(p,2); /* Info level 2 */
1785
PUTWORD(p,0xFFE0); /* Return buffer size */
1788
param, PTR_DIFF(p,param),8,
1789
NULL, 0, 0xFFE0 /* data area size */,
1792
res = GETRES(rparam);
1793
cli->rap_error = res;
1794
if(cli->rap_error == 234)
1795
DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n"));
1796
else if (cli->rap_error != 0) {
1797
DEBUG(1,("NetServiceEnum gave error %d\n", cli->rap_error));
1802
if (res == 0 || res == ERRmoredata) {
1805
p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
1808
for (i=0,p=rdata;i<count;i++) {
1810
char servicename[RAP_SRVCNAME_LEN];
1812
GETSTRINGF(p, servicename, RAP_SRVCNAME_LEN);
1813
p+=8; /* pass status words */
1814
GETSTRINGF(p, comment, RAP_SRVCCMNT_LEN);
1816
fn(servicename, comment, cli); /* BB add status too */
1819
DEBUG(4,("NetServiceEnum res=%d\n", res));
1822
DEBUG(4,("NetServiceEnum no data returned\n"));
1832
/****************************************************************************
1833
call a NetSessionEnum - list workstations with sessions to an SMB server
1834
****************************************************************************/
1835
int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, uint16, uint16, uint, uint, uint, char *))
1837
char param[WORDSIZE /* api number */
1838
+sizeof(RAP_NetSessionEnum_REQ) /* parm string */
1839
+sizeof(RAP_SESSION_INFO_L2) /* return string */
1840
+WORDSIZE /* info level */
1841
+WORDSIZE]; /* buffer size */
1843
char *rparam = NULL;
1845
unsigned int rprcnt, rdrcnt;
1848
memset(param, '\0', sizeof(param));
1849
p = make_header(param, RAP_WsessionEnum,
1850
RAP_NetSessionEnum_REQ, RAP_SESSION_INFO_L2);
1851
PUTWORD(p,2); /* Info level 2 */
1852
PUTWORD(p,0xFF); /* Return buffer size */
1855
param, PTR_DIFF(p,param),8,
1856
NULL, 0, CLI_BUFFER_SIZE,
1859
res = GETRES(rparam);
1860
cli->rap_error = res;
1862
DEBUG(1,("NetSessionEnum gave error %d\n", res));
1867
if (res == 0 || res == ERRmoredata) {
1868
int i, converter, count;
1870
p = rparam + WORDSIZE;
1871
GETWORD(p, converter);
1874
for (i=0,p=rdata;i<count;i++) {
1875
pstring wsname, username, clitype_name;
1876
uint16 num_conns, num_opens, num_users;
1877
unsigned int sess_time, idle_time, user_flags;
1879
GETSTRINGP(p, wsname, rdata, converter);
1880
GETSTRINGP(p, username, rdata, converter);
1881
GETWORD(p, num_conns);
1882
GETWORD(p, num_opens);
1883
GETWORD(p, num_users);
1884
GETDWORD(p, sess_time);
1885
GETDWORD(p, idle_time);
1886
GETDWORD(p, user_flags);
1887
GETSTRINGP(p, clitype_name, rdata, converter);
1889
fn(wsname, username, num_conns, num_opens, num_users, sess_time,
1890
idle_time, user_flags, clitype_name);
1894
DEBUG(4,("NetSessionEnum res=%d\n", res));
1897
DEBUG(4,("NetSesssionEnum no data returned\n"));
1906
/****************************************************************************
1907
Call a NetSessionGetInfo - get information about other session to an SMB server.
1908
****************************************************************************/
1910
int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void (*fn)(const char *, const char *, uint16, uint16, uint16, uint, uint, uint, const char *))
1912
char param[WORDSIZE /* api number */
1913
+sizeof(RAP_NetSessionGetInfo_REQ) /* req string */
1914
+sizeof(RAP_SESSION_INFO_L2) /* return string */
1915
+RAP_MACHNAME_LEN /* wksta name */
1916
+WORDSIZE /* info level */
1917
+WORDSIZE]; /* buffer size */
1919
char *rparam = NULL;
1921
unsigned int rprcnt, rdrcnt;
1925
memset(param, '\0', sizeof(param));
1926
p = make_header(param, RAP_WsessionGetInfo,
1927
RAP_NetSessionGetInfo_REQ, RAP_SESSION_INFO_L2);
1928
PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1);
1929
PUTWORD(p,2); /* Info level 2 */
1930
PUTWORD(p,0xFF); /* Return buffer size */
1933
param, PTR_DIFF(p,param),PTR_DIFF(p,param),
1934
NULL, 0, CLI_BUFFER_SIZE,
1937
cli->rap_error = SVAL(rparam,0);
1938
if (cli->rap_error != 0) {
1939
DEBUG(1,("NetSessionGetInfo gave error %d\n", cli->rap_error));
1944
res = GETRES(rparam);
1946
if (res == 0 || res == ERRmoredata) {
1948
pstring wsname, username, clitype_name;
1949
uint16 num_conns, num_opens, num_users;
1950
unsigned int sess_time, idle_time, user_flags;
1952
p = rparam + WORDSIZE;
1953
GETWORD(p, converter);
1954
p += WORDSIZE; /* skip rsize */
1957
GETSTRINGP(p, wsname, rdata, converter);
1958
GETSTRINGP(p, username, rdata, converter);
1959
GETWORD(p, num_conns);
1960
GETWORD(p, num_opens);
1961
GETWORD(p, num_users);
1962
GETDWORD(p, sess_time);
1963
GETDWORD(p, idle_time);
1964
GETDWORD(p, user_flags);
1965
GETSTRINGP(p, clitype_name, rdata, converter);
1967
fn(wsname, username, num_conns, num_opens, num_users, sess_time,
1968
idle_time, user_flags, clitype_name);
1970
DEBUG(4,("NetSessionGetInfo res=%d\n", res));
1973
DEBUG(4,("NetSessionGetInfo no data returned\n"));
1982
/****************************************************************************
1983
call a NetSessionDel - close a session to an SMB server
1984
****************************************************************************/
1985
int cli_NetSessionDel(struct cli_state *cli, const char *workstation)
1987
char param[WORDSIZE /* api number */
1988
+sizeof(RAP_NetSessionDel_REQ) /* req string */
1989
+1 /* no return string */
1990
+RAP_MACHNAME_LEN /* workstation name */
1991
+WORDSIZE]; /* reserved (0) */
1993
char *rparam = NULL;
1995
unsigned int rprcnt, rdrcnt;
1998
memset(param, '\0', sizeof(param));
1999
p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL);
2000
PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1);
2001
PUTWORD(p,0); /* reserved word of 0 */
2003
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
2004
NULL, 0, 200, /* data, length, maxlen */
2005
&rparam, &rprcnt, /* return params, length */
2006
&rdata, &rdrcnt)) /* return data, length */
2008
res = GETRES(rparam);
2009
cli->rap_error = res;
2015
DEBUG(4,("NetFileClose2 res=%d\n", res));
2019
DEBUG(4,("NetFileClose2 failed\n"));
2029
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))
2031
char param[WORDSIZE /* api number */
2032
+sizeof(RAP_NetConnectionEnum_REQ) /* req string */
2033
+sizeof(RAP_CONNECTION_INFO_L1) /* return string */
2034
+RAP_MACHNAME_LEN /* wksta name */
2035
+WORDSIZE /* info level */
2036
+WORDSIZE]; /* buffer size */
2038
char *rparam = NULL;
2040
unsigned int rprcnt, rdrcnt;
2043
memset(param, '\0', sizeof(param));
2044
p = make_header(param, RAP_WconnectionEnum,
2045
RAP_NetConnectionEnum_REQ, RAP_CONNECTION_INFO_L1);
2046
PUTSTRING(p, qualifier, RAP_MACHNAME_LEN-1);/* Workstation name */
2047
PUTWORD(p,1); /* Info level 1 */
2048
PUTWORD(p,0xFFE0); /* Return buffer size */
2051
param, PTR_DIFF(p,param),PTR_DIFF(p,param),
2052
NULL, 0, CLI_BUFFER_SIZE,
2055
res = GETRES(rparam);
2056
cli->rap_error = res;
2058
DEBUG(1,("NetConnectionEnum gave error %d\n", res));
2062
if (res == 0 || res == ERRmoredata) {
2063
int i, converter, count;
2065
p = rparam + WORDSIZE;
2066
GETWORD(p, converter);
2069
for (i=0,p=rdata;i<count;i++) {
2070
pstring netname, username;
2071
uint16 conn_id, conn_type, num_opens, num_users;
2072
unsigned int conn_time;
2075
GETWORD(p,conn_type);
2076
GETWORD(p,num_opens);
2077
GETWORD(p,num_users);
2078
GETDWORD(p,conn_time);
2079
GETSTRINGP(p, username, rdata, converter);
2080
GETSTRINGP(p, netname, rdata, converter);
2082
fn(conn_id, conn_type, num_opens, num_users, conn_time,
2087
DEBUG(4,("NetConnectionEnum res=%d\n", res));
2090
DEBUG(4,("NetConnectionEnum no data returned\n"));