LCOV - code coverage report
Current view: top level - source3/utils - clirap2.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 26 1168 2.2 %
Date: 2024-04-21 15:09:00 Functions: 3 33 9.1 %

          Line data    Source code
       1             : /*
       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)
       6             :    Copyright (C) 2007 Jeremy Allison. jra@samba.org
       7             : 
       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 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      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.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : /*****************************************************/
      23             : /*                                                   */
      24             : /*   Additional RAP functionality                    */
      25             : /*                                                   */
      26             : /*   RAP is the original SMB RPC, documented         */
      27             : /*   by Microsoft and X/Open in the 1990s and        */
      28             : /*   supported by most SMB/CIFS servers although     */
      29             : /*   it is unlikely that any one implementation      */
      30             : /*   supports all RAP command codes since some       */
      31             : /*   are quite obsolete and a few are specific       */
      32             : /*   to a particular network operating system        */
      33             : /*                                                   */
      34             : /*   Although it has largely been replaced           */
      35             : /*   for complex remote administration and management  */
      36             : /*   (of servers) by the relatively newer            */
      37             : /*   DCE/RPC based remote API (which better handles  */
      38             : /*   large >64K data structures), there are many     */
      39             : /*   important administrative and resource location  */
      40             : /*   tasks and user tasks (e.g. password change)     */
      41             : /*   that are performed via RAP.                     */
      42             : /*                                                   */
      43             : /*   Although a few of the RAP calls are implemented */
      44             : /*   in the Samba client library already (clirap.c)  */
      45             : /*   the new ones are in clirap2.c for easy patching */
      46             : /*   and integration and a corresponding header      */
      47             : /*   file, rap.h, has been created.                  */
      48             : /*                                                   */
      49             : /*   This is based on data from the CIFS spec        */
      50             : /*   and the LAN Server and LAN Manager              */
      51             : /*   Programming Reference books and published       */
      52             : /*   RAP document and CIFS forum postings and        */
      53             : /*   lots of trial and error                         */
      54             : /*                                                   */
      55             : /*   Function names changed from API_ (as they are   */
      56             : /*   in the CIFS specification) to RAP_ in order     */
      57             : /*   to avoid confusion with other API calls         */
      58             : /*   sent via DCE RPC                                */
      59             : /*                                                   */
      60             : /*****************************************************/
      61             : 
      62             : /*****************************************************/
      63             : /*                                                   */
      64             : /* cifsrap.c already includes support for:           */
      65             : /*                                                   */
      66             : /* WshareEnum ( API number 0, level 1)               */
      67             : /* NetServerEnum2 (API num 104, level 1)             */
      68             : /* WWkstaUserLogon (132)                             */
      69             : /* SamOEMchgPasswordUser2_P (214)                    */
      70             : /*                                                   */
      71             : /* cifsprint.c already includes support for:         */
      72             : /*                                                   */
      73             : /* WPrintJobEnum (API num 76, level 2)               */
      74             : /* WPrintJobDel  (API num 81)                        */
      75             : /*                                                   */
      76             : /*****************************************************/
      77             : 
      78             : #include "includes.h"
      79             : #include "libsmb/libsmb.h"
      80             : #include "../librpc/gen_ndr/rap.h"
      81             : #include "../librpc/gen_ndr/svcctl.h"
      82             : #include "clirap2.h"
      83             : #include "../libcli/smb/smbXcli_base.h"
      84             : 
      85             : #define WORDSIZE 2
      86             : #define DWORDSIZE 4
      87             : 
      88             : #define PUTBYTE(p,b) do {SCVAL(p,0,b); p++;} while(0)
      89             : 
      90             : #define GETBYTE(p,b,endp) \
      91             :         do {\
      92             :                 if (p+1 < endp) {\
      93             :                         b = CVAL(p,0);\
      94             :                 }\
      95             :                 p++;\
      96             :         } while(0)
      97             : 
      98             : #define PUTWORD(p,w) do {SSVAL(p,0,w); p += WORDSIZE;} while(0)
      99             : 
     100             : #define GETWORD(p,w,endp) \
     101             :         do {\
     102             :                 if (p+WORDSIZE < endp) {\
     103             :                         w = SVAL(p,0);\
     104             :                 }\
     105             :                 p += WORDSIZE;\
     106             :         } while(0)
     107             : 
     108             : #define PUTDWORD(p,d) do {SIVAL(p,0,d); p += DWORDSIZE;} while(0)
     109             : 
     110             : #define GETDWORD(p,d,endp) \
     111             :         do {\
     112             :                 if (p+DWORDSIZE < endp) {\
     113             :                         d = IVAL(p,0);\
     114             :                 }\
     115             :                 p += DWORDSIZE;\
     116             :         } while(0)
     117             : 
     118             : #define GETRES(p,endp) ((p && p+2 < endp) ? SVAL(p,0) : -1)
     119             : 
     120             : /**
     121             :  *  Skip past some strings in a buffer - old version - no checks.
     122             :  *  **/
     123             : 
     124          12 : static char *push_skip_string(char *buf)
     125             : {
     126          12 :         buf += strlen(buf) + 1;
     127          12 :         return(buf);
     128             : }
     129             : 
     130             : /* put string s at p with max len n and increment p past string */
     131             : #define PUTSTRING(p,s,n) \
     132             :         do {\
     133             :                 push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\
     134             :                 p = push_skip_string(p);\
     135             :         } while(0)
     136             : 
     137             : /* put string s and p, using fixed len l, and increment p by l */
     138             : #define PUTSTRINGF(p,s,l) \
     139             :         do {\
     140             :                 push_ascii(p,s?s:"",l,STR_TERMINATE);\
     141             :                 p += l;\
     142             :         } while (0)
     143             : 
     144             : /* put string pointer at p, supplying offset o from rdata r, store   */
     145             : /* dword offset at p, increment p by 4 and o by length of s.  This   */
     146             : /* means on the first call, you must calc the offset yourself!       */
     147             : 
     148             : #define PUTSTRINGP(p,s,r,o) \
     149             :         do {\
     150             :                 if (s) {\
     151             :                         push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\
     152             :                         PUTDWORD(p,o);\
     153             :                         o += strlen(s) + 1;\
     154             :                 } else {\
     155             :                         PUTDWORD(p,0);\
     156             :                 }\
     157             :         }while(0);
     158             : 
     159             : /* get asciiz string dest from src, return increment past string */
     160             : 
     161           0 : static size_t rap_getstring(TALLOC_CTX *ctx, char *src, char **dest, const char *endp)
     162             : {
     163           0 :         char *p1;
     164           0 :         size_t len;
     165             : 
     166           0 :         *dest = NULL;
     167           0 :         for (p1 = src, len = 0; *p1 && p1 < endp; len++)
     168           0 :                 p1++;
     169           0 :         if (!*p1) {
     170           0 :                 len++;
     171             :         }
     172           0 :         pull_string_talloc(ctx,src,0,dest,src,len,STR_ASCII);
     173           0 :         return len;
     174             : }
     175             : 
     176             : /* get fixed length l string dest from src, return increment for src */
     177             : 
     178           0 : static size_t rap_getstringf(char *src, char *dest, size_t l, size_t dlen, char *endp)
     179             : {
     180           0 :         char *p1;
     181           0 :         size_t len;
     182             : 
     183           0 :         if (dlen) {
     184           0 :                 dest[0] = '\0';
     185             :         }
     186           0 :         for (p1 = src, len = 0; *p1 && p1 < endp; len++) {
     187           0 :                 p1++;
     188             :         }
     189           0 :         if (!*p1) {
     190           0 :                 len++;
     191             :         }
     192           0 :         if (len > l) {
     193           0 :                 len = l;
     194             :         }
     195           0 :         if (len) {
     196           0 :                 pull_ascii(dest,src,len,len,STR_ASCII);
     197             :         }
     198           0 :         return l;
     199             : }
     200             : 
     201             : /* get string dest from offset (obtained at p) from rdata r - converter c */
     202           0 : static size_t rap_getstringp(TALLOC_CTX *ctx, char *p, char **dest, char *r, uint16_t c, char *endp)
     203             : {
     204           0 :         uint32_t off = 0;
     205           0 :         const char *src;
     206           0 :         size_t len=0;
     207             : 
     208           0 :         *dest = NULL;
     209           0 :         if (p+4 < endp) {
     210           0 :                 GETDWORD(p,off,endp);
     211           0 :                 off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */
     212           0 :                 off -= c;
     213             :         }
     214           0 :         if (r+off > endp || r+off < r) {
     215           0 :                 src="";
     216           0 :                 len=1;
     217             :         } else {
     218             :                 const char *p1;
     219           0 :                 src=r+off;
     220           0 :                 for (p1 = src, len = 0; *p1 && p1 < endp; len++) {
     221           0 :                         p1++;
     222             :                 }
     223           0 :                 if (!*p1) {
     224           0 :                         len++;
     225             :                 }
     226             :         }
     227           0 :         pull_string_talloc(ctx,src,0,dest,src,len,STR_ASCII);
     228           0 :         return 4;
     229             : }
     230             : 
     231           4 : static char *make_header(char *param, uint16_t apinum, const char *reqfmt, const char *datafmt)
     232             : {
     233           4 :         PUTWORD(param,apinum);
     234           4 :         if (reqfmt)
     235           4 :                 PUTSTRING(param,reqfmt,0);
     236             :         else
     237           0 :                 *param++ = (char) 0;
     238             : 
     239           4 :         if (datafmt)
     240           4 :                 PUTSTRING(param,datafmt,0);
     241             :         else
     242           0 :                 *param++ = (char) 0;
     243             : 
     244           4 :         return param;
     245             : }
     246             : 
     247             : /****************************************************************************
     248             :  call a NetGroupDelete - delete user group from remote server
     249             : ****************************************************************************/
     250             : 
     251           0 : int cli_NetGroupDelete(struct cli_state *cli, const char *group_name)
     252             : {
     253           0 :         char *rparam = NULL;
     254           0 :         char *rdata = NULL;
     255           0 :         char *p;
     256           0 :         unsigned int rdrcnt,rprcnt;
     257           0 :         int res = -1;
     258           0 :         char param[WORDSIZE                    /* api number    */
     259             :             +sizeof(RAP_NetGroupDel_REQ) /* parm string   */
     260             :             +1                           /* no ret string */
     261             :             +RAP_GROUPNAME_LEN           /* group to del  */
     262             :             +WORDSIZE];                  /* reserved word */
     263             : 
     264             :         /* now send a SMBtrans command with api GroupDel */
     265           0 :         p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL);
     266           0 :         PUTSTRING(p, group_name, RAP_GROUPNAME_LEN);
     267           0 :         PUTWORD(p,0);  /* reserved word MBZ on input */
     268             : 
     269           0 :         if (cli_api(cli,
     270           0 :               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
     271             :               NULL, 0, 200,       /* data, length, maxlen */
     272             :               &rparam, &rprcnt,   /* return params, length */
     273             :               &rdata, &rdrcnt))   /* return data, length */
     274             :         {
     275           0 :                 char *endp = rparam + rprcnt;
     276           0 :                 res = GETRES(rparam,endp);
     277             : 
     278           0 :                 if (res == 0) {
     279             :                         /* nothing to do */
     280           0 :                 } else if ((res == 5) || (res == 65)) {
     281           0 :                         DEBUG(1, ("Access Denied\n"));
     282           0 :                 } else if (res == 2220) {
     283           0 :                         DEBUG (1, ("Group does not exist\n"));
     284             :                 } else {
     285           0 :                         DEBUG(4,("NetGroupDelete res=%d\n", res));
     286             :                 }
     287             :         } else {
     288           0 :                 res = -1;
     289           0 :                 DEBUG(4,("NetGroupDelete failed\n"));
     290             :         }
     291             : 
     292           0 :         SAFE_FREE(rparam);
     293           0 :         SAFE_FREE(rdata);
     294             : 
     295           0 :         return res;
     296             : }
     297             : 
     298             : /****************************************************************************
     299             :  call a NetGroupAdd - add user group to remote server
     300             : ****************************************************************************/
     301             : 
     302           0 : int cli_NetGroupAdd(struct cli_state *cli, struct rap_group_info_1 *grinfo)
     303             : {
     304           0 :         char *rparam = NULL;
     305           0 :         char *rdata = NULL;
     306           0 :         char *p;
     307           0 :         unsigned int rdrcnt,rprcnt;
     308           0 :         int res = -1;
     309           0 :         char param[WORDSIZE                    /* api number    */
     310             :             +sizeof(RAP_NetGroupAdd_REQ) /* req string    */
     311             :             +sizeof(RAP_GROUP_INFO_L1)   /* return string */
     312             :             +WORDSIZE                    /* info level    */
     313             :             +WORDSIZE];                  /* reserved word */
     314             : 
     315             :         /* offset into data of free format strings.  Will be updated */
     316             :         /* by PUTSTRINGP macro and end up with total data length.    */
     317           0 :         int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE;
     318           0 :         char *data;
     319           0 :         size_t data_size;
     320             : 
     321             :         /* Allocate data. */
     322           0 :         data_size = MAX(soffset + strlen(grinfo->comment) + 1, 1024);
     323             : 
     324           0 :         data = SMB_MALLOC_ARRAY(char, data_size);
     325           0 :         if (!data) {
     326           0 :                 DEBUG (1, ("Malloc fail\n"));
     327           0 :                 return -1;
     328             :         }
     329             : 
     330             :         /* now send a SMBtrans command with api WGroupAdd */
     331             : 
     332           0 :         p = make_header(param, RAP_WGroupAdd,
     333             :                         RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1);
     334           0 :         PUTWORD(p, 1); /* info level */
     335           0 :         PUTWORD(p, 0); /* reserved word 0 */
     336             : 
     337           0 :         p = data;
     338           0 :         PUTSTRINGF(p, (const char *)grinfo->group_name, RAP_GROUPNAME_LEN);
     339           0 :         PUTBYTE(p, 0); /* pad byte 0 */
     340           0 :         PUTSTRINGP(p, grinfo->comment, data, soffset);
     341             : 
     342           0 :         if (cli_api(cli,
     343             :               param, sizeof(param), 1024, /* Param, length, maxlen */
     344             :               data, soffset, data_size, /* data, length, maxlen */
     345             :               &rparam, &rprcnt,   /* return params, length */
     346             :               &rdata, &rdrcnt))   /* return data, length */
     347             :         {
     348           0 :                 char *endp = rparam + rprcnt;
     349           0 :                 res = GETRES(rparam, endp);
     350             : 
     351           0 :                 if (res == 0) {
     352             :                         /* nothing to do */
     353           0 :                 } else if ((res == 5) || (res == 65)) {
     354           0 :                         DEBUG(1, ("Access Denied\n"));
     355           0 :                 } else if (res == 2223) {
     356           0 :                         DEBUG (1, ("Group already exists\n"));
     357             :                 } else {
     358           0 :                         DEBUG(4,("NetGroupAdd res=%d\n", res));
     359             :                 }
     360             :         } else {
     361           0 :                 res = -1;
     362           0 :                 DEBUG(4,("NetGroupAdd failed\n"));
     363             :         }
     364             : 
     365           0 :         SAFE_FREE(data);
     366           0 :         SAFE_FREE(rparam);
     367           0 :         SAFE_FREE(rdata);
     368             : 
     369           0 :         return res;
     370             : }
     371             : 
     372             : /****************************************************************************
     373             :  Call a NetGroupEnum - try and list user groups on a different host.
     374             : ****************************************************************************/
     375             : 
     376           0 : int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state)
     377             : {
     378           0 :         char param[WORDSIZE                     /* api number    */
     379             :             +sizeof(RAP_NetGroupEnum_REQ) /* parm string   */
     380             :             +sizeof(RAP_GROUP_INFO_L1)    /* return string */
     381             :             +WORDSIZE                     /* info level    */
     382             :             +WORDSIZE];                   /* buffer size   */
     383           0 :         char *p;
     384           0 :         char *rparam = NULL;
     385           0 :         char *rdata = NULL;
     386           0 :         unsigned int rprcnt, rdrcnt;
     387           0 :         int res = -1;
     388             : 
     389           0 :         memset(param, '\0', sizeof(param));
     390           0 :         p = make_header(param, RAP_WGroupEnum,
     391             :                   RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L1);
     392           0 :         PUTWORD(p,1); /* Info level 1 */  /* add level 0 */
     393           0 :         PUTWORD(p,0xFFE0); /* Return buffer size */
     394             : 
     395           0 :         if (cli_api(cli,
     396           0 :               param, PTR_DIFF(p,param),8,
     397             :               NULL, 0, 0xFFE0 /* data area size */,
     398             :               &rparam, &rprcnt,
     399             :               &rdata, &rdrcnt)) {
     400           0 :                 char *endp = rparam + rdrcnt;
     401             : 
     402           0 :                 res = GETRES(rparam, endp);
     403           0 :                 cli->rap_error = res;
     404           0 :                 if(cli->rap_error == 234) {
     405           0 :                         DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
     406           0 :                 } else if (cli->rap_error != 0) {
     407           0 :                         DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
     408             :                 }
     409             :         }
     410             : 
     411           0 :         if (!rdata) {
     412           0 :                 DEBUG(4,("NetGroupEnum no data returned\n"));
     413           0 :                 goto out;
     414             :         }
     415             : 
     416           0 :         if (res == 0 || res == ERRmoredata) {
     417           0 :                 char *endp = rparam + rprcnt;
     418           0 :                 int i, converter = 0, count = 0;
     419           0 :                 TALLOC_CTX *frame = talloc_stackframe();
     420             : 
     421           0 :                 p = rparam + WORDSIZE; /* skip result */
     422           0 :                 GETWORD(p, converter, endp);
     423           0 :                 GETWORD(p, count, endp);
     424             : 
     425           0 :                 endp = rdata + rdrcnt;
     426           0 :                 for (i=0,p=rdata; i<count && p < endp;i++) {
     427           0 :                         char *comment = NULL;
     428           0 :                         char groupname[RAP_GROUPNAME_LEN];
     429             : 
     430           0 :                         p += rap_getstringf(p,
     431             :                                         groupname,
     432             :                                         RAP_GROUPNAME_LEN,
     433             :                                         RAP_GROUPNAME_LEN,
     434             :                                         endp);
     435           0 :                         p++; /* pad byte */
     436           0 :                         p += rap_getstringp(frame,
     437             :                                         p,
     438             :                                         &comment,
     439             :                                         rdata,
     440             :                                         converter,
     441             :                                         endp);
     442             : 
     443           0 :                         if (!comment || !groupname[0]) {
     444             :                                 break;
     445             :                         }
     446             : 
     447           0 :                         fn(groupname, comment, cli);
     448             :                 }
     449           0 :                 TALLOC_FREE(frame);
     450             :         } else {
     451           0 :                 DEBUG(4,("NetGroupEnum res=%d\n", res));
     452             :         }
     453             : 
     454           0 :   out:
     455             : 
     456           0 :         SAFE_FREE(rparam);
     457           0 :         SAFE_FREE(rdata);
     458             : 
     459           0 :         return res;
     460             : }
     461             : 
     462           0 : int cli_RNetGroupEnum0(struct cli_state *cli,
     463             :                        void (*fn)(const char *, void *),
     464             :                        void *state)
     465             : {
     466           0 :         char param[WORDSIZE                     /* api number    */
     467             :                 +sizeof(RAP_NetGroupEnum_REQ) /* parm string   */
     468             :                 +sizeof(RAP_GROUP_INFO_L0)    /* return string */
     469             :                 +WORDSIZE                     /* info level    */
     470             :                 +WORDSIZE];                   /* buffer size   */
     471           0 :         char *p;
     472           0 :         char *rparam = NULL;
     473           0 :         char *rdata = NULL;
     474           0 :         unsigned int rprcnt, rdrcnt;
     475           0 :         int res = -1;
     476             : 
     477           0 :         memset(param, '\0', sizeof(param));
     478           0 :         p = make_header(param, RAP_WGroupEnum,
     479             :                 RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L0);
     480           0 :         PUTWORD(p,0); /* Info level 0 */ /* Hmmm. I *very* much suspect this
     481             :                                       is the resume count, at least
     482             :                                       that's what smbd believes... */
     483           0 :         PUTWORD(p,0xFFE0); /* Return buffer size */
     484             : 
     485           0 :         if (cli_api(cli,
     486           0 :                         param, PTR_DIFF(p,param),8,
     487             :                         NULL, 0, 0xFFE0 /* data area size */,
     488             :                         &rparam, &rprcnt,
     489             :                         &rdata, &rdrcnt)) {
     490           0 :                 char *endp = rparam+rprcnt;
     491           0 :                 res = GETRES(rparam,endp);
     492           0 :                 cli->rap_error = res;
     493           0 :                 if(cli->rap_error == 234) {
     494           0 :                         DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
     495           0 :                 } else if (cli->rap_error != 0) {
     496           0 :                         DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
     497             :                 }
     498             :         }
     499             : 
     500           0 :         if (!rdata) {
     501           0 :                 DEBUG(4,("NetGroupEnum no data returned\n"));
     502           0 :                 goto out;
     503             :         }
     504             : 
     505           0 :         if (res == 0 || res == ERRmoredata) {
     506           0 :                 char *endp = rparam + rprcnt;
     507           0 :                 int i, count = 0;
     508             : 
     509           0 :                 p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
     510           0 :                 GETWORD(p, count, endp);
     511             : 
     512           0 :                 endp = rdata + rdrcnt;
     513           0 :                 for (i=0,p=rdata; i<count && p < endp;i++) {
     514           0 :                         char groupname[RAP_GROUPNAME_LEN];
     515             : 
     516           0 :                         p += rap_getstringf(p,
     517             :                                         groupname,
     518             :                                         RAP_GROUPNAME_LEN,
     519             :                                         RAP_GROUPNAME_LEN,
     520             :                                         endp);
     521           0 :                         if (groupname[0]) {
     522           0 :                                 fn(groupname, cli);
     523             :                         }
     524             :                 }
     525             :         } else {
     526           0 :                 DEBUG(4,("NetGroupEnum res=%d\n", res));
     527             :         }
     528             : 
     529           0 :   out:
     530             : 
     531           0 :         SAFE_FREE(rparam);
     532           0 :         SAFE_FREE(rdata);
     533             : 
     534           0 :         return res;
     535             : }
     536             : 
     537           0 : int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const char *user_name)
     538             : {
     539           0 :         char *rparam = NULL;
     540           0 :         char *rdata = NULL;
     541           0 :         char *p;
     542           0 :         unsigned int rdrcnt,rprcnt;
     543           0 :         int res = -1;
     544           0 :         char param[WORDSIZE                        /* api number    */
     545             :                 +sizeof(RAP_NetGroupDelUser_REQ) /* parm string   */
     546             :                 +1                               /* no ret string */
     547             :                 +RAP_GROUPNAME_LEN               /* group name    */
     548             :                 +RAP_USERNAME_LEN];              /* user to del   */
     549             : 
     550             :         /* now send a SMBtrans command with api GroupMemberAdd */
     551           0 :         p = make_header(param, RAP_WGroupDelUser, RAP_NetGroupDelUser_REQ, NULL);
     552           0 :         PUTSTRING(p,group_name,RAP_GROUPNAME_LEN);
     553           0 :         PUTSTRING(p,user_name,RAP_USERNAME_LEN);
     554             : 
     555           0 :         if (cli_api(cli,
     556           0 :                         param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
     557             :                         NULL, 0, 200,       /* data, length, maxlen */
     558             :                         &rparam, &rprcnt,   /* return params, length */
     559             :                         &rdata, &rdrcnt))   /* return data, length */
     560             :         {
     561           0 :                 char *endp = rparam + rprcnt;
     562           0 :                 res = GETRES(rparam,endp);
     563             : 
     564           0 :                 switch(res) {
     565           0 :                 case 0:
     566           0 :                         break;
     567           0 :                 case 5:
     568             :                 case 65:
     569           0 :                         DEBUG(1, ("Access Denied\n"));
     570           0 :                         break;
     571           0 :                 case 50:
     572           0 :                         DEBUG(1, ("Not supported by server\n"));
     573           0 :                         break;
     574           0 :                 case 2220:
     575           0 :                         DEBUG(1, ("Group does not exist\n"));
     576           0 :                         break;
     577           0 :                 case 2221:
     578           0 :                         DEBUG(1, ("User does not exist\n"));
     579           0 :                         break;
     580           0 :                 case 2237:
     581           0 :                         DEBUG(1, ("User is not in group\n"));
     582           0 :                         break;
     583           0 :                 default:
     584           0 :                         DEBUG(4,("NetGroupDelUser res=%d\n", res));
     585             :                 }
     586             :         } else {
     587           0 :                 res = -1;
     588           0 :                 DEBUG(4,("NetGroupDelUser failed\n"));
     589             :         }
     590             : 
     591           0 :         SAFE_FREE(rparam);
     592           0 :         SAFE_FREE(rdata);
     593             : 
     594           0 :         return res;
     595             : }
     596             : 
     597           0 : int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const char *user_name)
     598             : {
     599           0 :         char *rparam = NULL;
     600           0 :         char *rdata = NULL;
     601           0 :         char *p;
     602           0 :         unsigned int rdrcnt,rprcnt;
     603           0 :         int res = -1;
     604           0 :         char param[WORDSIZE                        /* api number    */
     605             :                 +sizeof(RAP_NetGroupAddUser_REQ) /* parm string   */
     606             :                 +1                               /* no ret string */
     607             :                 +RAP_GROUPNAME_LEN               /* group name    */
     608             :                 +RAP_USERNAME_LEN];              /* user to add   */
     609             : 
     610             :         /* now send a SMBtrans command with api GroupMemberAdd */
     611           0 :         p = make_header(param, RAP_WGroupAddUser, RAP_NetGroupAddUser_REQ, NULL);
     612           0 :         PUTSTRING(p,group_name,RAP_GROUPNAME_LEN);
     613           0 :         PUTSTRING(p,user_name,RAP_USERNAME_LEN);
     614             : 
     615           0 :         if (cli_api(cli,
     616           0 :                         param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
     617             :                         NULL, 0, 200,       /* data, length, maxlen */
     618             :                         &rparam, &rprcnt,   /* return params, length */
     619             :                         &rdata, &rdrcnt))   /* return data, length */
     620             :         {
     621           0 :                 char *endp = rparam + rprcnt;
     622           0 :                 res = GETRES(rparam,endp);
     623             : 
     624           0 :                 switch(res) {
     625           0 :                 case 0:
     626           0 :                         break;
     627           0 :                 case 5:
     628             :                 case 65:
     629           0 :                         DEBUG(1, ("Access Denied\n"));
     630           0 :                         break;
     631           0 :                 case 50:
     632           0 :                         DEBUG(1, ("Not supported by server\n"));
     633           0 :                         break;
     634           0 :                 case 2220:
     635           0 :                         DEBUG(1, ("Group does not exist\n"));
     636           0 :                         break;
     637           0 :                 case 2221:
     638           0 :                         DEBUG(1, ("User does not exist\n"));
     639           0 :                         break;
     640           0 :                 default:
     641           0 :                         DEBUG(4,("NetGroupAddUser res=%d\n", res));
     642             :                 }
     643             :         } else {
     644           0 :                 res = -1;
     645           0 :                 DEBUG(4,("NetGroupAddUser failed\n"));
     646             :         }
     647             : 
     648           0 :         SAFE_FREE(rparam);
     649           0 :         SAFE_FREE(rdata);
     650             : 
     651           0 :         return res;
     652             : }
     653             : 
     654             : 
     655           0 : int cli_NetGroupGetUsers(struct cli_state * cli, const char *group_name, void (*fn)(const char *, void *), void *state )
     656             : {
     657           0 :         char *rparam = NULL;
     658           0 :         char *rdata = NULL;
     659           0 :         char *p;
     660           0 :         unsigned int rdrcnt,rprcnt;
     661           0 :         int res = -1;
     662           0 :         char param[WORDSIZE                        /* api number    */
     663             :                 +sizeof(RAP_NetGroupGetUsers_REQ)/* parm string   */
     664             :                 +sizeof(RAP_GROUP_USERS_INFO_0)  /* return string */
     665             :                 +RAP_GROUPNAME_LEN               /* group name    */
     666             :                 +WORDSIZE                        /* info level    */
     667             :                 +WORDSIZE];                      /* buffer size   */
     668             : 
     669             :         /* now send a SMBtrans command with api GroupGetUsers */
     670           0 :         p = make_header(param, RAP_WGroupGetUsers,
     671             :                 RAP_NetGroupGetUsers_REQ, RAP_GROUP_USERS_INFO_0);
     672           0 :         PUTSTRING(p,group_name,RAP_GROUPNAME_LEN-1);
     673           0 :         PUTWORD(p,0); /* info level 0 */
     674           0 :         PUTWORD(p,0xFFE0); /* return buffer size */
     675             : 
     676           0 :         if (cli_api(cli,
     677           0 :                         param, PTR_DIFF(p,param),PTR_DIFF(p,param),
     678             :                         NULL, 0, CLI_BUFFER_SIZE,
     679             :                         &rparam, &rprcnt,
     680             :                         &rdata, &rdrcnt)) {
     681           0 :                 char *endp = rparam + rprcnt;
     682           0 :                 res = GETRES(rparam,endp);
     683           0 :                 cli->rap_error = res;
     684           0 :                 if (res != 0) {
     685           0 :                         DEBUG(1,("NetGroupGetUsers gave error %d\n", res));
     686             :                 }
     687             :         }
     688             : 
     689           0 :         if (!rdata) {
     690           0 :                 DEBUG(4,("NetGroupGetUsers no data returned\n"));
     691           0 :                 goto out;
     692             :         }
     693             : 
     694           0 :         if (res == 0 || res == ERRmoredata) {
     695           0 :                 char *endp = rparam + rprcnt;
     696           0 :                 int i, count = 0;
     697           0 :                 char username[RAP_USERNAME_LEN];
     698             : 
     699           0 :                 p = rparam + WORDSIZE + WORDSIZE;
     700           0 :                 GETWORD(p, count, endp);
     701             : 
     702           0 :                 endp = rdata + rdrcnt;
     703           0 :                 for (i=0,p=rdata; i<count && p < endp; i++) {
     704           0 :                         p += rap_getstringf(p,
     705             :                                         username,
     706             :                                         RAP_USERNAME_LEN,
     707             :                                         RAP_USERNAME_LEN,
     708             :                                         endp);
     709           0 :                         if (username[0]) {
     710           0 :                                 fn(username, state);
     711             :                         }
     712             :                 }
     713             :         } else {
     714           0 :                 DEBUG(4,("NetGroupGetUsers res=%d\n", res));
     715             :         }
     716             : 
     717           0 :   out:
     718             : 
     719           0 :         SAFE_FREE(rdata);
     720           0 :         SAFE_FREE(rparam);
     721           0 :         return res;
     722             : }
     723             : 
     724           0 : int cli_NetUserGetGroups(struct cli_state * cli, const char *user_name, void (*fn)(const char *, void *), void *state )
     725             : {
     726           0 :         char *rparam = NULL;
     727           0 :         char *rdata = NULL;
     728           0 :         char *p;
     729           0 :         unsigned int rdrcnt,rprcnt;
     730           0 :         int res = -1;
     731           0 :         char param[WORDSIZE                        /* api number    */
     732             :                 +sizeof(RAP_NetUserGetGroups_REQ)/* parm string   */
     733             :                 +sizeof(RAP_GROUP_USERS_INFO_0)  /* return string */
     734             :                 +RAP_USERNAME_LEN               /* user name    */
     735             :                 +WORDSIZE                        /* info level    */
     736             :                 +WORDSIZE];                      /* buffer size   */
     737             : 
     738             :         /* now send a SMBtrans command with api GroupGetUsers */
     739           0 :         p = make_header(param, RAP_WUserGetGroups,
     740             :                 RAP_NetUserGetGroups_REQ, RAP_GROUP_USERS_INFO_0);
     741           0 :         PUTSTRING(p,user_name,RAP_USERNAME_LEN-1);
     742           0 :         PUTWORD(p,0); /* info level 0 */
     743           0 :         PUTWORD(p,0xFFE0); /* return buffer size */
     744             : 
     745           0 :         if (cli_api(cli,
     746           0 :                         param, PTR_DIFF(p,param),PTR_DIFF(p,param),
     747             :                         NULL, 0, CLI_BUFFER_SIZE,
     748             :                         &rparam, &rprcnt,
     749             :                         &rdata, &rdrcnt)) {
     750           0 :                 char *endp = rparam + rprcnt;
     751           0 :                 res = GETRES(rparam,endp);
     752           0 :                 cli->rap_error = res;
     753           0 :                 if (res != 0) {
     754           0 :                         DEBUG(1,("NetUserGetGroups gave error %d\n", res));
     755             :                 }
     756             :         }
     757             : 
     758           0 :         if (!rdata) {
     759           0 :                 DEBUG(4,("NetUserGetGroups no data returned\n"));
     760           0 :                 goto out;
     761             :         }
     762             : 
     763           0 :         if (res == 0 || res == ERRmoredata) {
     764           0 :                 char *endp = rparam + rprcnt;
     765           0 :                 int i, count = 0;
     766           0 :                 char groupname[RAP_GROUPNAME_LEN];
     767             : 
     768           0 :                 p = rparam + WORDSIZE + WORDSIZE;
     769           0 :                 GETWORD(p, count, endp);
     770             : 
     771           0 :                 endp = rdata + rdrcnt;
     772           0 :                 for (i=0,p=rdata; i<count && p < endp; i++) {
     773           0 :                         p += rap_getstringf(p,
     774             :                                         groupname,
     775             :                                         RAP_GROUPNAME_LEN,
     776             :                                         RAP_GROUPNAME_LEN,
     777             :                                         endp);
     778           0 :                         if (groupname[0]) {
     779           0 :                                 fn(groupname, state);
     780             :                         }
     781             :                 }
     782             :         } else {
     783           0 :                 DEBUG(4,("NetUserGetGroups res=%d\n", res));
     784             :         }
     785             : 
     786           0 :   out:
     787             : 
     788           0 :         SAFE_FREE(rdata);
     789           0 :         SAFE_FREE(rparam);
     790           0 :         return res;
     791             : }
     792             : 
     793             : /****************************************************************************
     794             :  Call a NetUserDelete - delete user from remote server.
     795             : ****************************************************************************/
     796             : 
     797           0 : int cli_NetUserDelete(struct cli_state *cli, const char * user_name )
     798             : {
     799           0 :         char *rparam = NULL;
     800           0 :         char *rdata = NULL;
     801           0 :         char *p;
     802           0 :         unsigned int rdrcnt,rprcnt;
     803           0 :         int res = -1;
     804           0 :         char param[WORDSIZE                    /* api number    */
     805             :                 +sizeof(RAP_NetGroupDel_REQ) /* parm string   */
     806             :                 +1                           /* no ret string */
     807             :                 +RAP_USERNAME_LEN            /* user to del   */
     808             :                 +WORDSIZE];                  /* reserved word */
     809             : 
     810             :         /* now send a SMBtrans command with api UserDel */
     811           0 :         p = make_header(param, RAP_WUserDel, RAP_NetGroupDel_REQ, NULL);
     812           0 :         PUTSTRING(p, user_name, RAP_USERNAME_LEN);
     813           0 :         PUTWORD(p,0);  /* reserved word MBZ on input */
     814             : 
     815           0 :         if (cli_api(cli,
     816           0 :                         param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
     817             :                         NULL, 0, 200,       /* data, length, maxlen */
     818             :                         &rparam, &rprcnt,   /* return params, length */
     819             :                         &rdata, &rdrcnt))   /* return data, length */
     820             :         {
     821           0 :                 char *endp = rparam + rprcnt;
     822           0 :                 res = GETRES(rparam,endp);
     823             : 
     824           0 :                 if (res == 0) {
     825             :                         /* nothing to do */
     826           0 :                 } else if ((res == 5) || (res == 65)) {
     827           0 :                         DEBUG(1, ("Access Denied\n"));
     828           0 :                 } else if (res == 2221) {
     829           0 :                         DEBUG (1, ("User does not exist\n"));
     830             :                 } else {
     831           0 :                         DEBUG(4,("NetUserDelete res=%d\n", res));
     832             :                 }
     833             :         } else {
     834           0 :                 res = -1;
     835           0 :                 DEBUG(4,("NetUserDelete failed\n"));
     836             :         }
     837             : 
     838           0 :         SAFE_FREE(rparam);
     839           0 :         SAFE_FREE(rdata);
     840             : 
     841           0 :         return res;
     842             : }
     843             : 
     844             : /****************************************************************************
     845             :  Call a NetUserAdd - add user to remote server.
     846             : ****************************************************************************/
     847             : 
     848           0 : int cli_NetUserAdd(struct cli_state *cli, struct rap_user_info_1 * userinfo )
     849             : {
     850           0 :         char *rparam = NULL;
     851           0 :         char *rdata = NULL;
     852           0 :         char *p;
     853           0 :         unsigned int rdrcnt,rprcnt;
     854           0 :         int res = -1;
     855           0 :         char param[WORDSIZE                    /* api number    */
     856             :                 +sizeof(RAP_NetUserAdd2_REQ) /* req string    */
     857             :                 +sizeof(RAP_USER_INFO_L1)    /* data string   */
     858             :                 +WORDSIZE                    /* info level    */
     859             :                 +WORDSIZE                    /* buffer length */
     860             :                 +WORDSIZE];                  /* reserved      */
     861             : 
     862           0 :         char data[1024];
     863             :                 /* offset into data of free format strings.  Will be updated */
     864             :                 /* by PUTSTRINGP macro and end up with total data length.    */
     865           0 :         int soffset=RAP_USERNAME_LEN+1 /* user name + pad */
     866             :                 + RAP_UPASSWD_LEN            /* password        */
     867             :                 + DWORDSIZE                  /* password age    */
     868             :                 + WORDSIZE                   /* privilege       */
     869             :                 + DWORDSIZE                  /* home dir ptr    */
     870             :                 + DWORDSIZE                  /* comment ptr     */
     871             :                 + WORDSIZE                   /* flags           */
     872             :                 + DWORDSIZE;                 /* login script ptr*/
     873             : 
     874             :         /* now send a SMBtrans command with api NetUserAdd */
     875           0 :         p = make_header(param, RAP_WUserAdd2,
     876             :                 RAP_NetUserAdd2_REQ, RAP_USER_INFO_L1);
     877             : 
     878           0 :         PUTWORD(p, 1); /* info level */
     879           0 :         PUTWORD(p, 0); /* pwencrypt */
     880           0 :         PUTWORD(p, MIN(strlen((const char *)userinfo->passwrd),
     881             :                        RAP_UPASSWD_LEN));
     882             : 
     883           0 :         p = data;
     884           0 :         memset(data, '\0', soffset);
     885             : 
     886           0 :         PUTSTRINGF(p, (const char *)userinfo->user_name, RAP_USERNAME_LEN);
     887           0 :         PUTBYTE(p, 0); /* pad byte 0 */
     888           0 :         PUTSTRINGF(p, (const char *)userinfo->passwrd, RAP_UPASSWD_LEN);
     889           0 :         PUTDWORD(p, 0); /* pw age - n.a. on user add */
     890           0 :         PUTWORD(p, userinfo->priv);
     891           0 :         PUTSTRINGP(p, userinfo->home_dir, data, soffset);
     892           0 :         PUTSTRINGP(p, userinfo->comment, data, soffset);
     893           0 :         PUTWORD(p, userinfo->userflags);
     894           0 :         PUTSTRINGP(p, userinfo->logon_script, data, soffset);
     895             : 
     896           0 :         if (cli_api(cli,
     897             :                       param, sizeof(param), 1024, /* Param, length, maxlen */
     898             :                       data, soffset, sizeof(data), /* data, length, maxlen */
     899             :                       &rparam, &rprcnt,   /* return params, length */
     900             :                       &rdata, &rdrcnt))   /* return data, length */
     901             :         {
     902           0 :                 char *endp = rparam + rprcnt;
     903           0 :                 res = GETRES(rparam, endp);
     904             : 
     905           0 :                 if (res == 0) {
     906             :                         /* nothing to do */
     907           0 :                 } else if ((res == 5) || (res == 65)) {
     908           0 :                         DEBUG(1, ("Access Denied\n"));
     909           0 :                 } else if (res == 2224) {
     910           0 :                         DEBUG (1, ("User already exists\n"));
     911             :                 } else {
     912           0 :                         DEBUG(4,("NetUserAdd res=%d\n", res));
     913             :                 }
     914             :         } else {
     915           0 :                 res = -1;
     916           0 :                 DEBUG(4,("NetUserAdd failed\n"));
     917             :         }
     918             : 
     919           0 :         SAFE_FREE(rparam);
     920           0 :         SAFE_FREE(rdata);
     921             : 
     922           0 :         return res;
     923             : }
     924             : 
     925             : /****************************************************************************
     926             : call a NetUserEnum - try and list users on a different host
     927             : ****************************************************************************/
     928             : 
     929           0 : int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char *, const char *, const char *, void *), void *state)
     930             : {
     931           0 :         char param[WORDSIZE                 /* api number    */
     932             :                 +sizeof(RAP_NetUserEnum_REQ) /* parm string   */
     933             :                 +sizeof(RAP_USER_INFO_L1)    /* return string */
     934             :                 +WORDSIZE                 /* info level    */
     935             :                 +WORDSIZE];               /* buffer size   */
     936           0 :         char *p;
     937           0 :         char *rparam = NULL;
     938           0 :         char *rdata = NULL;
     939           0 :         unsigned int rprcnt, rdrcnt;
     940           0 :         int res = -1;
     941             : 
     942           0 :         memset(param, '\0', sizeof(param));
     943           0 :         p = make_header(param, RAP_WUserEnum,
     944             :                 RAP_NetUserEnum_REQ, RAP_USER_INFO_L1);
     945           0 :         PUTWORD(p,1); /* Info level 1 */
     946           0 :         PUTWORD(p,0xFF00); /* Return buffer size */
     947             : 
     948             :         /* BB Fix handling of large numbers of users to be returned */
     949           0 :         if (cli_api(cli,
     950           0 :                         param, PTR_DIFF(p,param),8,
     951             :                         NULL, 0, CLI_BUFFER_SIZE,
     952             :                         &rparam, &rprcnt,
     953             :                         &rdata, &rdrcnt)) {
     954           0 :                 char *endp = rparam + rprcnt;
     955           0 :                 res = GETRES(rparam,endp);
     956           0 :                 cli->rap_error = res;
     957           0 :                 if (cli->rap_error != 0) {
     958           0 :                         DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
     959             :                 }
     960             :         }
     961             : 
     962           0 :         if (!rdata) {
     963           0 :                 DEBUG(4,("NetUserEnum no data returned\n"));
     964           0 :                 goto out;
     965             :         }
     966             : 
     967           0 :         if (res == 0 || res == ERRmoredata) {
     968           0 :                 int i, converter = 0, count = 0;
     969           0 :                 char username[RAP_USERNAME_LEN];
     970           0 :                 char userpw[RAP_UPASSWD_LEN];
     971           0 :                 char *endp = rparam + rprcnt;
     972           0 :                 char *comment, *homedir, *logonscript;
     973           0 :                 TALLOC_CTX *frame = talloc_stackframe();
     974             : 
     975           0 :                 p = rparam + WORDSIZE; /* skip result */
     976           0 :                 GETWORD(p, converter, endp);
     977           0 :                 GETWORD(p, count, endp);
     978             : 
     979           0 :                 endp = rdata + rdrcnt;
     980           0 :                 for (i=0,p=rdata;i<count && p < endp;i++) {
     981           0 :                         p += rap_getstringf(p,
     982             :                                         username,
     983             :                                         RAP_USERNAME_LEN,
     984             :                                         RAP_USERNAME_LEN,
     985             :                                         endp);
     986           0 :                         p++; /* pad byte */
     987           0 :                         p += rap_getstringf(p,
     988             :                                         userpw,
     989             :                                         RAP_UPASSWD_LEN,
     990             :                                         RAP_UPASSWD_LEN,
     991             :                                         endp);
     992           0 :                         p += DWORDSIZE; /* skip password age */
     993           0 :                         p += WORDSIZE;  /* skip priv: 0=guest, 1=user, 2=admin */
     994           0 :                         p += rap_getstringp(frame,
     995             :                                         p,
     996             :                                         &homedir,
     997             :                                         rdata,
     998             :                                         converter,
     999             :                                         endp);
    1000           0 :                         p += rap_getstringp(frame,
    1001             :                                         p,
    1002             :                                         &comment,
    1003             :                                         rdata,
    1004             :                                         converter,
    1005             :                                         endp);
    1006           0 :                         p += WORDSIZE;  /* skip flags */
    1007           0 :                         p += rap_getstringp(frame,
    1008             :                                         p,
    1009             :                                         &logonscript,
    1010             :                                         rdata,
    1011             :                                         converter,
    1012             :                                         endp);
    1013           0 :                         if (username[0] && comment &&
    1014           0 :                                         homedir && logonscript) {
    1015           0 :                                 fn(username,
    1016             :                                         comment,
    1017             :                                         homedir,
    1018             :                                         logonscript,
    1019             :                                         cli);
    1020             :                         }
    1021             :                 }
    1022           0 :                 TALLOC_FREE(frame);
    1023             :         } else {
    1024           0 :                 DEBUG(4,("NetUserEnum res=%d\n", res));
    1025             :         }
    1026             : 
    1027           0 :   out:
    1028             : 
    1029           0 :         SAFE_FREE(rparam);
    1030           0 :         SAFE_FREE(rdata);
    1031             : 
    1032           0 :         return res;
    1033             : }
    1034             : 
    1035           0 : int cli_RNetUserEnum0(struct cli_state *cli,
    1036             :                       void (*fn)(const char *, void *),
    1037             :                       void *state)
    1038             : {
    1039           0 :         char param[WORDSIZE                 /* api number    */
    1040             :                 +sizeof(RAP_NetUserEnum_REQ) /* parm string   */
    1041             :                 +sizeof(RAP_USER_INFO_L0)    /* return string */
    1042             :                 +WORDSIZE                 /* info level    */
    1043             :                 +WORDSIZE];               /* buffer size   */
    1044           0 :         char *p;
    1045           0 :         char *rparam = NULL;
    1046           0 :         char *rdata = NULL;
    1047           0 :         unsigned int rprcnt, rdrcnt;
    1048           0 :         int res = -1;
    1049             : 
    1050           0 :         memset(param, '\0', sizeof(param));
    1051           0 :         p = make_header(param, RAP_WUserEnum,
    1052             :                 RAP_NetUserEnum_REQ, RAP_USER_INFO_L0);
    1053           0 :         PUTWORD(p,0); /* Info level 1 */
    1054           0 :         PUTWORD(p,0xFF00); /* Return buffer size */
    1055             : 
    1056             :         /* BB Fix handling of large numbers of users to be returned */
    1057           0 :         if (cli_api(cli,
    1058           0 :                         param, PTR_DIFF(p,param),8,
    1059             :                         NULL, 0, CLI_BUFFER_SIZE,
    1060             :                         &rparam, &rprcnt,
    1061             :                         &rdata, &rdrcnt)) {
    1062           0 :                 char *endp = rparam + rprcnt;
    1063           0 :                 res = GETRES(rparam,endp);
    1064           0 :                 cli->rap_error = res;
    1065           0 :                 if (cli->rap_error != 0) {
    1066           0 :                         DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
    1067             :                 }
    1068             :         }
    1069             : 
    1070           0 :         if (!rdata) {
    1071           0 :                 DEBUG(4,("NetUserEnum no data returned\n"));
    1072           0 :                 goto out;
    1073             :         }
    1074             : 
    1075           0 :         if (res == 0 || res == ERRmoredata) {
    1076           0 :                 int i, count = 0;
    1077           0 :                 char *endp = rparam + rprcnt;
    1078           0 :                 char username[RAP_USERNAME_LEN];
    1079             : 
    1080           0 :                 p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
    1081           0 :                 GETWORD(p, count, endp);
    1082             : 
    1083           0 :                 endp = rdata + rdrcnt;
    1084           0 :                 for (i=0,p=rdata;i<count && p < endp;i++) {
    1085           0 :                         p += rap_getstringf(p,
    1086             :                                         username,
    1087             :                                         RAP_USERNAME_LEN,
    1088             :                                         RAP_USERNAME_LEN,
    1089             :                                         endp);
    1090           0 :                         if (username[0]) {
    1091           0 :                                 fn(username, cli);
    1092             :                         }
    1093             :                 }
    1094             :         } else {
    1095           0 :                 DEBUG(4,("NetUserEnum res=%d\n", res));
    1096             :         }
    1097             : 
    1098           0 :   out:
    1099             : 
    1100           0 :         SAFE_FREE(rparam);
    1101           0 :         SAFE_FREE(rdata);
    1102             : 
    1103           0 :         return res;
    1104             : }
    1105             : 
    1106             : /****************************************************************************
    1107             :  Call a NetFileClose2 - close open file on another session to server.
    1108             : ****************************************************************************/
    1109             : 
    1110           0 : int cli_NetFileClose(struct cli_state *cli, uint32_t file_id )
    1111             : {
    1112           0 :         char *rparam = NULL;
    1113           0 :         char *rdata = NULL;
    1114           0 :         char *p;
    1115           0 :         unsigned int rdrcnt,rprcnt;
    1116           0 :         char param[WORDSIZE                    /* api number    */
    1117             :                 +sizeof(RAP_WFileClose2_REQ) /* req string    */
    1118             :                 +1                           /* no ret string */
    1119             :                 +DWORDSIZE];                 /* file ID          */
    1120           0 :         int res = -1;
    1121             : 
    1122             :         /* now send a SMBtrans command with api RNetShareEnum */
    1123           0 :         p = make_header(param, RAP_WFileClose2, RAP_WFileClose2_REQ, NULL);
    1124           0 :         PUTDWORD(p, file_id);
    1125             : 
    1126           0 :         if (cli_api(cli,
    1127           0 :                         param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
    1128             :                         NULL, 0, 200,       /* data, length, maxlen */
    1129             :                         &rparam, &rprcnt,   /* return params, length */
    1130             :                         &rdata, &rdrcnt))   /* return data, length */
    1131             :         {
    1132           0 :                 char *endp = rparam + rprcnt;
    1133           0 :                 res = GETRES(rparam, endp);
    1134             : 
    1135           0 :                 if (res == 0) {
    1136             :                         /* nothing to do */
    1137           0 :                 } else if (res == 2314){
    1138           0 :                         DEBUG(1, ("NetFileClose2 - attempt to close non-existent file open instance\n"));
    1139             :                 } else {
    1140           0 :                         DEBUG(4,("NetFileClose2 res=%d\n", res));
    1141             :                 }
    1142             :         } else {
    1143           0 :                 res = -1;
    1144           0 :                 DEBUG(4,("NetFileClose2 failed\n"));
    1145             :         }
    1146             : 
    1147           0 :         SAFE_FREE(rparam);
    1148           0 :         SAFE_FREE(rdata);
    1149             : 
    1150           0 :         return res;
    1151             : }
    1152             : 
    1153             : /****************************************************************************
    1154             :  Call a NetFileGetInfo - get information about server file opened from other
    1155             :  workstation.
    1156             : ****************************************************************************/
    1157             : 
    1158           0 : int cli_NetFileGetInfo(struct cli_state *cli, uint32_t file_id, void (*fn)(const char *, const char *, uint16_t, uint16_t, uint32_t))
    1159             : {
    1160           0 :         char *rparam = NULL;
    1161           0 :         char *rdata = NULL;
    1162           0 :         char *p;
    1163           0 :         unsigned int rdrcnt,rprcnt;
    1164           0 :         int res = -1;
    1165           0 :         char param[WORDSIZE                      /* api number      */
    1166             :                 +sizeof(RAP_WFileGetInfo2_REQ) /* req string      */
    1167             :                 +sizeof(RAP_FILE_INFO_L3)      /* return string   */
    1168             :                 +DWORDSIZE                     /* file ID          */
    1169             :                 +WORDSIZE                      /* info level      */
    1170             :                 +WORDSIZE];                    /* buffer size     */
    1171             : 
    1172             :         /* now send a SMBtrans command with api RNetShareEnum */
    1173           0 :         p = make_header(param, RAP_WFileGetInfo2,
    1174             :                 RAP_WFileGetInfo2_REQ, RAP_FILE_INFO_L3);
    1175           0 :         PUTDWORD(p, file_id);
    1176           0 :         PUTWORD(p, 3);  /* info level */
    1177           0 :         PUTWORD(p, 0x1000);   /* buffer size */
    1178           0 :         if (cli_api(cli,
    1179           0 :                         param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
    1180             :                         NULL, 0, 0x1000,  /* data, length, maxlen */
    1181             :                         &rparam, &rprcnt,               /* return params, length */
    1182             :                         &rdata, &rdrcnt))               /* return data, length */
    1183             :         {
    1184           0 :                 char *endp = rparam + rprcnt;
    1185           0 :                 res = GETRES(rparam,endp);
    1186           0 :                 if (res == 0 || res == ERRmoredata) {
    1187           0 :                         TALLOC_CTX *frame = talloc_stackframe();
    1188           0 :                         int converter = 0,id = 0, perms = 0, locks = 0;
    1189           0 :                         char *fpath, *fuser;
    1190             : 
    1191           0 :                         p = rparam + WORDSIZE; /* skip result */
    1192           0 :                         GETWORD(p, converter, endp);
    1193             : 
    1194           0 :                         p = rdata;
    1195           0 :                         endp = rdata + rdrcnt;
    1196             : 
    1197           0 :                         GETDWORD(p, id, endp);
    1198           0 :                         GETWORD(p, perms, endp);
    1199           0 :                         GETWORD(p, locks, endp);
    1200             : 
    1201           0 :                         p += rap_getstringp(frame,
    1202             :                                         p,
    1203             :                                         &fpath,
    1204             :                                         rdata,
    1205             :                                         converter,
    1206             :                                         endp);
    1207           0 :                         rap_getstringp(frame,
    1208             :                                         p,
    1209             :                                         &fuser,
    1210             :                                         rdata,
    1211             :                                         converter,
    1212             :                                         endp);
    1213             : 
    1214           0 :                         if (fpath && fuser) {
    1215           0 :                                 fn(fpath, fuser, perms, locks, id);
    1216             :                         }
    1217             : 
    1218           0 :                         TALLOC_FREE(frame);
    1219             :                 } else {
    1220           0 :                         DEBUG(4,("NetFileGetInfo2 res=%d\n", res));
    1221             :                 }
    1222             :         } else {
    1223           0 :                 res = -1;
    1224           0 :                 DEBUG(4,("NetFileGetInfo2 failed\n"));
    1225             :         }
    1226             : 
    1227           0 :         SAFE_FREE(rparam);
    1228           0 :         SAFE_FREE(rdata);
    1229             : 
    1230           0 :         return res;
    1231             : }
    1232             : 
    1233             : /****************************************************************************
    1234             : * Call a NetFileEnum2 - list open files on an SMB server
    1235             : *
    1236             : * PURPOSE:  Remotes a NetFileEnum API call to the current server or target
    1237             : *           server listing the files open via the network (and their
    1238             : *           corresponding open instance ids)
    1239             : *
    1240             : * Dependencies: none
    1241             : *
    1242             : * Parameters:
    1243             : *             cli    - pointer to cli_state structure
    1244             : *             user   - if present, return only files opened by this remote user
    1245             : *             base_path - if present, return only files opened below this
    1246             : *                         base path
    1247             : *             fn     - display function to invoke for each entry in the result
    1248             : *
    1249             : *
    1250             : * Returns:
    1251             : *             True      - success
    1252             : *             False     - failure
    1253             : *
    1254             : ****************************************************************************/
    1255             : 
    1256           0 : int cli_NetFileEnum(struct cli_state *cli, const char * user,
    1257             :                     const char * base_path,
    1258             :                     void (*fn)(const char *, const char *, uint16_t, uint16_t,
    1259             :                                uint32_t))
    1260             : {
    1261           0 :         char *rparam = NULL;
    1262           0 :         char *rdata = NULL;
    1263           0 :         char *p;
    1264           0 :         unsigned int rdrcnt,rprcnt;
    1265           0 :         char param[WORDSIZE                   /* api number      */
    1266             :                 +sizeof(RAP_WFileEnum2_REQ) /* req string      */
    1267             :                 +sizeof(RAP_FILE_INFO_L3)   /* return string   */
    1268             :                 +1024                        /* base path (opt) */
    1269             :                 +RAP_USERNAME_LEN           /* user name (opt) */
    1270             :                 +WORDSIZE                   /* info level      */
    1271             :                 +WORDSIZE                   /* buffer size     */
    1272             :                 +DWORDSIZE                  /* resume key ?    */
    1273             :                 +DWORDSIZE];                /* resume key ?    */
    1274           0 :         int count = -1;
    1275           0 :         int res = -1;
    1276             : 
    1277             :         /* now send a SMBtrans command with api RNetShareEnum */
    1278           0 :         p = make_header(param, RAP_WFileEnum2,
    1279             :                 RAP_WFileEnum2_REQ, RAP_FILE_INFO_L3);
    1280             : 
    1281           0 :         PUTSTRING(p, base_path, 1024);
    1282           0 :         PUTSTRING(p, user, RAP_USERNAME_LEN);
    1283           0 :         PUTWORD(p, 3); /* info level */
    1284           0 :         PUTWORD(p, 0xFF00);  /* buffer size */
    1285           0 :         PUTDWORD(p, 0);  /* zero out the resume key */
    1286           0 :         PUTDWORD(p, 0);  /* or is this one the resume key? */
    1287             : 
    1288           0 :         if (cli_api(cli,
    1289           0 :                         param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
    1290             :                         NULL, 0, 0xFF00,  /* data, length, maxlen */
    1291             :                         &rparam, &rprcnt,               /* return params, length */
    1292             :                         &rdata, &rdrcnt))               /* return data, length */
    1293             :         {
    1294           0 :                 char *endp = rparam + rprcnt;
    1295           0 :                 res = GETRES(rparam, endp);
    1296             : 
    1297           0 :                 if (res == 0 || res == ERRmoredata) {
    1298           0 :                         TALLOC_CTX *frame = talloc_stackframe();
    1299           0 :                         int converter = 0, i;
    1300             : 
    1301           0 :                         p = rparam + WORDSIZE; /* skip result */
    1302           0 :                         GETWORD(p, converter, endp);
    1303           0 :                         GETWORD(p, count, endp);
    1304             : 
    1305           0 :                         p = rdata;
    1306           0 :                         endp = rdata + rdrcnt;
    1307           0 :                         for (i=0; i<count && p < endp; i++) {
    1308           0 :                                 int id = 0, perms = 0, locks = 0;
    1309           0 :                                 char *fpath, *fuser;
    1310             : 
    1311           0 :                                 GETDWORD(p, id, endp);
    1312           0 :                                 GETWORD(p, perms, endp);
    1313           0 :                                 GETWORD(p, locks, endp);
    1314           0 :                                 p += rap_getstringp(frame,
    1315             :                                         p,
    1316             :                                         &fpath,
    1317             :                                         rdata,
    1318             :                                         converter,
    1319             :                                         endp);
    1320           0 :                                 p += rap_getstringp(frame,
    1321             :                                         p,
    1322             :                                         &fuser,
    1323             :                                         rdata,
    1324             :                                         converter,
    1325             :                                         endp);
    1326             : 
    1327           0 :                                 if (fpath && fuser) {
    1328           0 :                                         fn(fpath, fuser, perms, locks, id);
    1329             :                                 }
    1330             :                         }  /* BB fix ERRmoredata case to send resume request */
    1331           0 :                         TALLOC_FREE(frame);
    1332             :                 } else {
    1333           0 :                         DEBUG(4,("NetFileEnum2 res=%d\n", res));
    1334             :                 }
    1335             :         } else {
    1336           0 :                 DEBUG(4,("NetFileEnum2 failed\n"));
    1337             :         }
    1338             : 
    1339           0 :         SAFE_FREE(rparam);
    1340           0 :         SAFE_FREE(rdata);
    1341             : 
    1342           0 :         return count;
    1343             : }
    1344             : 
    1345             : /****************************************************************************
    1346             :  Call a NetShareAdd - share/export directory on remote server.
    1347             : ****************************************************************************/
    1348             : 
    1349           0 : int cli_NetShareAdd(struct cli_state *cli, struct rap_share_info_2 * sinfo )
    1350             : {
    1351           0 :         char *rparam = NULL;
    1352           0 :         char *rdata = NULL;
    1353           0 :         char *p;
    1354           0 :         unsigned int rdrcnt,rprcnt;
    1355           0 :         int res = -1;
    1356           0 :         char param[WORDSIZE                  /* api number    */
    1357             :                 +sizeof(RAP_WShareAdd_REQ) /* req string    */
    1358             :                 +sizeof(RAP_SHARE_INFO_L2) /* return string */
    1359             :                 +WORDSIZE                  /* info level    */
    1360             :                 +WORDSIZE];                /* reserved word */
    1361           0 :         char data[1024];
    1362             :         /* offset to free format string section following fixed length data.  */
    1363             :         /* will be updated by PUTSTRINGP macro and will end up with total len */
    1364           0 :         int soffset = RAP_SHARENAME_LEN + 1 /* share name + pad   */
    1365             :                 + WORDSIZE                        /* share type    */
    1366             :                 + DWORDSIZE                       /* comment pointer */
    1367             :                 + WORDSIZE                        /* permissions */
    1368             :                 + WORDSIZE                        /* max users */
    1369             :                 + WORDSIZE                        /* active users */
    1370             :                 + DWORDSIZE                       /* share path */
    1371             :                 + RAP_SPASSWD_LEN + 1;            /* share password + pad */
    1372             : 
    1373           0 :         memset(param,'\0',sizeof(param));
    1374             :         /* now send a SMBtrans command with api RNetShareAdd */
    1375           0 :         p = make_header(param, RAP_WshareAdd,
    1376             :                 RAP_WShareAdd_REQ, RAP_SHARE_INFO_L2);
    1377           0 :         PUTWORD(p, 2); /* info level */
    1378           0 :         PUTWORD(p, 0); /* reserved word 0 */
    1379             : 
    1380           0 :         p = data;
    1381           0 :         PUTSTRINGF(p, (const char *)sinfo->share_name, RAP_SHARENAME_LEN);
    1382           0 :         PUTBYTE(p, 0); /* pad byte 0 */
    1383             : 
    1384           0 :         PUTWORD(p, sinfo->share_type);
    1385           0 :         PUTSTRINGP(p, sinfo->comment, data, soffset);
    1386           0 :         PUTWORD(p, sinfo->perms);
    1387           0 :         PUTWORD(p, sinfo->maximum_users);
    1388           0 :         PUTWORD(p, sinfo->active_users);
    1389           0 :         PUTSTRINGP(p, sinfo->path, data, soffset);
    1390           0 :         PUTSTRINGF(p, (const char *)sinfo->password, RAP_SPASSWD_LEN);
    1391           0 :         SCVAL(p,-1,0x0A); /* required 0x0A at end of password */
    1392             : 
    1393           0 :         if (cli_api(cli,
    1394             :                         param, sizeof(param), 1024, /* Param, length, maxlen */
    1395             :                         data, soffset, sizeof(data), /* data, length, maxlen */
    1396             :                         &rparam, &rprcnt,   /* return params, length */
    1397             :                         &rdata, &rdrcnt))   /* return data, length */
    1398             :         {
    1399           0 :                 char *endp = rparam + rprcnt;
    1400           0 :                 res = GETRES(rparam, endp);
    1401             : 
    1402           0 :                 if (res == 0) {
    1403             :                         /* nothing to do */
    1404             :                 } else {
    1405           0 :                         DEBUG(4,("NetShareAdd res=%d\n", res));
    1406             :                 }
    1407             :         } else {
    1408           0 :                 DEBUG(4,("NetShareAdd failed\n"));
    1409             :         }
    1410             : 
    1411           0 :         SAFE_FREE(rparam);
    1412           0 :         SAFE_FREE(rdata);
    1413             : 
    1414           0 :         return res;
    1415             : }
    1416             : 
    1417             : /****************************************************************************
    1418             :  Call a NetShareDelete - unshare exported directory on remote server.
    1419             : ****************************************************************************/
    1420             : 
    1421           0 : int cli_NetShareDelete(struct cli_state *cli, const char * share_name )
    1422             : {
    1423           0 :         char *rparam = NULL;
    1424           0 :         char *rdata = NULL;
    1425           0 :         char *p;
    1426           0 :         unsigned int rdrcnt,rprcnt;
    1427           0 :         int res = -1;
    1428           0 :         char param[WORDSIZE                  /* api number    */
    1429             :                 +sizeof(RAP_WShareDel_REQ) /* req string    */
    1430             :                 +1                         /* no ret string */
    1431             :                 +RAP_SHARENAME_LEN         /* share to del  */
    1432             :                 +WORDSIZE];                /* reserved word */
    1433             : 
    1434             :         /* now send a SMBtrans command with api RNetShareDelete */
    1435           0 :         p = make_header(param, RAP_WshareDel, RAP_WShareDel_REQ, NULL);
    1436           0 :         PUTSTRING(p,share_name,RAP_SHARENAME_LEN);
    1437           0 :         PUTWORD(p,0);  /* reserved word MBZ on input */
    1438             : 
    1439           0 :         if (cli_api(cli,
    1440           0 :                         param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
    1441             :                         NULL, 0, 200,       /* data, length, maxlen */
    1442             :                         &rparam, &rprcnt,   /* return params, length */
    1443             :                         &rdata, &rdrcnt))   /* return data, length */
    1444             :         {
    1445           0 :                 char *endp = rparam + rprcnt;
    1446           0 :                 res = GETRES(rparam, endp);
    1447             : 
    1448           0 :                 if (res == 0) {
    1449             :                         /* nothing to do */
    1450             :                 } else {
    1451           0 :                         DEBUG(4,("NetShareDelete res=%d\n", res));
    1452             :                 }
    1453             :         } else {
    1454           0 :                 DEBUG(4,("NetShareDelete failed\n"));
    1455             :         }
    1456             : 
    1457           0 :         SAFE_FREE(rparam);
    1458           0 :         SAFE_FREE(rdata);
    1459             : 
    1460           0 :         return res;
    1461             : }
    1462             : 
    1463             : /*************************************************************************
    1464             : *
    1465             : * Function Name:  cli_get_pdc_name
    1466             : *
    1467             : * PURPOSE:  Remotes a NetServerEnum API call to the current server
    1468             : *           requesting the name of a server matching the server
    1469             : *           type of SV_TYPE_DOMAIN_CTRL (PDC).
    1470             : *
    1471             : * Dependencies: none
    1472             : *
    1473             : * Parameters:
    1474             : *             cli       - pointer to cli_state structure
    1475             : *             workgroup - pointer to string containing name of domain
    1476             : *             pdc_name  - pointer to string that will contain PDC name
    1477             : *                         on successful return
    1478             : *
    1479             : * Returns:
    1480             : *             True      - success
    1481             : *             False     - failure
    1482             : *
    1483             : ************************************************************************/
    1484             : 
    1485           4 : bool cli_get_pdc_name(struct cli_state *cli, const char *workgroup, char **pdc_name)
    1486             : {
    1487           4 :         char *rparam = NULL;
    1488           4 :         char *rdata = NULL;
    1489           0 :         unsigned int rdrcnt,rprcnt;
    1490           0 :         char *p;
    1491           0 :         char param[WORDSIZE                       /* api number    */
    1492             :                 +sizeof(RAP_NetServerEnum2_REQ) /* req string    */
    1493             :                 +sizeof(RAP_SERVER_INFO_L1)     /* return string */
    1494             :                 +WORDSIZE                       /* info level    */
    1495             :                 +WORDSIZE                       /* buffer size   */
    1496             :                 +DWORDSIZE                      /* server type   */
    1497             :                 +RAP_MACHNAME_LEN];             /* workgroup     */
    1498           4 :         int count = -1;
    1499           4 :         int res = -1;
    1500             : 
    1501           4 :         *pdc_name = NULL;
    1502             : 
    1503             :         /* send a SMBtrans command with api NetServerEnum */
    1504           4 :         p = make_header(param, RAP_NetServerEnum2,
    1505             :                 RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L1);
    1506           4 :         PUTWORD(p, 1); /* info level */
    1507           4 :         PUTWORD(p, CLI_BUFFER_SIZE);
    1508           4 :         PUTDWORD(p, SV_TYPE_DOMAIN_CTRL);
    1509           4 :         PUTSTRING(p, workgroup, RAP_MACHNAME_LEN);
    1510             : 
    1511           4 :         if (cli_api(cli,
    1512           4 :                         param, PTR_DIFF(p,param), 8,        /* params, length, max */
    1513             :                         NULL, 0, CLI_BUFFER_SIZE,               /* data, length, max */
    1514             :                         &rparam, &rprcnt,                   /* return params, return size */
    1515             :                         &rdata, &rdrcnt                     /* return data, return size */
    1516             :                         )) {
    1517             : 
    1518           0 :                 char *endp = rparam + rprcnt;
    1519           0 :                 res = GETRES(rparam, endp);
    1520           0 :                 cli->rap_error = res;
    1521             : 
    1522             :                 /*
    1523             :                  * We only really care to copy a name if the
    1524             :                  * API succeeded and we got back a name.
    1525             :                  */
    1526           0 :                 if (cli->rap_error == 0) {
    1527           0 :                         p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
    1528           0 :                         GETWORD(p, count, endp);
    1529           0 :                         p = rdata;
    1530           0 :                         endp = rdata + rdrcnt;
    1531             : 
    1532           0 :                         if (count > 0) {
    1533           0 :                                 TALLOC_CTX *frame = talloc_stackframe();
    1534           0 :                                 char *dcname;
    1535           0 :                                 rap_getstring(frame,
    1536             :                                         p,
    1537             :                                         &dcname,
    1538             :                                         endp);
    1539           0 :                                 if (dcname) {
    1540           0 :                                         *pdc_name = SMB_STRDUP(dcname);
    1541             :                                 }
    1542           0 :                                 TALLOC_FREE(frame);
    1543             :                         }
    1544             :                 } else {
    1545           0 :                         DEBUG(4, ("cli_get_pdc_name: machine %s failed the "
    1546             :                                   "NetServerEnum call. Error was : %s.\n",
    1547             :                                   smbXcli_conn_remote_name(cli->conn),
    1548             :                                   win_errstr(W_ERROR(cli->rap_error))));
    1549             :                 }
    1550             :         }
    1551             : 
    1552           4 :         SAFE_FREE(rparam);
    1553           4 :         SAFE_FREE(rdata);
    1554             : 
    1555           4 :         return(count > 0);
    1556             : }
    1557             : 
    1558           0 : bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli,
    1559             :                          char **servername)
    1560             : {
    1561           0 :         char *rparam = NULL;
    1562           0 :         char *rdata = NULL;
    1563           0 :         unsigned int rdrcnt,rprcnt;
    1564           0 :         char *p;
    1565           0 :         char param[WORDSIZE                       /* api number    */
    1566             :                    +sizeof(RAP_WserverGetInfo_REQ) /* req string    */
    1567             :                    +sizeof(RAP_SERVER_INFO_L1)     /* return string */
    1568             :                    +WORDSIZE                       /* info level    */
    1569             :                    +WORDSIZE];                     /* buffer size   */
    1570           0 :         bool res = false;
    1571           0 :         char *endp;
    1572           0 :         fstring tmp;
    1573             : 
    1574             :         /* send a SMBtrans command with api NetServerGetInfo */
    1575           0 :         p = make_header(param, RAP_WserverGetInfo,
    1576             :                         RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1);
    1577           0 :         PUTWORD(p, 1); /* info level */
    1578           0 :         PUTWORD(p, CLI_BUFFER_SIZE);
    1579             : 
    1580           0 :         if (!cli_api(cli,
    1581           0 :                      param, PTR_DIFF(p,param), 8, /* params, length, max */
    1582             :                      NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
    1583             :                      &rparam, &rprcnt,         /* return params, return size */
    1584             :                      &rdata, &rdrcnt           /* return data, return size */
    1585             :                     )) {
    1586           0 :                 goto failed;
    1587             :         }
    1588             : 
    1589           0 :         endp = rparam + rprcnt;
    1590           0 :         if (GETRES(rparam, endp) != 0) {
    1591           0 :                 goto failed;
    1592             :         }
    1593             : 
    1594           0 :         if (rdrcnt < 16) {
    1595           0 :                 DEBUG(10, ("invalid data count %d, expected >= 16\n", rdrcnt));
    1596           0 :                 goto failed;
    1597             :         }
    1598             : 
    1599           0 :         if (pull_ascii(tmp, rdata, sizeof(tmp)-1, 16, STR_TERMINATE) == -1) {
    1600           0 :                 DEBUG(10, ("pull_ascii failed\n"));
    1601           0 :                 goto failed;
    1602             :         }
    1603             : 
    1604           0 :         if (!(*servername = talloc_strdup(mem_ctx, tmp))) {
    1605           0 :                 DEBUG(1, ("talloc_strdup failed\n"));
    1606           0 :                 goto failed;
    1607             :         }
    1608             : 
    1609           0 :         res = true;
    1610             : 
    1611           0 :  failed:
    1612           0 :         SAFE_FREE(rparam);
    1613           0 :         SAFE_FREE(rdata);
    1614           0 :         return res;
    1615             : }
    1616             : 
    1617             : /*************************************************************************
    1618             : *
    1619             : * Function Name:  cli_ns_check_server_type
    1620             : *
    1621             : * PURPOSE:  Remotes a NetServerEnum2 API call to the current server
    1622             : *           requesting server_info_0 level information of machines
    1623             : *           matching the given server type. If the returned server
    1624             : *           list contains the machine name contained in smbXcli_conn_remote_name(->conn)
    1625             : *           then we conclude the server type checks out. This routine
    1626             : *           is useful to retrieve list of server's of a certain
    1627             : *           type when all you have is a null session connection and
    1628             : *           can't remote API calls such as NetWkstaGetInfo or
    1629             : *           NetServerGetInfo.
    1630             : *
    1631             : * Dependencies: none
    1632             : *
    1633             : * Parameters:
    1634             : *             cli       - pointer to cli_state structure
    1635             : *             workgroup - pointer to string containing domain
    1636             : *             stype     - server type
    1637             : *
    1638             : * Returns:
    1639             : *             True      - success
    1640             : *             False     - failure
    1641             : *
    1642             : ************************************************************************/
    1643             : 
    1644           0 : bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32_t stype)
    1645             : {
    1646           0 :         char *rparam = NULL;
    1647           0 :         char *rdata = NULL;
    1648           0 :         unsigned int rdrcnt,rprcnt;
    1649           0 :         char *p;
    1650           0 :         char param[WORDSIZE                       /* api number    */
    1651             :                 +sizeof(RAP_NetServerEnum2_REQ) /* req string    */
    1652             :                 +sizeof(RAP_SERVER_INFO_L0)     /* return string */
    1653             :                 +WORDSIZE                       /* info level    */
    1654             :                 +WORDSIZE                       /* buffer size   */
    1655             :                 +DWORDSIZE                      /* server type   */
    1656             :                 +RAP_MACHNAME_LEN];             /* workgroup     */
    1657           0 :         bool found_server = false;
    1658           0 :         int res = -1;
    1659           0 :         const char *remote_name = smbXcli_conn_remote_name(cli->conn);
    1660             : 
    1661             :         /* send a SMBtrans command with api NetServerEnum */
    1662           0 :         p = make_header(param, RAP_NetServerEnum2,
    1663             :                         RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L0);
    1664           0 :         PUTWORD(p, 0); /* info level 0 */
    1665           0 :         PUTWORD(p, CLI_BUFFER_SIZE);
    1666           0 :         PUTDWORD(p, stype);
    1667           0 :         PUTSTRING(p, workgroup, RAP_MACHNAME_LEN);
    1668             : 
    1669           0 :         if (cli_api(cli,
    1670           0 :                         param, PTR_DIFF(p,param), 8, /* params, length, max */
    1671             :                         NULL, 0, CLI_BUFFER_SIZE,  /* data, length, max */
    1672             :                         &rparam, &rprcnt,          /* return params, return size */
    1673             :                         &rdata, &rdrcnt            /* return data, return size */
    1674             :                         )) {
    1675           0 :                 char *endp = rparam + rprcnt;
    1676           0 :                 res = GETRES(rparam,endp);
    1677           0 :                 cli->rap_error = res;
    1678             : 
    1679           0 :                 if (res == 0 || res == ERRmoredata) {
    1680           0 :                         int i, count = 0;
    1681             : 
    1682           0 :                         p = rparam + WORDSIZE + WORDSIZE;
    1683           0 :                         GETWORD(p, count,endp);
    1684             : 
    1685           0 :                         p = rdata;
    1686           0 :                         endp = rdata + rdrcnt;
    1687           0 :                         for (i = 0;i < count && p < endp;i++, p += 16) {
    1688           0 :                                 char ret_server[RAP_MACHNAME_LEN];
    1689             : 
    1690           0 :                                 p += rap_getstringf(p,
    1691             :                                                 ret_server,
    1692             :                                                 RAP_MACHNAME_LEN,
    1693             :                                                 RAP_MACHNAME_LEN,
    1694             :                                                 endp);
    1695           0 :                                 if (strequal(ret_server, remote_name)) {
    1696           0 :                                         found_server = true;
    1697           0 :                                         break;
    1698             :                                 }
    1699             :                         }
    1700             :                 } else {
    1701           0 :                         DEBUG(4, ("cli_ns_check_server_type: machine %s "
    1702             :                                   "failed the NetServerEnum call. Error was : "
    1703             :                                   "%s.\n", remote_name,
    1704             :                                   win_errstr(W_ERROR(cli->rap_error))));
    1705             :                 }
    1706             :         }
    1707             : 
    1708           0 :         SAFE_FREE(rparam);
    1709           0 :         SAFE_FREE(rdata);
    1710             : 
    1711           0 :         return found_server;
    1712             : }
    1713             : 
    1714             : /****************************************************************************
    1715             :  Perform a NetWkstaUserLogoff.
    1716             : ****************************************************************************/
    1717             : 
    1718           0 : bool cli_NetWkstaUserLogoff(struct cli_state *cli, const char *user, const char *workstation)
    1719             : {
    1720           0 :         char *rparam = NULL;
    1721           0 :         char *rdata = NULL;
    1722           0 :         char *p;
    1723           0 :         unsigned int rdrcnt,rprcnt;
    1724           0 :         char param[WORDSIZE                           /* api number    */
    1725             :                         +sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string    */
    1726             :                         +sizeof(RAP_USER_LOGOFF_INFO_L1)    /* return string */
    1727             :                         +RAP_USERNAME_LEN+1                 /* user name+pad */
    1728             :                         +RAP_MACHNAME_LEN                   /* wksta name    */
    1729             :                         +WORDSIZE                           /* buffer size   */
    1730             :                         +WORDSIZE];                         /* buffer size?  */
    1731           0 :         char upperbuf[MAX(RAP_USERNAME_LEN,RAP_MACHNAME_LEN)];
    1732           0 :         int res = -1;
    1733           0 :         char *tmp = NULL;
    1734             : 
    1735           0 :         memset(param, 0, sizeof(param));
    1736             : 
    1737             :         /* send a SMBtrans command with api NetWkstaUserLogoff */
    1738           0 :         p = make_header(param, RAP_WWkstaUserLogoff,
    1739             :                 RAP_NetWkstaUserLogoff_REQ, RAP_USER_LOGOFF_INFO_L1);
    1740           0 :         PUTDWORD(p, 0); /* Null pointer */
    1741           0 :         PUTDWORD(p, 0); /* Null pointer */
    1742           0 :         strlcpy(upperbuf, user, sizeof(upperbuf));
    1743           0 :         if (!strupper_m(upperbuf)) {
    1744           0 :                 return false;
    1745             :         }
    1746           0 :         tmp = upperbuf;
    1747           0 :         PUTSTRINGF(p, tmp, RAP_USERNAME_LEN);
    1748           0 :         p++; /* strange format, but ok */
    1749           0 :         strlcpy(upperbuf, workstation, sizeof(upperbuf));
    1750           0 :         if (!strupper_m(upperbuf)) {
    1751           0 :                 return false;
    1752             :         }
    1753           0 :         tmp = upperbuf;
    1754           0 :         PUTSTRINGF(p, tmp, RAP_MACHNAME_LEN);
    1755           0 :         PUTWORD(p, CLI_BUFFER_SIZE);
    1756           0 :         PUTWORD(p, CLI_BUFFER_SIZE);
    1757             : 
    1758           0 :         if (cli_api(cli,
    1759           0 :                         param, PTR_DIFF(p,param),1024,  /* param, length, max */
    1760             :                         NULL, 0, CLI_BUFFER_SIZE,       /* data, length, max */
    1761             :                         &rparam, &rprcnt,               /* return params, return size */
    1762             :                         &rdata, &rdrcnt                 /* return data, return size */
    1763             :                         )) {
    1764           0 :                 char *endp = rparam + rprcnt;
    1765           0 :                 res = GETRES(rparam,endp);
    1766           0 :                 cli->rap_error = res;
    1767             : 
    1768           0 :                 if (cli->rap_error != 0) {
    1769           0 :                         DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli->rap_error));
    1770             :                 }
    1771             :         }
    1772             : 
    1773           0 :         SAFE_FREE(rparam);
    1774           0 :         SAFE_FREE(rdata);
    1775           0 :         return (cli->rap_error == 0);
    1776             : }
    1777             : 
    1778           0 : int cli_NetPrintQEnum(struct cli_state *cli,
    1779             :                 void (*qfn)(const char*,uint16_t,uint16_t,uint16_t,const char*,const char*,const char*,const char*,const char*,uint16_t,uint16_t),
    1780             :                 void (*jfn)(uint16_t,const char*,const char*,const char*,const char*,uint16_t,uint16_t,const char*,unsigned int,unsigned int,const char*))
    1781             : {
    1782           0 :         char param[WORDSIZE                         /* api number    */
    1783             :                 +sizeof(RAP_NetPrintQEnum_REQ)    /* req string    */
    1784             :                 +sizeof(RAP_PRINTQ_INFO_L2)       /* return string */
    1785             :                 +WORDSIZE                         /* info level    */
    1786             :                 +WORDSIZE                         /* buffer size   */
    1787             :                 +sizeof(RAP_SMB_PRINT_JOB_L1)];   /* more ret data */
    1788           0 :         char *p;
    1789           0 :         char *rparam = NULL;
    1790           0 :         char *rdata = NULL;
    1791           0 :         unsigned int rprcnt, rdrcnt;
    1792           0 :         int res = -1;
    1793             : 
    1794           0 :         memset(param, '\0',sizeof(param));
    1795           0 :         p = make_header(param, RAP_WPrintQEnum,
    1796             :                 RAP_NetPrintQEnum_REQ, RAP_PRINTQ_INFO_L2);
    1797           0 :         PUTWORD(p,2); /* Info level 2 */
    1798           0 :         PUTWORD(p,0xFFE0); /* Return buffer size */
    1799           0 :         PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0);
    1800             : 
    1801           0 :         if (cli_api(cli,
    1802           0 :                         param, PTR_DIFF(p,param),1024,
    1803             :                         NULL, 0, CLI_BUFFER_SIZE,
    1804             :                         &rparam, &rprcnt,
    1805             :                         &rdata, &rdrcnt)) {
    1806           0 :                 char *endp = rparam + rprcnt;
    1807           0 :                 res = GETRES(rparam, endp);
    1808           0 :                 cli->rap_error = res;
    1809           0 :                 if (res != 0) {
    1810           0 :                         DEBUG(1,("NetPrintQEnum gave error %d\n", res));
    1811             :                 }
    1812             :         }
    1813             : 
    1814           0 :         if (!rdata) {
    1815           0 :                 DEBUG(4,("NetPrintQEnum no data returned\n"));
    1816           0 :                 goto out;
    1817             :         }
    1818             : 
    1819           0 :         if (res == 0 || res == ERRmoredata) {
    1820           0 :                 TALLOC_CTX *frame = talloc_stackframe();
    1821           0 :                 char *endp = rparam + rprcnt;
    1822           0 :                 int i, converter = 0, count = 0;
    1823             : 
    1824           0 :                 p = rparam + WORDSIZE;
    1825           0 :                 GETWORD(p, converter, endp);
    1826           0 :                 GETWORD(p, count, endp);
    1827             : 
    1828           0 :                 p = rdata;
    1829           0 :                 endp = rdata + rdrcnt;
    1830           0 :                 for (i=0;i<count && p < endp;i++) {
    1831           0 :                         char qname[RAP_SHARENAME_LEN];
    1832           0 :                         char *sep_file, *print_proc, *dest, *parms, *comment;
    1833           0 :                         uint16_t jobcount = 0, priority = 0;
    1834           0 :                         uint16_t start_time = 0, until_time = 0, status = 0;
    1835             : 
    1836           0 :                         p += rap_getstringf(p,
    1837             :                                         qname,
    1838             :                                         RAP_SHARENAME_LEN,
    1839             :                                         RAP_SHARENAME_LEN,
    1840             :                                         endp);
    1841           0 :                         p++; /* pad */
    1842           0 :                         GETWORD(p, priority, endp);
    1843           0 :                         GETWORD(p, start_time, endp);
    1844           0 :                         GETWORD(p, until_time, endp);
    1845           0 :                         p += rap_getstringp(frame,
    1846             :                                         p,
    1847             :                                         &sep_file,
    1848             :                                         rdata,
    1849             :                                         converter,
    1850             :                                         endp);
    1851           0 :                         p += rap_getstringp(frame,
    1852             :                                         p,
    1853             :                                         &print_proc,
    1854             :                                         rdata,
    1855             :                                         converter,
    1856             :                                         endp);
    1857           0 :                         p += rap_getstringp(frame,
    1858             :                                         p,
    1859             :                                         &dest,
    1860             :                                         rdata,
    1861             :                                         converter,
    1862             :                                         endp);
    1863           0 :                         p += rap_getstringp(frame,
    1864             :                                         p,
    1865             :                                         &parms,
    1866             :                                         rdata,
    1867             :                                         converter,
    1868             :                                         endp);
    1869           0 :                         p += rap_getstringp(frame,
    1870             :                                         p,
    1871             :                                         &comment,
    1872             :                                         rdata,
    1873             :                                         converter,
    1874             :                                         endp);
    1875           0 :                         GETWORD(p, status, endp);
    1876           0 :                         GETWORD(p, jobcount, endp);
    1877             : 
    1878           0 :                         if (sep_file && print_proc && dest && parms &&
    1879             :                                         comment) {
    1880           0 :                                 qfn(qname, priority, start_time, until_time, sep_file, print_proc,
    1881             :                                         dest, parms, comment, status, jobcount);
    1882             :                         }
    1883             : 
    1884           0 :                         if (jobcount) {
    1885             :                                 int j;
    1886           0 :                                 for (j=0;j<jobcount;j++) {
    1887           0 :                                         uint16_t jid = 0, pos = 0, fsstatus = 0;
    1888           0 :                                         char ownername[RAP_USERNAME_LEN];
    1889           0 :                                         char notifyname[RAP_MACHNAME_LEN];
    1890           0 :                                         char datatype[RAP_DATATYPE_LEN];
    1891           0 :                                         char *jparms, *jstatus, *jcomment;
    1892           0 :                                         unsigned int submitted = 0, jsize = 0;
    1893             : 
    1894           0 :                                         GETWORD(p, jid, endp);
    1895           0 :                                         p += rap_getstringf(p,
    1896             :                                                         ownername,
    1897             :                                                         RAP_USERNAME_LEN,
    1898             :                                                         RAP_USERNAME_LEN,
    1899             :                                                         endp);
    1900           0 :                                         p++; /* pad byte */
    1901           0 :                                         p += rap_getstringf(p,
    1902             :                                                         notifyname,
    1903             :                                                         RAP_MACHNAME_LEN,
    1904             :                                                         RAP_MACHNAME_LEN,
    1905             :                                                         endp);
    1906           0 :                                         p += rap_getstringf(p,
    1907             :                                                         datatype,
    1908             :                                                         RAP_DATATYPE_LEN,
    1909             :                                                         RAP_DATATYPE_LEN,
    1910             :                                                         endp);
    1911           0 :                                         p += rap_getstringp(frame,
    1912             :                                                         p,
    1913             :                                                         &jparms,
    1914             :                                                         rdata,
    1915             :                                                         converter,
    1916             :                                                         endp);
    1917           0 :                                         GETWORD(p, pos, endp);
    1918           0 :                                         GETWORD(p, fsstatus, endp);
    1919           0 :                                         p += rap_getstringp(frame,
    1920             :                                                         p,
    1921             :                                                         &jstatus,
    1922             :                                                         rdata,
    1923             :                                                         converter,
    1924             :                                                         endp);
    1925           0 :                                         GETDWORD(p, submitted, endp);
    1926           0 :                                         GETDWORD(p, jsize, endp);
    1927           0 :                                         p += rap_getstringp(frame,
    1928             :                                                         p,
    1929             :                                                         &jcomment,
    1930             :                                                         rdata,
    1931             :                                                         converter,
    1932             :                                                         endp);
    1933             : 
    1934           0 :                                         if (jparms && jstatus && jcomment) {
    1935           0 :                                                 jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus,
    1936             :                                                         jstatus, submitted, jsize, jcomment);
    1937             :                                         }
    1938             :                                 }
    1939             :                         }
    1940             :                 }
    1941           0 :                 TALLOC_FREE(frame);
    1942             :         } else {
    1943           0 :                 DEBUG(4,("NetPrintQEnum res=%d\n", res));
    1944             :         }
    1945             : 
    1946           0 :   out:
    1947             : 
    1948           0 :         SAFE_FREE(rparam);
    1949           0 :         SAFE_FREE(rdata);
    1950             : 
    1951           0 :         return res;
    1952             : }
    1953             : 
    1954           0 : int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer,
    1955             :         void (*qfn)(const char*,uint16_t,uint16_t,uint16_t,const char*,const char*,const char*,const char*,const char*,uint16_t,uint16_t),
    1956             :         void (*jfn)(uint16_t,const char*,const char*,const char*,const char*,uint16_t,uint16_t,const char*,unsigned int,unsigned int,const char*))
    1957             : {
    1958           0 :         char param[WORDSIZE                         /* api number    */
    1959             :                 +sizeof(RAP_NetPrintQGetInfo_REQ) /* req string    */
    1960             :                 +sizeof(RAP_PRINTQ_INFO_L2)       /* return string */
    1961             :                 +RAP_SHARENAME_LEN                /* printer name  */
    1962             :                 +WORDSIZE                         /* info level    */
    1963             :                 +WORDSIZE                         /* buffer size   */
    1964             :                 +sizeof(RAP_SMB_PRINT_JOB_L1)];   /* more ret data */
    1965           0 :         char *p;
    1966           0 :         char *rparam = NULL;
    1967           0 :         char *rdata = NULL;
    1968           0 :         unsigned int rprcnt, rdrcnt;
    1969           0 :         int res = -1;
    1970             : 
    1971           0 :         memset(param, '\0',sizeof(param));
    1972           0 :         p = make_header(param, RAP_WPrintQGetInfo,
    1973             :                 RAP_NetPrintQGetInfo_REQ, RAP_PRINTQ_INFO_L2);
    1974           0 :         PUTSTRING(p, printer, RAP_SHARENAME_LEN-1);
    1975           0 :         PUTWORD(p, 2);     /* Info level 2 */
    1976           0 :         PUTWORD(p,0xFFE0); /* Return buffer size */
    1977           0 :         PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0);
    1978             : 
    1979           0 :         if (cli_api(cli,
    1980           0 :                         param, PTR_DIFF(p,param),1024,
    1981             :                         NULL, 0, CLI_BUFFER_SIZE,
    1982             :                         &rparam, &rprcnt,
    1983             :                         &rdata, &rdrcnt)) {
    1984           0 :                 char *endp = rparam + rprcnt;
    1985           0 :                 res = GETRES(rparam, endp);
    1986           0 :                 cli->rap_error = res;
    1987           0 :                 if (res != 0) {
    1988           0 :                         DEBUG(1,("NetPrintQGetInfo gave error %d\n", res));
    1989             :                 }
    1990             :         }
    1991             : 
    1992           0 :         if (!rdata) {
    1993           0 :                 DEBUG(4,("NetPrintQGetInfo no data returned\n"));
    1994           0 :                 goto out;
    1995             :         }
    1996             : 
    1997           0 :         if (res == 0 || res == ERRmoredata) {
    1998           0 :                 TALLOC_CTX *frame = talloc_stackframe();
    1999           0 :                 char *endp = rparam + rprcnt;
    2000           0 :                 int rsize = 0, converter = 0;
    2001           0 :                 char qname[RAP_SHARENAME_LEN];
    2002           0 :                 char *sep_file, *print_proc, *dest, *parms, *comment;
    2003           0 :                 uint16_t jobcount = 0, priority = 0;
    2004           0 :                 uint16_t start_time = 0, until_time = 0, status = 0;
    2005             : 
    2006           0 :                 p = rparam + WORDSIZE;
    2007           0 :                 GETWORD(p, converter, endp);
    2008           0 :                 GETWORD(p, rsize, endp);
    2009             : 
    2010           0 :                 p = rdata;
    2011           0 :                 endp = rdata + rdrcnt;
    2012           0 :                 p += rap_getstringf(p,
    2013             :                                 qname,
    2014             :                                 RAP_SHARENAME_LEN,
    2015             :                                 RAP_SHARENAME_LEN,
    2016             :                                 endp);
    2017           0 :                 p++; /* pad */
    2018           0 :                 GETWORD(p, priority, endp);
    2019           0 :                 GETWORD(p, start_time, endp);
    2020           0 :                 GETWORD(p, until_time, endp);
    2021           0 :                 p += rap_getstringp(frame,
    2022             :                                 p,
    2023             :                                 &sep_file,
    2024             :                                 rdata,
    2025             :                                 converter,
    2026             :                                 endp);
    2027           0 :                 p += rap_getstringp(frame,
    2028             :                                 p,
    2029             :                                 &print_proc,
    2030             :                                 rdata,
    2031             :                                 converter,
    2032             :                                 endp);
    2033           0 :                 p += rap_getstringp(frame,
    2034             :                                 p,
    2035             :                                 &dest,
    2036             :                                 rdata,
    2037             :                                 converter,
    2038             :                                 endp);
    2039           0 :                 p += rap_getstringp(frame,
    2040             :                                 p,
    2041             :                                 &parms,
    2042             :                                 rdata,
    2043             :                                 converter,
    2044             :                                 endp);
    2045           0 :                 p += rap_getstringp(frame,
    2046             :                                 p,
    2047             :                                 &comment,
    2048             :                                 rdata,
    2049             :                                 converter,
    2050             :                                 endp);
    2051           0 :                 GETWORD(p, status, endp);
    2052           0 :                 GETWORD(p, jobcount, endp);
    2053             : 
    2054           0 :                 if (sep_file && print_proc && dest &&
    2055           0 :                                 parms && comment) {
    2056           0 :                         qfn(qname, priority, start_time, until_time, sep_file, print_proc,
    2057             :                                 dest, parms, comment, status, jobcount);
    2058             :                 }
    2059           0 :                 if (jobcount) {
    2060             :                         int j;
    2061           0 :                         for (j=0;(j<jobcount)&&(PTR_DIFF(p,rdata)< rsize)&&
    2062           0 :                                         p<endp;j++) {
    2063           0 :                                 uint16_t jid = 0, pos = 0, fsstatus = 0;
    2064           0 :                                 char ownername[RAP_USERNAME_LEN];
    2065           0 :                                 char notifyname[RAP_MACHNAME_LEN];
    2066           0 :                                 char datatype[RAP_DATATYPE_LEN];
    2067           0 :                                 char *jparms, *jstatus, *jcomment;
    2068           0 :                                 unsigned int submitted = 0, jsize = 0;
    2069             : 
    2070           0 :                                 GETWORD(p, jid, endp);
    2071           0 :                                 p += rap_getstringf(p,
    2072             :                                                 ownername,
    2073             :                                                 RAP_USERNAME_LEN,
    2074             :                                                 RAP_USERNAME_LEN,
    2075             :                                                 endp);
    2076           0 :                                 p++; /* pad byte */
    2077           0 :                                 p += rap_getstringf(p,
    2078             :                                                 notifyname,
    2079             :                                                 RAP_MACHNAME_LEN,
    2080             :                                                 RAP_MACHNAME_LEN,
    2081             :                                                 endp);
    2082           0 :                                 p += rap_getstringf(p,
    2083             :                                                 datatype,
    2084             :                                                 RAP_DATATYPE_LEN,
    2085             :                                                 RAP_DATATYPE_LEN,
    2086             :                                                 endp);
    2087           0 :                                 p += rap_getstringp(frame,
    2088             :                                                 p,
    2089             :                                                 &jparms,
    2090             :                                                 rdata,
    2091             :                                                 converter,
    2092             :                                                 endp);
    2093           0 :                                 GETWORD(p, pos,endp);
    2094           0 :                                 GETWORD(p, fsstatus,endp);
    2095           0 :                                 p += rap_getstringp(frame,
    2096             :                                                 p,
    2097             :                                                 &jstatus,
    2098             :                                                 rdata,
    2099             :                                                 converter,
    2100             :                                                 endp);
    2101           0 :                                 GETDWORD(p, submitted,endp);
    2102           0 :                                 GETDWORD(p, jsize,endp);
    2103           0 :                                 p += rap_getstringp(frame,
    2104             :                                                 p,
    2105             :                                                 &jcomment,
    2106             :                                                 rdata,
    2107             :                                                 converter,
    2108             :                                                 endp);
    2109             : 
    2110           0 :                                 if (jparms && jstatus && jcomment) {
    2111           0 :                                         jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus,
    2112             :                                                 jstatus, submitted, jsize, jcomment);
    2113             :                                 }
    2114             :                         }
    2115             :                 }
    2116           0 :                 TALLOC_FREE(frame);
    2117             :         } else {
    2118           0 :                 DEBUG(4,("NetPrintQGetInfo res=%d\n", res));
    2119             :         }
    2120             : 
    2121           0 :   out:
    2122             : 
    2123           0 :         SAFE_FREE(rparam);
    2124           0 :         SAFE_FREE(rdata);
    2125             : 
    2126           0 :         return res;
    2127             : }
    2128             : 
    2129             : /****************************************************************************
    2130             :  Call a NetServiceEnum - list running services on a different host.
    2131             : ****************************************************************************/
    2132             : 
    2133           0 : int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state)
    2134             : {
    2135           0 :         char param[WORDSIZE                     /* api number    */
    2136             :                 +sizeof(RAP_NetServiceEnum_REQ) /* parm string   */
    2137             :                 +sizeof(RAP_SERVICE_INFO_L2)    /* return string */
    2138             :                 +WORDSIZE                     /* info level    */
    2139             :                 +WORDSIZE];                   /* buffer size   */
    2140           0 :         char *p;
    2141           0 :         char *rparam = NULL;
    2142           0 :         char *rdata = NULL;
    2143           0 :         unsigned int rprcnt, rdrcnt;
    2144           0 :         int res = -1;
    2145             : 
    2146           0 :         memset(param, '\0', sizeof(param));
    2147           0 :         p = make_header(param, RAP_WServiceEnum,
    2148             :                 RAP_NetServiceEnum_REQ, RAP_SERVICE_INFO_L2);
    2149           0 :         PUTWORD(p,2); /* Info level 2 */
    2150           0 :         PUTWORD(p,0xFFE0); /* Return buffer size */
    2151             : 
    2152           0 :         if (cli_api(cli,
    2153           0 :                         param, PTR_DIFF(p,param),8,
    2154             :                         NULL, 0, 0xFFE0 /* data area size */,
    2155             :                         &rparam, &rprcnt,
    2156             :                         &rdata, &rdrcnt)) {
    2157           0 :                 char *endp = rparam + rprcnt;
    2158           0 :                 res = GETRES(rparam, endp);
    2159           0 :                 cli->rap_error = res;
    2160           0 :                 if(cli->rap_error == 234) {
    2161           0 :                         DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n"));
    2162           0 :                 } else if (cli->rap_error != 0) {
    2163           0 :                         DEBUG(1,("NetServiceEnum gave error %d\n", cli->rap_error));
    2164             :                 }
    2165             :         }
    2166             : 
    2167           0 :         if (!rdata) {
    2168           0 :                 DEBUG(4,("NetServiceEnum no data returned\n"));
    2169           0 :                 goto out;
    2170             :         }
    2171             : 
    2172           0 :         if (res == 0 || res == ERRmoredata) {
    2173           0 :                 char *endp = rparam + rprcnt;
    2174           0 :                 int i, count = 0;
    2175             : 
    2176           0 :                 p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
    2177           0 :                 GETWORD(p, count,endp);
    2178             : 
    2179           0 :                 endp = rdata + rdrcnt;
    2180           0 :                 for (i=0,p=rdata;i<count && p < endp;i++) {
    2181           0 :                         char comment[RAP_SRVCCMNT_LEN];
    2182           0 :                         char servicename[RAP_SRVCNAME_LEN];
    2183             : 
    2184           0 :                         p += rap_getstringf(p,
    2185             :                                         servicename,
    2186             :                                         RAP_SRVCNAME_LEN,
    2187             :                                         RAP_SRVCNAME_LEN,
    2188             :                                         endp);
    2189           0 :                         p+=8; /* pass status words */
    2190           0 :                         p += rap_getstringf(p,
    2191             :                                         comment,
    2192             :                                         RAP_SRVCCMNT_LEN,
    2193             :                                         RAP_SRVCCMNT_LEN,
    2194             :                                         endp);
    2195             : 
    2196           0 :                         if (servicename[0]) {
    2197           0 :                                 fn(servicename, comment, cli);  /* BB add status too */
    2198             :                         }
    2199             :                 }
    2200             :         } else {
    2201           0 :                 DEBUG(4,("NetServiceEnum res=%d\n", res));
    2202             :         }
    2203             : 
    2204           0 :   out:
    2205             : 
    2206           0 :         SAFE_FREE(rparam);
    2207           0 :         SAFE_FREE(rdata);
    2208             : 
    2209           0 :         return res;
    2210             : }
    2211             : 
    2212             : /****************************************************************************
    2213             :  Call a NetSessionEnum - list workstations with sessions to an SMB server.
    2214             : ****************************************************************************/
    2215             : 
    2216           0 : int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16_t, uint16_t, uint16_t, unsigned int, unsigned int, unsigned int, char *))
    2217             : {
    2218           0 :         char param[WORDSIZE                       /* api number    */
    2219             :                 +sizeof(RAP_NetSessionEnum_REQ) /* parm string   */
    2220             :                 +sizeof(RAP_SESSION_INFO_L2)    /* return string */
    2221             :                 +WORDSIZE                       /* info level    */
    2222             :                 +WORDSIZE];                     /* buffer size   */
    2223           0 :         char *p;
    2224           0 :         char *rparam = NULL;
    2225           0 :         char *rdata = NULL;
    2226           0 :         unsigned int rprcnt, rdrcnt;
    2227           0 :         int res = -1;
    2228             : 
    2229           0 :         memset(param, '\0', sizeof(param));
    2230           0 :         p = make_header(param, RAP_WsessionEnum,
    2231             :                         RAP_NetSessionEnum_REQ, RAP_SESSION_INFO_L2);
    2232           0 :         PUTWORD(p,2);    /* Info level 2 */
    2233           0 :         PUTWORD(p,0xFF); /* Return buffer size */
    2234             : 
    2235           0 :         if (cli_api(cli,
    2236           0 :                         param, PTR_DIFF(p,param),8,
    2237             :                         NULL, 0, CLI_BUFFER_SIZE,
    2238             :                         &rparam, &rprcnt,
    2239             :                         &rdata, &rdrcnt)) {
    2240           0 :                 char *endp = rparam + rprcnt;
    2241           0 :                 res = GETRES(rparam, endp);
    2242           0 :                 cli->rap_error = res;
    2243           0 :                 if (res != 0) {
    2244           0 :                         DEBUG(1,("NetSessionEnum gave error %d\n", res));
    2245             :                 }
    2246             :         }
    2247             : 
    2248           0 :         if (!rdata) {
    2249           0 :                 DEBUG(4,("NetSessionEnum no data returned\n"));
    2250           0 :                 goto out;
    2251             :         }
    2252             : 
    2253           0 :         if (res == 0 || res == ERRmoredata) {
    2254           0 :                 TALLOC_CTX *frame = talloc_stackframe();
    2255           0 :                 char *endp = rparam + rprcnt;
    2256           0 :                 int i, converter = 0, count = 0;
    2257             : 
    2258           0 :                 p = rparam + WORDSIZE;
    2259           0 :                 GETWORD(p, converter, endp);
    2260           0 :                 GETWORD(p, count, endp);
    2261             : 
    2262           0 :                 endp = rdata + rdrcnt;
    2263           0 :                 for (i=0,p=rdata;i<count && p < endp;i++) {
    2264           0 :                         char *wsname, *username, *clitype_name;
    2265           0 :                         uint16_t num_conns = 0, num_opens = 0, num_users = 0;
    2266           0 :                         unsigned int sess_time = 0, idle_time = 0, user_flags = 0;
    2267             : 
    2268           0 :                         p += rap_getstringp(frame,
    2269             :                                         p,
    2270             :                                         &wsname,
    2271             :                                         rdata,
    2272             :                                         converter,
    2273             :                                         endp);
    2274           0 :                         p += rap_getstringp(frame,
    2275             :                                         p,
    2276             :                                         &username,
    2277             :                                         rdata,
    2278             :                                         converter,
    2279             :                                         endp);
    2280           0 :                         GETWORD(p, num_conns, endp);
    2281           0 :                         GETWORD(p, num_opens, endp);
    2282           0 :                         GETWORD(p, num_users, endp);
    2283           0 :                         GETDWORD(p, sess_time, endp);
    2284           0 :                         GETDWORD(p, idle_time, endp);
    2285           0 :                         GETDWORD(p, user_flags, endp);
    2286           0 :                         p += rap_getstringp(frame,
    2287             :                                         p,
    2288             :                                         &clitype_name,
    2289             :                                         rdata,
    2290             :                                         converter,
    2291             :                                         endp);
    2292             : 
    2293           0 :                         if (wsname && username && clitype_name) {
    2294           0 :                                 fn(wsname, username, num_conns, num_opens, num_users, sess_time,
    2295             :                                         idle_time, user_flags, clitype_name);
    2296             :                         }
    2297             :                 }
    2298           0 :                 TALLOC_FREE(frame);
    2299             :         } else {
    2300           0 :                 DEBUG(4,("NetSessionEnum res=%d\n", res));
    2301             :         }
    2302             : 
    2303           0 :   out:
    2304             : 
    2305           0 :         SAFE_FREE(rparam);
    2306           0 :         SAFE_FREE(rdata);
    2307             : 
    2308           0 :         return res;
    2309             : }
    2310             : 
    2311             : /****************************************************************************
    2312             :  Call a NetSessionGetInfo - get information about other session to an SMB server.
    2313             : ****************************************************************************/
    2314             : 
    2315           0 : int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation,
    2316             :                 void (*fn)(const char *, const char *, uint16_t, uint16_t, uint16_t, unsigned int, unsigned int, unsigned int, const char *))
    2317             : {
    2318           0 :         char param[WORDSIZE                          /* api number    */
    2319             :                 +sizeof(RAP_NetSessionGetInfo_REQ) /* req string    */
    2320             :                 +sizeof(RAP_SESSION_INFO_L2)       /* return string */
    2321             :                 +RAP_MACHNAME_LEN                  /* wksta name    */
    2322             :                 +WORDSIZE                          /* info level    */
    2323             :                 +WORDSIZE];                        /* buffer size   */
    2324           0 :         char *p;
    2325           0 :         char *rparam = NULL;
    2326           0 :         char *rdata = NULL;
    2327           0 :         unsigned int rprcnt, rdrcnt;
    2328           0 :         char *endp;
    2329           0 :         int res = -1;
    2330             : 
    2331           0 :         memset(param, '\0', sizeof(param));
    2332           0 :         p = make_header(param, RAP_WsessionGetInfo,
    2333             :                         RAP_NetSessionGetInfo_REQ, RAP_SESSION_INFO_L2);
    2334           0 :         PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1);
    2335           0 :         PUTWORD(p,2); /* Info level 2 */
    2336           0 :         PUTWORD(p,0xFF); /* Return buffer size */
    2337             : 
    2338           0 :         if (cli_api(cli,
    2339           0 :                         param, PTR_DIFF(p,param),PTR_DIFF(p,param),
    2340             :                         NULL, 0, CLI_BUFFER_SIZE,
    2341             :                         &rparam, &rprcnt,
    2342             :                         &rdata, &rdrcnt)) {
    2343           0 :                 endp = rparam + rprcnt;
    2344           0 :                 res = GETRES(rparam, endp);
    2345           0 :                 cli->rap_error = res;
    2346           0 :                 if (cli->rap_error != 0) {
    2347           0 :                         DEBUG(1,("NetSessionGetInfo gave error %d\n", cli->rap_error));
    2348             :                 }
    2349             :         }
    2350             : 
    2351           0 :         if (!rdata) {
    2352           0 :                 DEBUG(4,("NetSessionGetInfo no data returned\n"));
    2353           0 :                 goto out;
    2354             :         }
    2355             : 
    2356           0 :         endp = rparam + rprcnt;
    2357           0 :         res = GETRES(rparam, endp);
    2358             : 
    2359           0 :         if (res == 0 || res == ERRmoredata) {
    2360           0 :                 TALLOC_CTX *frame = talloc_stackframe();
    2361           0 :                 int converter = 0;
    2362           0 :                 char *wsname, *username, *clitype_name;
    2363           0 :                 uint16_t num_conns = 0, num_opens = 0, num_users = 0;
    2364           0 :                 unsigned int sess_time = 0, idle_time = 0, user_flags = 0;
    2365             : 
    2366           0 :                 p = rparam + WORDSIZE;
    2367           0 :                 GETWORD(p, converter,endp);
    2368             : 
    2369           0 :                 p = rdata;
    2370           0 :                 endp = rdata + rdrcnt;
    2371           0 :                 p += rap_getstringp(frame,
    2372             :                                 p,
    2373             :                                 &wsname,
    2374             :                                 rdata,
    2375             :                                 converter,
    2376             :                                 endp);
    2377           0 :                 p += rap_getstringp(frame,
    2378             :                                 p,
    2379             :                                 &username,
    2380             :                                 rdata,
    2381             :                                 converter,
    2382             :                                 endp);
    2383           0 :                 GETWORD(p, num_conns, endp);
    2384           0 :                 GETWORD(p, num_opens, endp);
    2385           0 :                 GETWORD(p, num_users, endp);
    2386           0 :                 GETDWORD(p, sess_time, endp);
    2387           0 :                 GETDWORD(p, idle_time, endp);
    2388           0 :                 GETDWORD(p, user_flags, endp);
    2389           0 :                 rap_getstringp(frame,
    2390             :                                 p,
    2391             :                                 &clitype_name,
    2392             :                                 rdata,
    2393             :                                 converter,
    2394             :                                 endp);
    2395             : 
    2396           0 :                 if (wsname && username && clitype_name) {
    2397           0 :                         fn(wsname, username, num_conns, num_opens, num_users, sess_time,
    2398             :                                 idle_time, user_flags, clitype_name);
    2399             :                 }
    2400           0 :                 TALLOC_FREE(frame);
    2401             :         } else {
    2402           0 :                 DEBUG(4,("NetSessionGetInfo res=%d\n", res));
    2403             :         }
    2404             : 
    2405           0 :   out:
    2406             : 
    2407           0 :         SAFE_FREE(rparam);
    2408           0 :         SAFE_FREE(rdata);
    2409             : 
    2410           0 :         return res;
    2411             : }
    2412             : 
    2413             : /****************************************************************************
    2414             :  Call a NetSessionDel - close a session to an SMB server.
    2415             : ****************************************************************************/
    2416             : 
    2417           0 : int cli_NetSessionDel(struct cli_state *cli, const char *workstation)
    2418             : {
    2419           0 :         char param[WORDSIZE                      /* api number       */
    2420             :                 +sizeof(RAP_NetSessionDel_REQ) /* req string       */
    2421             :                 +1                             /* no return string */
    2422             :                 +RAP_MACHNAME_LEN              /* workstation name */
    2423             :                 +WORDSIZE];                    /* reserved (0)     */
    2424           0 :         char *p;
    2425           0 :         char *rparam = NULL;
    2426           0 :         char *rdata = NULL;
    2427           0 :         unsigned int rprcnt, rdrcnt;
    2428           0 :         int res = -1;
    2429             : 
    2430           0 :         memset(param, '\0', sizeof(param));
    2431           0 :         p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL);
    2432           0 :         PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1);
    2433           0 :         PUTWORD(p,0); /* reserved word of 0 */
    2434             : 
    2435           0 :         if (cli_api(cli,
    2436           0 :                         param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
    2437             :                         NULL, 0, 200,       /* data, length, maxlen */
    2438             :                         &rparam, &rprcnt,   /* return params, length */
    2439             :                         &rdata, &rdrcnt))   /* return data, length */
    2440             :         {
    2441           0 :                 char *endp = rparam + rprcnt;
    2442           0 :                 res = GETRES(rparam, endp);
    2443           0 :                 cli->rap_error = res;
    2444             : 
    2445           0 :                 if (res == 0) {
    2446             :                         /* nothing to do */
    2447             :                 } else {
    2448           0 :                         DEBUG(4,("NetFileClose2 res=%d\n", res));
    2449             :                 }
    2450             :         } else {
    2451           0 :                 res = -1;
    2452           0 :                 DEBUG(4,("NetFileClose2 failed\n"));
    2453             :         }
    2454             : 
    2455           0 :         SAFE_FREE(rparam);
    2456           0 :         SAFE_FREE(rdata);
    2457             : 
    2458           0 :         return res;
    2459             : }
    2460             : 
    2461           0 : int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier,
    2462             :                         void (*fn)(uint16_t conid, uint16_t contype,
    2463             :                                 uint16_t numopens, uint16_t numusers,
    2464             :                                 uint32_t contime, const char *username,
    2465             :                                 const char *netname))
    2466             : {
    2467           0 :         char param[WORDSIZE                          /* api number    */
    2468             :                 +sizeof(RAP_NetConnectionEnum_REQ) /* req string    */
    2469             :                 +sizeof(RAP_CONNECTION_INFO_L1)    /* return string */
    2470             :                 +RAP_MACHNAME_LEN                  /* wksta name    */
    2471             :                 +WORDSIZE                          /* info level    */
    2472             :                 +WORDSIZE];                        /* buffer size   */
    2473           0 :         char *p;
    2474           0 :         char *rparam = NULL;
    2475           0 :         char *rdata = NULL;
    2476           0 :         unsigned int rprcnt, rdrcnt;
    2477           0 :         int res = -1;
    2478             : 
    2479           0 :         memset(param, '\0', sizeof(param));
    2480           0 :         p = make_header(param, RAP_WconnectionEnum,
    2481             :                 RAP_NetConnectionEnum_REQ, RAP_CONNECTION_INFO_L1);
    2482           0 :         PUTSTRING(p, qualifier, RAP_MACHNAME_LEN-1);/* Workstation name */
    2483           0 :         PUTWORD(p,1);            /* Info level 1 */
    2484           0 :         PUTWORD(p,0xFFE0);       /* Return buffer size */
    2485             : 
    2486           0 :         if (cli_api(cli,
    2487           0 :                         param, PTR_DIFF(p,param),PTR_DIFF(p,param),
    2488             :                         NULL, 0, CLI_BUFFER_SIZE,
    2489             :                         &rparam, &rprcnt,
    2490             :                         &rdata, &rdrcnt)) {
    2491           0 :                 char *endp = rparam + rprcnt;
    2492           0 :                 res = GETRES(rparam, endp);
    2493           0 :                 cli->rap_error = res;
    2494           0 :                 if (res != 0) {
    2495           0 :                         DEBUG(1,("NetConnectionEnum gave error %d\n", res));
    2496             :                 }
    2497             :         }
    2498             : 
    2499           0 :         if (!rdata) {
    2500           0 :                 DEBUG(4,("NetConnectionEnum no data returned\n"));
    2501           0 :                 goto out;
    2502             :         }
    2503             : 
    2504           0 :         if (res == 0 || res == ERRmoredata) {
    2505           0 :                 TALLOC_CTX *frame = talloc_stackframe();
    2506           0 :                 char *endp = rparam + rprcnt;
    2507           0 :                 int i, converter = 0, count = 0;
    2508             : 
    2509           0 :                 p = rparam + WORDSIZE;
    2510           0 :                 GETWORD(p, converter, endp);
    2511           0 :                 GETWORD(p, count, endp);
    2512             : 
    2513           0 :                 endp = rdata + rdrcnt;
    2514           0 :                 for (i=0,p=rdata;i<count && p < endp;i++) {
    2515           0 :                         char *netname, *username;
    2516           0 :                         uint16_t conn_id = 0, conn_type = 0, num_opens = 0, num_users = 0;
    2517           0 :                         unsigned int conn_time = 0;
    2518             : 
    2519           0 :                         GETWORD(p,conn_id, endp);
    2520           0 :                         GETWORD(p,conn_type, endp);
    2521           0 :                         GETWORD(p,num_opens, endp);
    2522           0 :                         GETWORD(p,num_users, endp);
    2523           0 :                         GETDWORD(p,conn_time, endp);
    2524           0 :                         p += rap_getstringp(frame,
    2525             :                                         p,
    2526             :                                         &username,
    2527             :                                         rdata,
    2528             :                                         converter,
    2529             :                                         endp);
    2530           0 :                         p += rap_getstringp(frame,
    2531             :                                         p,
    2532             :                                         &netname,
    2533             :                                         rdata,
    2534             :                                         converter,
    2535             :                                         endp);
    2536             : 
    2537           0 :                         if (username && netname) {
    2538           0 :                                 fn(conn_id, conn_type, num_opens, num_users, conn_time,
    2539             :                                         username, netname);
    2540             :                         }
    2541             :                 }
    2542           0 :                 TALLOC_FREE(frame);
    2543             :         } else {
    2544           0 :                 DEBUG(4,("NetConnectionEnum res=%d\n", res));
    2545             :         }
    2546             : 
    2547           0 :   out:
    2548             : 
    2549           0 :         SAFE_FREE(rdata);
    2550           0 :         SAFE_FREE(rparam);
    2551           0 :         return res;
    2552             : }

Generated by: LCOV version 1.14