libsmb/clirap2.c

説明を見る。
00001 /* 
00002    Samba Unix/Linux SMB client library 
00003    More client RAP (SMB Remote Procedure Calls) functions
00004    Copyright (C) 2001 Steve French (sfrench@us.ibm.com)
00005    Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
00006                     
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 /*****************************************************/
00024 /*                                                   */
00025 /*   Additional RAP functionality                    */
00026 /*                                                   */
00027 /*   RAP is the original SMB RPC, documented         */
00028 /*   by Microsoft and X/Open in the 1990s and        */
00029 /*   supported by most SMB/CIFS servers although     */
00030 /*   it is unlikely that any one implementation      */
00031 /*   supports all RAP command codes since some       */
00032 /*   are quite obsolete and a few are specific       */
00033 /*   to a particular network operating system        */
00034 /*                                                   */ 
00035 /*   Although it has largely been replaced           */ 
00036 /*   for complex remote admistration and management  */
00037 /*   (of servers) by the relatively newer            */
00038 /*   DCE/RPC based remote API (which better handles  */
00039 /*   large >64K data structures), there are many     */
00040 /*   important administrative and resource location  */
00041 /*   tasks and user tasks (e.g. password change)     */
00042 /*   that are performed via RAP.                     */
00043 /*                                                   */
00044 /*   Although a few of the RAP calls are implemented */
00045 /*   in the Samba client library already (clirap.c)  */
00046 /*   the new ones are in clirap2.c for easy patching */
00047 /*   and integration and a corresponding header      */
00048 /*   file, rap.h, has been created.                  */
00049 /*                                                   */
00050 /*   This is based on data from the CIFS spec        */
00051 /*   and the LAN Server and LAN Manager              */
00052 /*   Programming Reference books and published       */
00053 /*   RAP document and CIFS forum postings and        */
00054 /*   lots of trial and error                         */
00055 /*                                                   */
00056 /*   Function names changed from API_ (as they are   */
00057 /*   in the CIFS specification) to RAP_ in order     */
00058 /*   to avoid confusion with other API calls         */
00059 /*   sent via DCE RPC                                */
00060 /*                                                   */
00061 /*****************************************************/
00062 
00063 /*****************************************************/
00064 /*                                                   */
00065 /* cifsrap.c already includes support for:           */
00066 /*                                                   */
00067 /* WshareEnum ( API number 0, level 1)               */
00068 /* NetServerEnum2 (API num 104, level 1)             */
00069 /* WWkstaUserLogon (132)                             */
00070 /* SamOEMchgPasswordUser2_P (214)                    */
00071 /*                                                   */
00072 /* cifsprint.c already includes support for:         */
00073 /*                                                   */
00074 /* WPrintJobEnum (API num 76, level 2)               */
00075 /* WPrintJobDel  (API num 81)                        */
00076 /*                                                   */
00077 /*****************************************************/ 
00078 
00079 #include "includes.h" 
00080 
00081 #define WORDSIZE 2
00082 #define DWORDSIZE 4
00083 
00084 #define PUTBYTE(p,b) do {SCVAL(p,0,b); p++;} while(0)
00085 #define GETBYTE(p,b) do {b = CVAL(p,0); p++;} while(0)
00086 #define PUTWORD(p,w) do {SSVAL(p,0,w); p += WORDSIZE;} while(0)
00087 #define GETWORD(p,w) do {w = SVAL(p,0); p += WORDSIZE;} while(0)
00088 #define PUTDWORD(p,d) do {SIVAL(p,0,d); p += DWORDSIZE;} while(0)
00089 #define GETDWORD(p,d) do {d = IVAL(p,0); p += DWORDSIZE;} while(0)
00090 #define GETRES(p) p ? SVAL(p,0) : -1
00091 /* put string s at p with max len n and increment p past string */
00092 #define PUTSTRING(p,s,n) do {\
00093   push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\
00094   p = push_skip_string(p);\
00095   } while(0)
00096 /* put string s and p, using fixed len l, and increment p by l */
00097 #define PUTSTRINGF(p,s,l) do {\
00098   push_ascii(p,s?s:"",l,STR_TERMINATE);\
00099   p += l;\
00100   } while (0)
00101 /* put string pointer at p, supplying offset o from rdata r, store   */
00102 /* dword offset at p, increment p by 4 and o by length of s.  This   */
00103 /* means on the first call, you must calc the offset yourself!       */
00104 #define PUTSTRINGP(p,s,r,o) do {\
00105   if (s) {\
00106     push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\
00107     PUTDWORD(p,o);\
00108     o += strlen(s) + 1;\
00109   } else PUTDWORD(p,0);\
00110   }while(0);
00111 /* get asciiz string s from p, increment p past string */
00112 #define GETSTRING(p,s) do {\
00113   pull_ascii_pstring(s,p);\
00114   p = push_skip_string(p);\
00115   } while(0)
00116 /* get fixed length l string s from p, increment p by l */
00117 #define GETSTRINGF(p,s,l) do {\
00118   pull_ascii_pstring(s,p);\
00119   p += l;\
00120   } while(0)
00121 /* get string s from offset (obtained at p) from rdata r - converter c */
00122 #define GETSTRINGP(p,s,r,c) do {\
00123   uint32 off;\
00124   GETDWORD(p,off);\
00125   off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */ \
00126   pull_ascii_pstring(s, off?(r+off-c):"");\
00127   } while(0)
00128 
00129 static char *make_header(char *param, uint16 apinum, const char *reqfmt, const char *datafmt)
00130 {
00131   PUTWORD(param,apinum);
00132   if (reqfmt) 
00133     PUTSTRING(param,reqfmt,0);
00134   else 
00135     *param++ = (char) 0;
00136 
00137   if (datafmt)
00138     PUTSTRING(param,datafmt,0);
00139   else
00140     *param++ = (char) 0;
00141 
00142   return param;
00143 }
00144     
00145 
00146 /****************************************************************************
00147  call a NetGroupDelete - delete user group from remote server
00148 ****************************************************************************/
00149 int cli_NetGroupDelete(struct cli_state *cli, const char *group_name )
00150 {
00151   char *rparam = NULL;
00152   char *rdata = NULL;
00153   char *p;
00154   unsigned int rdrcnt,rprcnt;
00155   int res;
00156   char param[WORDSIZE                    /* api number    */
00157             +sizeof(RAP_NetGroupDel_REQ) /* parm string   */
00158             +1                           /* no ret string */
00159             +RAP_GROUPNAME_LEN           /* group to del  */
00160             +WORDSIZE];                  /* reserved word */
00161 
00162   /* now send a SMBtrans command with api GroupDel */
00163   p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL);  
00164   PUTSTRING(p, group_name, RAP_GROUPNAME_LEN);
00165   PUTWORD(p,0);  /* reserved word MBZ on input */
00166                  
00167   if (cli_api(cli, 
00168               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
00169               NULL, 0, 200,       /* data, length, maxlen */
00170               &rparam, &rprcnt,   /* return params, length */
00171               &rdata, &rdrcnt))   /* return data, length */
00172     {
00173       res = GETRES(rparam);
00174                         
00175       if (res == 0) {
00176         /* nothing to do */             
00177       }
00178       else if ((res == 5) || (res == 65)) {
00179           DEBUG(1, ("Access Denied\n"));
00180       }
00181       else if (res == 2220) {
00182          DEBUG (1, ("Group does not exist\n"));
00183       }
00184       else {
00185         DEBUG(4,("NetGroupDelete res=%d\n", res));
00186       }      
00187     } else {
00188       res = -1;
00189       DEBUG(4,("NetGroupDelete failed\n"));
00190     }
00191   
00192   SAFE_FREE(rparam);
00193   SAFE_FREE(rdata);
00194   
00195   return res;
00196 }
00197 
00198 /****************************************************************************
00199  call a NetGroupAdd - add user group to remote server
00200 ****************************************************************************/
00201 int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo )
00202 {
00203   char *rparam = NULL;
00204   char *rdata = NULL;
00205   char *p;
00206   unsigned int rdrcnt,rprcnt;
00207   int res;
00208   char param[WORDSIZE                    /* api number    */
00209             +sizeof(RAP_NetGroupAdd_REQ) /* req string    */
00210             +sizeof(RAP_GROUP_INFO_L1)   /* return string */
00211             +WORDSIZE                    /* info level    */
00212             +WORDSIZE];                  /* reserved word */
00213 
00214   /* offset into data of free format strings.  Will be updated */
00215   /* by PUTSTRINGP macro and end up with total data length.    */
00216   int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE; 
00217   char *data;
00218   size_t data_size;
00219 
00220   /* Allocate data. */
00221   data_size = MAX(soffset + strlen(grinfo->comment) + 1, 1024);
00222 
00223   data = SMB_MALLOC_ARRAY(char, data_size);
00224   if (!data) {
00225     DEBUG (1, ("Malloc fail\n"));
00226     return -1;
00227   }
00228 
00229   /* now send a SMBtrans command with api WGroupAdd */
00230   
00231   p = make_header(param, RAP_WGroupAdd,
00232                   RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1); 
00233   PUTWORD(p, 1); /* info level */
00234   PUTWORD(p, 0); /* reserved word 0 */
00235   
00236   p = data;
00237   PUTSTRINGF(p, grinfo->group_name, RAP_GROUPNAME_LEN);
00238   PUTBYTE(p, 0); /* pad byte 0 */
00239   PUTSTRINGP(p, grinfo->comment, data, soffset);
00240   
00241   if (cli_api(cli, 
00242               param, sizeof(param), 1024, /* Param, length, maxlen */
00243               data, soffset, sizeof(data), /* data, length, maxlen */
00244               &rparam, &rprcnt,   /* return params, length */
00245               &rdata, &rdrcnt))   /* return data, length */
00246     {
00247       res = GETRES(rparam);
00248       
00249       if (res == 0) {
00250         /* nothing to do */             
00251       } else if ((res == 5) || (res == 65)) {
00252         DEBUG(1, ("Access Denied\n"));
00253       }
00254       else if (res == 2223) {
00255         DEBUG (1, ("Group already exists\n"));
00256       }
00257       else {
00258         DEBUG(4,("NetGroupAdd res=%d\n", res));
00259       }
00260     } else {
00261       res = -1;
00262       DEBUG(4,("NetGroupAdd failed\n"));
00263     }
00264   
00265   SAFE_FREE(data);
00266   SAFE_FREE(rparam);
00267   SAFE_FREE(rdata);
00268 
00269   return res;
00270 }
00271 
00272 /****************************************************************************
00273 call a NetGroupEnum - try and list user groups on a different host
00274 ****************************************************************************/
00275 int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state)
00276 {
00277   char param[WORDSIZE                     /* api number    */
00278             +sizeof(RAP_NetGroupEnum_REQ) /* parm string   */
00279             +sizeof(RAP_GROUP_INFO_L1)    /* return string */
00280             +WORDSIZE                     /* info level    */
00281             +WORDSIZE];                   /* buffer size   */
00282   char *p;
00283   char *rparam = NULL;
00284   char *rdata = NULL; 
00285   unsigned int rprcnt, rdrcnt;
00286   int res = -1;
00287   
00288   
00289   memset(param, '\0', sizeof(param));
00290   p = make_header(param, RAP_WGroupEnum,
00291                   RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L1);
00292   PUTWORD(p,1); /* Info level 1 */  /* add level 0 */
00293   PUTWORD(p,0xFFE0); /* Return buffer size */
00294 
00295   if (cli_api(cli,
00296               param, PTR_DIFF(p,param),8,
00297               NULL, 0, 0xFFE0 /* data area size */,
00298               &rparam, &rprcnt,
00299               &rdata, &rdrcnt)) {
00300     res = GETRES(rparam);
00301     cli->rap_error = res;
00302     if(cli->rap_error == 234) 
00303         DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
00304     else if (cli->rap_error != 0) {
00305       DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
00306     }
00307   }
00308 
00309   if (rdata) {
00310     if (res == 0 || res == ERRmoredata) {
00311       int i, converter, count;
00312 
00313       p = rparam + WORDSIZE; /* skip result */
00314       GETWORD(p, converter);
00315       GETWORD(p, count);
00316 
00317       for (i=0,p=rdata;i<count;i++) {
00318             pstring comment;
00319             char groupname[RAP_GROUPNAME_LEN];
00320 
00321             GETSTRINGF(p, groupname, RAP_GROUPNAME_LEN);
00322             p++; /* pad byte */
00323             GETSTRINGP(p, comment, rdata, converter);
00324 
00325             fn(groupname, comment, cli);
00326       } 
00327     } else {
00328       DEBUG(4,("NetGroupEnum res=%d\n", res));
00329     }
00330   } else {
00331     DEBUG(4,("NetGroupEnum no data returned\n"));
00332   }
00333     
00334   SAFE_FREE(rparam);
00335   SAFE_FREE(rdata);
00336 
00337   return res;
00338 }
00339 
00340 int cli_RNetGroupEnum0(struct cli_state *cli,
00341                        void (*fn)(const char *, void *),
00342                        void *state)
00343 {
00344   char param[WORDSIZE                     /* api number    */
00345             +sizeof(RAP_NetGroupEnum_REQ) /* parm string   */
00346             +sizeof(RAP_GROUP_INFO_L0)    /* return string */
00347             +WORDSIZE                     /* info level    */
00348             +WORDSIZE];                   /* buffer size   */
00349   char *p;
00350   char *rparam = NULL;
00351   char *rdata = NULL; 
00352   unsigned int rprcnt, rdrcnt;
00353   int res = -1;
00354   
00355   
00356   memset(param, '\0', sizeof(param));
00357   p = make_header(param, RAP_WGroupEnum,
00358                   RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L0);
00359   PUTWORD(p,0); /* Info level 0 */ /* Hmmm. I *very* much suspect this
00360                                       is the resume count, at least
00361                                       that's what smbd believes... */
00362   PUTWORD(p,0xFFE0); /* Return buffer size */
00363 
00364   if (cli_api(cli,
00365               param, PTR_DIFF(p,param),8,
00366               NULL, 0, 0xFFE0 /* data area size */,
00367               &rparam, &rprcnt,
00368               &rdata, &rdrcnt)) {
00369     res = GETRES(rparam);
00370     cli->rap_error = res;
00371     if(cli->rap_error == 234) 
00372         DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n"));
00373     else if (cli->rap_error != 0) {
00374       DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error));
00375     }
00376   }
00377 
00378   if (rdata) {
00379     if (res == 0 || res == ERRmoredata) {
00380       int i, count;
00381 
00382       p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
00383       GETWORD(p, count);
00384 
00385       for (i=0,p=rdata;i<count;i++) {
00386             char groupname[RAP_GROUPNAME_LEN];
00387             GETSTRINGF(p, groupname, RAP_GROUPNAME_LEN);
00388             fn(groupname, cli);
00389       } 
00390     } else {
00391       DEBUG(4,("NetGroupEnum res=%d\n", res));
00392     }
00393   } else {
00394     DEBUG(4,("NetGroupEnum no data returned\n"));
00395   }
00396     
00397   SAFE_FREE(rparam);
00398   SAFE_FREE(rdata);
00399 
00400   return res;
00401 }
00402 
00403 int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const char *user_name)
00404 {
00405   char *rparam = NULL;
00406   char *rdata = NULL;
00407   char *p;
00408   unsigned int rdrcnt,rprcnt;
00409   int res;
00410   char param[WORDSIZE                        /* api number    */
00411             +sizeof(RAP_NetGroupDelUser_REQ) /* parm string   */
00412             +1                               /* no ret string */
00413             +RAP_GROUPNAME_LEN               /* group name    */
00414             +RAP_USERNAME_LEN];              /* user to del   */
00415 
00416   /* now send a SMBtrans command with api GroupMemberAdd */
00417   p = make_header(param, RAP_WGroupDelUser, RAP_NetGroupDelUser_REQ, NULL);
00418   PUTSTRING(p,group_name,RAP_GROUPNAME_LEN);
00419   PUTSTRING(p,user_name,RAP_USERNAME_LEN);
00420 
00421   if (cli_api(cli, 
00422               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
00423               NULL, 0, 200,       /* data, length, maxlen */
00424               &rparam, &rprcnt,   /* return params, length */
00425               &rdata, &rdrcnt))   /* return data, length */
00426     {
00427       res = GETRES(rparam);
00428       
00429       switch(res) {
00430         case 0:
00431           break;
00432         case 5:
00433         case 65:
00434           DEBUG(1, ("Access Denied\n"));
00435           break;
00436         case 50:
00437           DEBUG(1, ("Not supported by server\n"));
00438           break;
00439         case 2220:
00440           DEBUG(1, ("Group does not exist\n"));
00441           break;
00442         case 2221:
00443           DEBUG(1, ("User does not exist\n"));
00444           break;
00445         case 2237:
00446           DEBUG(1, ("User is not in group\n"));
00447           break;
00448         default:
00449           DEBUG(4,("NetGroupDelUser res=%d\n", res));
00450       }
00451     } else {
00452       res = -1;
00453       DEBUG(4,("NetGroupDelUser failed\n"));
00454     }
00455   
00456   SAFE_FREE(rparam);
00457   SAFE_FREE(rdata);
00458         
00459   return res; 
00460 }
00461 
00462 int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const char *user_name)
00463 {
00464   char *rparam = NULL;
00465   char *rdata = NULL;
00466   char *p;
00467   unsigned int rdrcnt,rprcnt;
00468   int res;
00469   char param[WORDSIZE                        /* api number    */
00470             +sizeof(RAP_NetGroupAddUser_REQ) /* parm string   */
00471             +1                               /* no ret string */
00472             +RAP_GROUPNAME_LEN               /* group name    */
00473             +RAP_USERNAME_LEN];              /* user to add   */
00474 
00475   /* now send a SMBtrans command with api GroupMemberAdd */
00476   p = make_header(param, RAP_WGroupAddUser, RAP_NetGroupAddUser_REQ, NULL);
00477   PUTSTRING(p,group_name,RAP_GROUPNAME_LEN);
00478   PUTSTRING(p,user_name,RAP_USERNAME_LEN);
00479 
00480   if (cli_api(cli, 
00481               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
00482               NULL, 0, 200,       /* data, length, maxlen */
00483               &rparam, &rprcnt,   /* return params, length */
00484               &rdata, &rdrcnt))   /* return data, length */
00485     {
00486       res = GETRES(rparam);
00487       
00488       switch(res) {
00489         case 0:
00490           break;
00491         case 5:
00492         case 65:
00493           DEBUG(1, ("Access Denied\n"));
00494           break;
00495         case 50:
00496           DEBUG(1, ("Not supported by server\n"));
00497           break;
00498         case 2220:
00499           DEBUG(1, ("Group does not exist\n"));
00500           break;
00501         case 2221:
00502           DEBUG(1, ("User does not exist\n"));
00503           break;
00504         default:
00505           DEBUG(4,("NetGroupAddUser res=%d\n", res));
00506       }
00507     } else {
00508       res = -1;
00509       DEBUG(4,("NetGroupAddUser failed\n"));
00510     }
00511   
00512   SAFE_FREE(rparam);
00513   SAFE_FREE(rdata);
00514         
00515   return res;
00516 }
00517 
00518 
00519 int cli_NetGroupGetUsers(struct cli_state * cli, const char *group_name, void (*fn)(const char *, void *), void *state )
00520 {
00521   char *rparam = NULL;
00522   char *rdata = NULL;
00523   char *p;
00524   unsigned int rdrcnt,rprcnt;
00525   int res = -1;
00526   char param[WORDSIZE                        /* api number    */
00527             +sizeof(RAP_NetGroupGetUsers_REQ)/* parm string   */
00528             +sizeof(RAP_GROUP_USERS_INFO_0)  /* return string */
00529             +RAP_GROUPNAME_LEN               /* group name    */
00530             +WORDSIZE                        /* info level    */
00531             +WORDSIZE];                      /* buffer size   */
00532 
00533   /* now send a SMBtrans command with api GroupGetUsers */
00534   p = make_header(param, RAP_WGroupGetUsers,
00535                   RAP_NetGroupGetUsers_REQ, RAP_GROUP_USERS_INFO_0);
00536   PUTSTRING(p,group_name,RAP_GROUPNAME_LEN-1);
00537   PUTWORD(p,0); /* info level 0 */
00538   PUTWORD(p,0xFFE0); /* return buffer size */
00539 
00540   if (cli_api(cli,
00541               param, PTR_DIFF(p,param),PTR_DIFF(p,param),
00542               NULL, 0, CLI_BUFFER_SIZE,
00543               &rparam, &rprcnt,
00544               &rdata, &rdrcnt)) {
00545     res = GETRES(rparam);
00546     cli->rap_error = res;
00547     if (res != 0) {
00548       DEBUG(1,("NetGroupGetUsers gave error %d\n", res));
00549     }
00550   }
00551   if (rdata) {
00552     if (res == 0 || res == ERRmoredata) {
00553       int i, count;
00554       fstring username;
00555       p = rparam + WORDSIZE + WORDSIZE;
00556       GETWORD(p, count);
00557 
00558       for (i=0,p=rdata; i<count; i++) {
00559         GETSTRINGF(p, username, RAP_USERNAME_LEN);
00560         fn(username, state);
00561       }
00562     } else {
00563       DEBUG(4,("NetGroupGetUsers res=%d\n", res));
00564     }
00565   } else {
00566     DEBUG(4,("NetGroupGetUsers no data returned\n"));
00567   }
00568   SAFE_FREE(rdata);
00569   SAFE_FREE(rparam);
00570   return res;
00571 }
00572 
00573 int cli_NetUserGetGroups(struct cli_state * cli, const char *user_name, void (*fn)(const char *, void *), void *state )
00574 {
00575   char *rparam = NULL;
00576   char *rdata = NULL;
00577   char *p;
00578   unsigned int rdrcnt,rprcnt;
00579   int res = -1;
00580   char param[WORDSIZE                        /* api number    */
00581             +sizeof(RAP_NetUserGetGroups_REQ)/* parm string   */
00582             +sizeof(RAP_GROUP_USERS_INFO_0)  /* return string */
00583             +RAP_USERNAME_LEN               /* user name    */
00584             +WORDSIZE                        /* info level    */
00585             +WORDSIZE];                      /* buffer size   */
00586 
00587   /* now send a SMBtrans command with api GroupGetUsers */
00588   p = make_header(param, RAP_WUserGetGroups,
00589                   RAP_NetUserGetGroups_REQ, RAP_GROUP_USERS_INFO_0);
00590   PUTSTRING(p,user_name,RAP_USERNAME_LEN-1);
00591   PUTWORD(p,0); /* info level 0 */
00592   PUTWORD(p,0xFFE0); /* return buffer size */
00593 
00594   if (cli_api(cli,
00595               param, PTR_DIFF(p,param),PTR_DIFF(p,param),
00596               NULL, 0, CLI_BUFFER_SIZE,
00597               &rparam, &rprcnt,
00598               &rdata, &rdrcnt)) {
00599     res = GETRES(rparam);
00600     cli->rap_error = res;
00601     if (res != 0) {
00602       DEBUG(1,("NetUserGetGroups gave error %d\n", res));
00603     }
00604   }
00605   if (rdata) {
00606     if (res == 0 || res == ERRmoredata) {
00607       int i, count;
00608       fstring groupname;
00609       p = rparam + WORDSIZE + WORDSIZE;
00610       GETWORD(p, count);
00611 
00612       for (i=0,p=rdata; i<count; i++) {
00613         GETSTRINGF(p, groupname, RAP_USERNAME_LEN);
00614             fn(groupname, state);
00615       }
00616     } else {
00617       DEBUG(4,("NetUserGetGroups res=%d\n", res));
00618     }
00619   } else {
00620     DEBUG(4,("NetUserGetGroups no data returned\n"));
00621   }
00622   SAFE_FREE(rdata);
00623   SAFE_FREE(rparam);
00624   return res;
00625 }
00626 
00627 
00628 /****************************************************************************
00629  call a NetUserDelete - delete user from remote server
00630 ****************************************************************************/
00631 int cli_NetUserDelete(struct cli_state *cli, const char * user_name )
00632 {
00633   char *rparam = NULL;
00634   char *rdata = NULL;
00635   char *p;
00636   unsigned int rdrcnt,rprcnt;
00637   int res;
00638   char param[WORDSIZE                    /* api number    */
00639             +sizeof(RAP_NetGroupDel_REQ) /* parm string   */
00640             +1                           /* no ret string */
00641             +RAP_USERNAME_LEN            /* user to del   */
00642             +WORDSIZE];                  /* reserved word */
00643 
00644   /* now send a SMBtrans command with api UserDel */
00645   p = make_header(param, RAP_WUserDel, RAP_NetGroupDel_REQ, NULL);  
00646   PUTSTRING(p, user_name, RAP_USERNAME_LEN);
00647   PUTWORD(p,0);  /* reserved word MBZ on input */
00648                  
00649   if (cli_api(cli, 
00650               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
00651               NULL, 0, 200,       /* data, length, maxlen */
00652               &rparam, &rprcnt,   /* return params, length */
00653               &rdata, &rdrcnt))   /* return data, length */
00654     {
00655       res = GETRES(rparam);
00656       
00657       if (res == 0) {
00658         /* nothing to do */             
00659       }
00660       else if ((res == 5) || (res == 65)) {
00661          DEBUG(1, ("Access Denied\n"));
00662       }
00663       else if (res == 2221) {
00664          DEBUG (1, ("User does not exist\n"));
00665       }
00666       else {
00667           DEBUG(4,("NetUserDelete res=%d\n", res));
00668       }      
00669     } else {
00670       res = -1;
00671       DEBUG(4,("NetUserDelete failed\n"));
00672     }
00673   
00674   SAFE_FREE(rparam);
00675   SAFE_FREE(rdata);
00676         
00677   return res;
00678 }
00679 
00680 /****************************************************************************
00681  call a NetUserAdd - add user to remote server
00682 ****************************************************************************/
00683 int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo )
00684 {
00685    
00686 
00687 
00688   char *rparam = NULL;
00689   char *rdata = NULL;
00690   char *p;                                          
00691   unsigned int rdrcnt,rprcnt;
00692   int res;
00693   char param[WORDSIZE                    /* api number    */
00694             +sizeof(RAP_NetUserAdd2_REQ) /* req string    */
00695             +sizeof(RAP_USER_INFO_L1)    /* data string   */
00696             +WORDSIZE                    /* info level    */
00697             +WORDSIZE                    /* buffer length */
00698             +WORDSIZE];                  /* reserved      */
00699  
00700   char data[1024];
00701   /* offset into data of free format strings.  Will be updated */
00702   /* by PUTSTRINGP macro and end up with total data length.    */
00703   int soffset=RAP_USERNAME_LEN+1 /* user name + pad */
00704     + RAP_UPASSWD_LEN            /* password        */
00705     + DWORDSIZE                  /* password age    */
00706     + WORDSIZE                   /* privilege       */
00707     + DWORDSIZE                  /* home dir ptr    */
00708     + DWORDSIZE                  /* comment ptr     */
00709     + WORDSIZE                   /* flags           */
00710     + DWORDSIZE;                 /* login script ptr*/
00711 
00712   /* now send a SMBtrans command with api NetUserAdd */
00713   p = make_header(param, RAP_WUserAdd2,
00714                   RAP_NetUserAdd2_REQ, RAP_USER_INFO_L1);
00715   PUTWORD(p, 1); /* info level */
00716 
00717   PUTWORD(p, 0); /* pwencrypt */
00718   if(userinfo->passwrd)
00719     PUTWORD(p,MIN(strlen(userinfo->passwrd), RAP_UPASSWD_LEN));
00720   else
00721     PUTWORD(p, 0); /* password length */
00722 
00723   p = data;
00724   memset(data, '\0', soffset);
00725 
00726   PUTSTRINGF(p, userinfo->user_name, RAP_USERNAME_LEN);
00727   PUTBYTE(p, 0); /* pad byte 0 */
00728   PUTSTRINGF(p, userinfo->passwrd, RAP_UPASSWD_LEN);
00729   PUTDWORD(p, 0); /* pw age - n.a. on user add */
00730   PUTWORD(p, userinfo->priv);
00731   PUTSTRINGP(p, userinfo->home_dir, data, soffset);
00732   PUTSTRINGP(p, userinfo->comment, data, soffset);
00733   PUTWORD(p, userinfo->userflags);
00734   PUTSTRINGP(p, userinfo->logon_script, data, soffset);
00735 
00736   if (cli_api(cli, 
00737               param, sizeof(param), 1024, /* Param, length, maxlen */
00738               data, soffset, sizeof(data), /* data, length, maxlen */
00739               &rparam, &rprcnt,   /* return params, length */
00740               &rdata, &rdrcnt))   /* return data, length */
00741     {
00742       res = GETRES(rparam);
00743       
00744       if (res == 0) {
00745         /* nothing to do */             
00746       }       
00747       else if ((res == 5) || (res == 65)) {
00748         DEBUG(1, ("Access Denied\n"));
00749       }
00750       else if (res == 2224) {
00751         DEBUG (1, ("User already exists\n"));
00752       }
00753       else {
00754             DEBUG(4,("NetUserAdd res=%d\n", res));
00755       }
00756     } else {
00757       res = -1;
00758       DEBUG(4,("NetUserAdd failed\n"));
00759     }
00760   
00761   SAFE_FREE(rparam);
00762   SAFE_FREE(rdata);
00763 
00764   return res;
00765 }
00766 
00767 /****************************************************************************
00768 call a NetUserEnum - try and list users on a different host
00769 ****************************************************************************/
00770 int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char *, const char *, const char *, void *), void *state)
00771 {
00772   char param[WORDSIZE                 /* api number    */
00773             +sizeof(RAP_NetUserEnum_REQ) /* parm string   */
00774             +sizeof(RAP_USER_INFO_L1)    /* return string */
00775             +WORDSIZE                 /* info level    */
00776             +WORDSIZE];               /* buffer size   */
00777   char *p;
00778   char *rparam = NULL;
00779   char *rdata = NULL; 
00780   unsigned int rprcnt, rdrcnt;
00781   int res = -1;
00782   
00783 
00784   memset(param, '\0', sizeof(param));
00785   p = make_header(param, RAP_WUserEnum,
00786                   RAP_NetUserEnum_REQ, RAP_USER_INFO_L1);
00787   PUTWORD(p,1); /* Info level 1 */
00788   PUTWORD(p,0xFF00); /* Return buffer size */
00789 
00790 /* BB Fix handling of large numbers of users to be returned */
00791   if (cli_api(cli,
00792               param, PTR_DIFF(p,param),8,
00793               NULL, 0, CLI_BUFFER_SIZE,
00794               &rparam, &rprcnt,
00795               &rdata, &rdrcnt)) {
00796     res = GETRES(rparam);
00797     cli->rap_error = res;
00798     if (cli->rap_error != 0) {
00799       DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
00800     }
00801   }
00802   if (rdata) {
00803     if (res == 0 || res == ERRmoredata) {
00804       int i, converter, count;
00805       char username[RAP_USERNAME_LEN];
00806       char userpw[RAP_UPASSWD_LEN];
00807       pstring comment, homedir, logonscript;
00808 
00809       p = rparam + WORDSIZE; /* skip result */
00810       GETWORD(p, converter);
00811       GETWORD(p, count);
00812 
00813       for (i=0,p=rdata;i<count;i++) {
00814         GETSTRINGF(p, username, RAP_USERNAME_LEN);
00815         p++; /* pad byte */
00816         GETSTRINGF(p, userpw, RAP_UPASSWD_LEN);
00817         p += DWORDSIZE; /* skip password age */
00818         p += WORDSIZE;  /* skip priv: 0=guest, 1=user, 2=admin */
00819         GETSTRINGP(p, homedir, rdata, converter);
00820         GETSTRINGP(p, comment, rdata, converter);
00821         p += WORDSIZE;  /* skip flags */
00822         GETSTRINGP(p, logonscript, rdata, converter);
00823 
00824         fn(username, comment, homedir, logonscript, cli);
00825       }
00826     } else {
00827       DEBUG(4,("NetUserEnum res=%d\n", res));
00828     }
00829   } else {
00830     DEBUG(4,("NetUserEnum no data returned\n"));
00831   }
00832     
00833   SAFE_FREE(rparam);
00834   SAFE_FREE(rdata);
00835 
00836   return res;
00837 }
00838 
00839 int cli_RNetUserEnum0(struct cli_state *cli,
00840                       void (*fn)(const char *, void *),
00841                       void *state)
00842 {
00843   char param[WORDSIZE                 /* api number    */
00844             +sizeof(RAP_NetUserEnum_REQ) /* parm string   */
00845             +sizeof(RAP_USER_INFO_L0)    /* return string */
00846             +WORDSIZE                 /* info level    */
00847             +WORDSIZE];               /* buffer size   */
00848   char *p;
00849   char *rparam = NULL;
00850   char *rdata = NULL; 
00851   unsigned int rprcnt, rdrcnt;
00852   int res = -1;
00853   
00854 
00855   memset(param, '\0', sizeof(param));
00856   p = make_header(param, RAP_WUserEnum,
00857                   RAP_NetUserEnum_REQ, RAP_USER_INFO_L0);
00858   PUTWORD(p,0); /* Info level 1 */
00859   PUTWORD(p,0xFF00); /* Return buffer size */
00860 
00861 /* BB Fix handling of large numbers of users to be returned */
00862   if (cli_api(cli,
00863               param, PTR_DIFF(p,param),8,
00864               NULL, 0, CLI_BUFFER_SIZE,
00865               &rparam, &rprcnt,
00866               &rdata, &rdrcnt)) {
00867     res = GETRES(rparam);
00868     cli->rap_error = res;
00869     if (cli->rap_error != 0) {
00870       DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error));
00871     }
00872   }
00873   if (rdata) {
00874     if (res == 0 || res == ERRmoredata) {
00875       int i, count;
00876       char username[RAP_USERNAME_LEN];
00877 
00878       p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
00879       GETWORD(p, count);
00880 
00881       for (i=0,p=rdata;i<count;i++) {
00882         GETSTRINGF(p, username, RAP_USERNAME_LEN);
00883         fn(username, cli);
00884       }
00885     } else {
00886       DEBUG(4,("NetUserEnum res=%d\n", res));
00887     }
00888   } else {
00889     DEBUG(4,("NetUserEnum no data returned\n"));
00890   }
00891     
00892   SAFE_FREE(rparam);
00893   SAFE_FREE(rdata);
00894 
00895   return res;
00896 }
00897 
00898 /****************************************************************************
00899  call a NetFileClose2 - close open file on another session to server
00900 ****************************************************************************/
00901 int cli_NetFileClose(struct cli_state *cli, uint32 file_id )
00902 {
00903   char *rparam = NULL;
00904   char *rdata = NULL;
00905   char *p;
00906   unsigned int rdrcnt,rprcnt;
00907   char param[WORDSIZE                    /* api number    */
00908             +sizeof(RAP_WFileClose2_REQ) /* req string    */
00909             +1                           /* no ret string */
00910             +DWORDSIZE];                 /* file ID          */
00911   int res = -1;
00912 
00913   /* now send a SMBtrans command with api RNetShareEnum */
00914   p = make_header(param, RAP_WFileClose2, RAP_WFileClose2_REQ, NULL);
00915   PUTDWORD(p, file_id);  
00916                  
00917   if (cli_api(cli, 
00918               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
00919               NULL, 0, 200,       /* data, length, maxlen */
00920               &rparam, &rprcnt,   /* return params, length */
00921               &rdata, &rdrcnt))   /* return data, length */
00922     {
00923       res = GETRES(rparam);
00924       
00925       if (res == 0) {
00926         /* nothing to do */             
00927       } else if (res == 2314){
00928          DEBUG(1, ("NetFileClose2 - attempt to close non-existant file open instance\n"));
00929       } else {
00930         DEBUG(4,("NetFileClose2 res=%d\n", res));
00931       }      
00932     } else {
00933       res = -1;
00934       DEBUG(4,("NetFileClose2 failed\n"));
00935     }
00936   
00937   SAFE_FREE(rparam);
00938   SAFE_FREE(rdata);
00939   
00940   return res;
00941 }
00942 
00943 /****************************************************************************
00944 call a NetFileGetInfo - get information about server file opened from other
00945      workstation
00946 ****************************************************************************/
00947 int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const char *, const char *, uint16, uint16, uint32))
00948 {
00949   char *rparam = NULL;
00950   char *rdata = NULL;
00951   char *p;
00952   unsigned int rdrcnt,rprcnt;
00953   int res;
00954   char param[WORDSIZE                      /* api number      */
00955             +sizeof(RAP_WFileGetInfo2_REQ) /* req string      */
00956             +sizeof(RAP_FILE_INFO_L3)      /* return string   */
00957             +DWORDSIZE                     /* file ID          */
00958             +WORDSIZE                      /* info level      */
00959             +WORDSIZE];                    /* buffer size     */
00960 
00961   /* now send a SMBtrans command with api RNetShareEnum */
00962   p = make_header(param, RAP_WFileGetInfo2,
00963                   RAP_WFileGetInfo2_REQ, RAP_FILE_INFO_L3); 
00964   PUTDWORD(p, file_id);
00965   PUTWORD(p, 3);  /* info level */
00966   PUTWORD(p, 0x1000);   /* buffer size */ 
00967   if (cli_api(cli, 
00968               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
00969               NULL, 0, 0x1000,  /* data, length, maxlen */
00970               &rparam, &rprcnt,               /* return params, length */
00971               &rdata, &rdrcnt))               /* return data, length */
00972     {
00973       res = GETRES(rparam);
00974       if (res == 0 || res == ERRmoredata) {
00975         int converter,id, perms, locks;
00976         pstring fpath, fuser;
00977           
00978         p = rparam + WORDSIZE; /* skip result */
00979         GETWORD(p, converter);
00980 
00981         p = rdata;
00982         GETDWORD(p, id);
00983         GETWORD(p, perms);
00984         GETWORD(p, locks);
00985         GETSTRINGP(p, fpath, rdata, converter);
00986         GETSTRINGP(p, fuser, rdata, converter);
00987         
00988         fn(fpath, fuser, perms, locks, id);
00989       } else {
00990         DEBUG(4,("NetFileGetInfo2 res=%d\n", res));
00991       }      
00992     } else {
00993       res = -1;
00994       DEBUG(4,("NetFileGetInfo2 failed\n"));
00995     }
00996   
00997   SAFE_FREE(rparam);
00998   SAFE_FREE(rdata);
00999   
01000   return res;
01001 }
01002 
01003 /****************************************************************************
01004 * Call a NetFileEnum2 - list open files on an SMB server
01005 * 
01006 * PURPOSE:  Remotes a NetFileEnum API call to the current server or target 
01007 *           server listing the files open via the network (and their
01008 *           corresponding open instance ids)
01009 *          
01010 * Dependencies: none
01011 *
01012 * Parameters: 
01013 *             cli    - pointer to cli_state structure
01014 *             user   - if present, return only files opened by this remote user
01015 *             base_path - if present, return only files opened below this 
01016 *                         base path
01017 *             fn     - display function to invoke for each entry in the result
01018 *                        
01019 *
01020 * Returns:
01021 *             True      - success
01022 *             False     - failure
01023 *
01024 ****************************************************************************/
01025 int cli_NetFileEnum(struct cli_state *cli, char * user, char * base_path, void (*fn)(const char *, const char *, uint16, uint16, uint32))
01026 {
01027   char *rparam = NULL;
01028   char *rdata = NULL;
01029   char *p;
01030   unsigned int rdrcnt,rprcnt;
01031   char param[WORDSIZE                   /* api number      */
01032             +sizeof(RAP_WFileEnum2_REQ) /* req string      */
01033             +sizeof(RAP_FILE_INFO_L3)   /* return string   */
01034             +256                        /* base path (opt) */
01035             +RAP_USERNAME_LEN           /* user name (opt) */
01036             +WORDSIZE                   /* info level      */
01037             +WORDSIZE                   /* buffer size     */
01038             +DWORDSIZE                  /* resume key ?    */
01039             +DWORDSIZE];                /* resume key ?    */
01040   int count = -1;
01041 
01042   /* now send a SMBtrans command with api RNetShareEnum */
01043   p = make_header(param, RAP_WFileEnum2,
01044                   RAP_WFileEnum2_REQ, RAP_FILE_INFO_L3); 
01045 
01046   PUTSTRING(p, base_path, 256);
01047   PUTSTRING(p, user, RAP_USERNAME_LEN);
01048   PUTWORD(p, 3); /* info level */
01049   PUTWORD(p, 0xFF00);  /* buffer size */ 
01050   PUTDWORD(p, 0);  /* zero out the resume key */
01051   PUTDWORD(p, 0);  /* or is this one the resume key? */
01052                  
01053   if (cli_api(cli, 
01054               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
01055               NULL, 0, 0xFF00,  /* data, length, maxlen */
01056               &rparam, &rprcnt,               /* return params, length */
01057               &rdata, &rdrcnt))               /* return data, length */
01058     {
01059       int res = GETRES(rparam);
01060       
01061       if (res == 0 || res == ERRmoredata) {
01062         int converter, i;
01063 
01064         p = rparam + WORDSIZE; /* skip result */
01065         GETWORD(p, converter);
01066         GETWORD(p, count);
01067         
01068         p = rdata;
01069         for (i=0; i<count; i++) {
01070           int id, perms, locks;
01071           pstring fpath, fuser;
01072           
01073           GETDWORD(p, id);
01074           GETWORD(p, perms);
01075           GETWORD(p, locks);
01076           GETSTRINGP(p, fpath, rdata, converter);
01077           GETSTRINGP(p, fuser, rdata, converter);
01078 
01079           fn(fpath, fuser, perms, locks, id);
01080         }  /* BB fix ERRmoredata case to send resume request */
01081       } else {
01082         DEBUG(4,("NetFileEnum2 res=%d\n", res));
01083       }      
01084     } else {
01085       DEBUG(4,("NetFileEnum2 failed\n"));
01086     }
01087   
01088   SAFE_FREE(rparam);
01089   SAFE_FREE(rdata);
01090   
01091   return count;
01092 }
01093 
01094 /****************************************************************************
01095  call a NetShareAdd - share/export directory on remote server
01096 ****************************************************************************/
01097 int cli_NetShareAdd(struct cli_state *cli, RAP_SHARE_INFO_2 * sinfo )
01098 {
01099   char *rparam = NULL;
01100   char *rdata = NULL;
01101   char *p;
01102   unsigned int rdrcnt,rprcnt;
01103   int res;
01104   char param[WORDSIZE                  /* api number    */
01105             +sizeof(RAP_WShareAdd_REQ) /* req string    */
01106             +sizeof(RAP_SHARE_INFO_L2) /* return string */
01107             +WORDSIZE                  /* info level    */
01108             +WORDSIZE];                /* reserved word */
01109   char data[1024];
01110   /* offset to free format string section following fixed length data.  */
01111   /* will be updated by PUTSTRINGP macro and will end up with total len */
01112   int soffset = RAP_SHARENAME_LEN + 1 /* share name + pad   */
01113     + WORDSIZE                        /* share type    */
01114     + DWORDSIZE                       /* comment pointer */
01115     + WORDSIZE                        /* permissions */
01116     + WORDSIZE                        /* max users */
01117     + WORDSIZE                        /* active users */
01118     + DWORDSIZE                       /* share path */
01119     + RAP_SPASSWD_LEN + 1;            /* share password + pad */
01120 
01121   memset(param,'\0',sizeof(param));
01122   /* now send a SMBtrans command with api RNetShareAdd */
01123   p = make_header(param, RAP_WshareAdd,
01124                   RAP_WShareAdd_REQ, RAP_SHARE_INFO_L2); 
01125   PUTWORD(p, 2); /* info level */
01126   PUTWORD(p, 0); /* reserved word 0 */
01127 
01128   p = data;
01129   PUTSTRINGF(p, sinfo->share_name, RAP_SHARENAME_LEN);
01130   PUTBYTE(p, 0); /* pad byte 0 */
01131 
01132   PUTWORD(p, sinfo->share_type);
01133   PUTSTRINGP(p, sinfo->comment, data, soffset);
01134   PUTWORD(p, sinfo->perms);
01135   PUTWORD(p, sinfo->maximum_users);
01136   PUTWORD(p, sinfo->active_users);
01137   PUTSTRINGP(p, sinfo->path, data, soffset);
01138   PUTSTRINGF(p, sinfo->password, RAP_SPASSWD_LEN);
01139   SCVAL(p,-1,0x0A); /* required 0x0A at end of password */
01140   
01141   if (cli_api(cli, 
01142               param, sizeof(param), 1024, /* Param, length, maxlen */
01143               data, soffset, sizeof(data), /* data, length, maxlen */
01144               &rparam, &rprcnt,   /* return params, length */
01145               &rdata, &rdrcnt))   /* return data, length */
01146     {
01147       res = rparam? SVAL(rparam,0) : -1;
01148                         
01149       if (res == 0) {
01150         /* nothing to do */             
01151       }
01152       else {
01153         DEBUG(4,("NetShareAdd res=%d\n", res));
01154       }      
01155     } else {
01156       res = -1;
01157       DEBUG(4,("NetShareAdd failed\n"));
01158     }
01159   
01160   SAFE_FREE(rparam);
01161   SAFE_FREE(rdata);
01162   
01163   return res;
01164 }
01165 /****************************************************************************
01166  call a NetShareDelete - unshare exported directory on remote server
01167 ****************************************************************************/
01168 int cli_NetShareDelete(struct cli_state *cli, const char * share_name )
01169 {
01170   char *rparam = NULL;
01171   char *rdata = NULL;
01172   char *p;
01173   unsigned int rdrcnt,rprcnt;
01174   int res;
01175   char param[WORDSIZE                  /* api number    */
01176             +sizeof(RAP_WShareDel_REQ) /* req string    */
01177             +1                         /* no ret string */
01178             +RAP_SHARENAME_LEN         /* share to del  */
01179             +WORDSIZE];                /* reserved word */
01180             
01181 
01182   /* now send a SMBtrans command with api RNetShareDelete */
01183   p = make_header(param, RAP_WshareDel, RAP_WShareDel_REQ, NULL);
01184   PUTSTRING(p,share_name,RAP_SHARENAME_LEN);
01185   PUTWORD(p,0);  /* reserved word MBZ on input */
01186                  
01187   if (cli_api(cli, 
01188               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
01189               NULL, 0, 200,       /* data, length, maxlen */
01190               &rparam, &rprcnt,   /* return params, length */
01191               &rdata, &rdrcnt))   /* return data, length */
01192     {
01193       res = GETRES(rparam);
01194                         
01195       if (res == 0) {
01196         /* nothing to do */             
01197       }
01198       else {
01199         DEBUG(4,("NetShareDelete res=%d\n", res));
01200       }      
01201     } else {
01202       res = -1;
01203       DEBUG(4,("NetShareDelete failed\n"));
01204     }
01205   
01206   SAFE_FREE(rparam);
01207   SAFE_FREE(rdata);
01208         
01209   return res;
01210 }
01211 /*************************************************************************
01212 *
01213 * Function Name:  cli_get_pdc_name
01214 *
01215 * PURPOSE:  Remotes a NetServerEnum API call to the current server
01216 *           requesting the name of a server matching the server
01217 *           type of SV_TYPE_DOMAIN_CTRL (PDC).
01218 *
01219 * Dependencies: none
01220 *
01221 * Parameters: 
01222 *             cli       - pointer to cli_state structure
01223 *             workgroup - pointer to string containing name of domain
01224 *             pdc_name  - pointer to string that will contain PDC name
01225 *                         on successful return
01226 *
01227 * Returns:
01228 *             True      - success
01229 *             False     - failure
01230 *
01231 ************************************************************************/
01232 BOOL cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name)
01233 {
01234   char *rparam = NULL;
01235   char *rdata = NULL;
01236   unsigned int rdrcnt,rprcnt;
01237   char *p;
01238   char param[WORDSIZE                       /* api number    */
01239             +sizeof(RAP_NetServerEnum2_REQ) /* req string    */
01240             +sizeof(RAP_SERVER_INFO_L1)     /* return string */
01241             +WORDSIZE                       /* info level    */
01242             +WORDSIZE                       /* buffer size   */
01243             +DWORDSIZE                      /* server type   */
01244             +RAP_MACHNAME_LEN];             /* workgroup     */
01245   int count = -1;
01246   
01247   *pdc_name = '\0';
01248 
01249   /* send a SMBtrans command with api NetServerEnum */
01250   p = make_header(param, RAP_NetServerEnum2,
01251                   RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L1);
01252   PUTWORD(p, 1); /* info level */
01253   PUTWORD(p, CLI_BUFFER_SIZE);
01254   PUTDWORD(p, SV_TYPE_DOMAIN_CTRL);
01255   PUTSTRING(p, workgroup, RAP_MACHNAME_LEN);
01256         
01257   if (cli_api(cli, 
01258               param, PTR_DIFF(p,param), 8,        /* params, length, max */
01259               NULL, 0, CLI_BUFFER_SIZE,               /* data, length, max */
01260               &rparam, &rprcnt,                   /* return params, return size */
01261               &rdata, &rdrcnt                     /* return data, return size */
01262               )) {
01263     cli->rap_error = GETRES(rparam);
01264                         
01265         /*
01266          * We only really care to copy a name if the
01267          * API succeeded and we got back a name.
01268          */
01269     if (cli->rap_error == 0) {
01270       p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
01271       GETWORD(p, count);
01272       p = rdata;
01273       
01274       if (count > 0)
01275         GETSTRING(p, pdc_name);
01276     }
01277     else {
01278         DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. "
01279                  "Error was : %s.\n", cli->desthost, cli_errstr(cli) ));
01280     }
01281   }
01282   
01283   SAFE_FREE(rparam);
01284   SAFE_FREE(rdata);
01285   
01286   return(count > 0);
01287 }
01288 
01289 
01290 /*************************************************************************
01291 *
01292 * Function Name:  cli_get_server_domain
01293 *
01294 * PURPOSE:  Remotes a NetWkstaGetInfo API call to the current server
01295 *           requesting wksta_info_10 level information to determine
01296 *           the domain the server belongs to. On success, this
01297 *           routine sets the server_domain field in the cli_state structure
01298 *           to the server's domain name.
01299 *
01300 * Dependencies: none
01301 *
01302 * Parameters: 
01303 *             cli       - pointer to cli_state structure
01304 *
01305 * Returns:
01306 *             True      - success
01307 *             False     - failure
01308 *
01309 * Origins:  samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
01310 *
01311 ************************************************************************/
01312 BOOL cli_get_server_domain(struct cli_state *cli)
01313 {
01314   char *rparam = NULL;
01315   char *rdata = NULL;
01316   unsigned int rdrcnt,rprcnt;
01317   char *p;
01318   char param[WORDSIZE                      /* api number    */
01319             +sizeof(RAP_WWkstaGetInfo_REQ) /* req string    */
01320             +sizeof(RAP_WKSTA_INFO_L10)    /* return string */
01321             +WORDSIZE                      /* info level    */
01322             +WORDSIZE];                    /* buffer size   */
01323   int res = -1;
01324   
01325   /* send a SMBtrans command with api NetWkstaGetInfo */
01326   p = make_header(param, RAP_WWkstaGetInfo,
01327                   RAP_WWkstaGetInfo_REQ, RAP_WKSTA_INFO_L10);
01328   PUTWORD(p, 10); /* info level */
01329   PUTWORD(p, CLI_BUFFER_SIZE);
01330         
01331   if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */
01332               NULL, 0, CLI_BUFFER_SIZE,         /* data, length, max */
01333               &rparam, &rprcnt,         /* return params, return size */
01334               &rdata, &rdrcnt)) {       /* return data, return size */
01335     res = GETRES(rparam);
01336     p = rdata;          
01337     
01338     if (res == 0) {
01339       int converter;
01340 
01341       p = rparam + WORDSIZE;
01342       GETWORD(p, converter);
01343       
01344       p = rdata + DWORDSIZE + DWORDSIZE; /* skip computer & user names */
01345       GETSTRINGP(p, cli->server_domain, rdata, converter);
01346     }
01347   }
01348   
01349   SAFE_FREE(rparam);
01350   SAFE_FREE(rdata);
01351   
01352   return(res == 0);
01353 }
01354 
01355 
01356 /*************************************************************************
01357 *
01358 * Function Name:  cli_get_server_type
01359 *
01360 * PURPOSE:  Remotes a NetServerGetInfo API call to the current server
01361 *           requesting server_info_1 level information to retrieve
01362 *           the server type.
01363 *
01364 * Dependencies: none
01365 *
01366 * Parameters: 
01367 *             cli       - pointer to cli_state structure
01368 *             pstype    - pointer to uint32 to contain returned server type
01369 *
01370 * Returns:
01371 *             True      - success
01372 *             False     - failure
01373 *
01374 * Origins:  samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum()
01375 *
01376 ************************************************************************/
01377 BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype)
01378 {
01379   char *rparam = NULL;
01380   char *rdata = NULL;
01381   unsigned int rdrcnt,rprcnt;
01382   char *p;
01383   char param[WORDSIZE                       /* api number    */
01384             +sizeof(RAP_WserverGetInfo_REQ) /* req string    */
01385             +sizeof(RAP_SERVER_INFO_L1)     /* return string */
01386             +WORDSIZE                       /* info level    */
01387             +WORDSIZE];                     /* buffer size   */
01388   int res = -1;
01389   
01390   /* send a SMBtrans command with api NetServerGetInfo */
01391   p = make_header(param, RAP_WserverGetInfo,
01392                   RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1);
01393   PUTWORD(p, 1); /* info level */
01394   PUTWORD(p, CLI_BUFFER_SIZE);
01395         
01396   if (cli_api(cli, 
01397               param, PTR_DIFF(p,param), 8, /* params, length, max */
01398               NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
01399               &rparam, &rprcnt,         /* return params, return size */
01400               &rdata, &rdrcnt           /* return data, return size */
01401               )) {
01402     
01403     res = GETRES(rparam);
01404     
01405     if (res == 0 || res == ERRmoredata) {
01406       p = rdata;                                        
01407       *pstype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
01408     }
01409   }
01410   
01411   SAFE_FREE(rparam);
01412   SAFE_FREE(rdata);
01413   
01414   return(res == 0 || res == ERRmoredata);
01415 }
01416 
01417 BOOL cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli,
01418                          char **servername)
01419 {
01420         char *rparam = NULL;
01421         char *rdata = NULL;
01422         unsigned int rdrcnt,rprcnt;
01423         char *p;
01424         char param[WORDSIZE                       /* api number    */
01425                    +sizeof(RAP_WserverGetInfo_REQ) /* req string    */
01426                    +sizeof(RAP_SERVER_INFO_L1)     /* return string */
01427                    +WORDSIZE                       /* info level    */
01428                    +WORDSIZE];                     /* buffer size   */
01429         BOOL res = False;
01430         fstring tmp;
01431   
01432         /* send a SMBtrans command with api NetServerGetInfo */
01433         p = make_header(param, RAP_WserverGetInfo,
01434                         RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1);
01435         PUTWORD(p, 1); /* info level */
01436         PUTWORD(p, CLI_BUFFER_SIZE);
01437         
01438         if (!cli_api(cli, 
01439                      param, PTR_DIFF(p,param), 8, /* params, length, max */
01440                      NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
01441                      &rparam, &rprcnt,         /* return params, return size */
01442                      &rdata, &rdrcnt           /* return data, return size */
01443                     )) {
01444                 goto failed;
01445         }
01446     
01447         if (GETRES(rparam) != 0) {
01448                 goto failed;
01449         }
01450 
01451         if (rdrcnt < 16) {
01452                 DEBUG(10, ("invalid data count %d, expected >= 16\n", rdrcnt));
01453                 goto failed;
01454         }
01455 
01456         if (pull_ascii(tmp, rdata, sizeof(tmp)-1, 16, STR_TERMINATE) == -1) {
01457                 DEBUG(10, ("pull_ascii failed\n"));
01458                 goto failed;
01459         }
01460 
01461         if (!(*servername = talloc_strdup(mem_ctx, tmp))) {
01462                 DEBUG(1, ("talloc_strdup failed\n"));
01463                 goto failed;
01464         }
01465 
01466         res = True;
01467 
01468  failed:
01469         SAFE_FREE(rparam);
01470         SAFE_FREE(rdata);
01471         return res;
01472 }
01473 
01474 /*************************************************************************
01475 *
01476 * Function Name:  cli_ns_check_server_type
01477 *
01478 * PURPOSE:  Remotes a NetServerEnum2 API call to the current server
01479 *           requesting server_info_0 level information of machines
01480 *           matching the given server type. If the returned server
01481 *           list contains the machine name contained in cli->desthost
01482 *           then we conclude the server type checks out. This routine
01483 *           is useful to retrieve list of server's of a certain
01484 *           type when all you have is a null session connection and
01485 *           can't remote API calls such as NetWkstaGetInfo or 
01486 *           NetServerGetInfo.
01487 *
01488 * Dependencies: none
01489 *
01490 * Parameters: 
01491 *             cli       - pointer to cli_state structure
01492 *             workgroup - pointer to string containing domain
01493 *             stype     - server type
01494 *
01495 * Returns:
01496 *             True      - success
01497 *             False     - failure
01498 *
01499 ************************************************************************/
01500 BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype)
01501 {
01502   char *rparam = NULL;
01503   char *rdata = NULL;
01504   unsigned int rdrcnt,rprcnt;
01505   char *p;
01506   char param[WORDSIZE                       /* api number    */
01507             +sizeof(RAP_NetServerEnum2_REQ) /* req string    */
01508             +sizeof(RAP_SERVER_INFO_L0)     /* return string */
01509             +WORDSIZE                       /* info level    */
01510             +WORDSIZE                       /* buffer size   */
01511             +DWORDSIZE                      /* server type   */
01512             +RAP_MACHNAME_LEN];             /* workgroup     */
01513   BOOL found_server = False;
01514   int res = -1;
01515   
01516   /* send a SMBtrans command with api NetServerEnum */
01517   p = make_header(param, RAP_NetServerEnum2,
01518                   RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L0);
01519   PUTWORD(p, 0); /* info level 0 */
01520   PUTWORD(p, CLI_BUFFER_SIZE);
01521   PUTDWORD(p, stype);
01522   PUTSTRING(p, workgroup, RAP_MACHNAME_LEN);
01523         
01524   if (cli_api(cli, 
01525               param, PTR_DIFF(p,param), 8, /* params, length, max */
01526               NULL, 0, CLI_BUFFER_SIZE,  /* data, length, max */
01527               &rparam, &rprcnt,          /* return params, return size */
01528               &rdata, &rdrcnt            /* return data, return size */
01529               )) {
01530         
01531     res = GETRES(rparam);
01532     cli->rap_error = res;
01533 
01534     if (res == 0 || res == ERRmoredata) {
01535       int i, count;
01536 
01537       p = rparam + WORDSIZE + WORDSIZE;
01538       GETWORD(p, count);
01539 
01540       p = rdata;
01541       for (i = 0;i < count;i++, p += 16) {
01542         char ret_server[RAP_MACHNAME_LEN];
01543 
01544         GETSTRINGF(p, ret_server, RAP_MACHNAME_LEN);
01545         if (strequal(ret_server, cli->desthost)) {
01546           found_server = True;
01547           break;
01548         }
01549       }
01550     }
01551     else {
01552       DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. "
01553                "Error was : %s.\n", cli->desthost, cli_errstr(cli) ));
01554     }
01555   }
01556   
01557   SAFE_FREE(rparam);
01558   SAFE_FREE(rdata);
01559         
01560   return found_server;
01561  }
01562 
01563 
01564 /****************************************************************************
01565  perform a NetWkstaUserLogoff
01566 ****************************************************************************/
01567 BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation)
01568 {
01569   char *rparam = NULL;
01570   char *rdata = NULL;
01571   char *p;
01572   unsigned int rdrcnt,rprcnt;
01573   char param[WORDSIZE                           /* api number    */
01574             +sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string    */
01575             +sizeof(RAP_USER_LOGOFF_INFO_L1)    /* return string */
01576             +RAP_USERNAME_LEN+1                 /* user name+pad */
01577             +RAP_MACHNAME_LEN                   /* wksta name    */
01578             +WORDSIZE                           /* buffer size   */
01579             +WORDSIZE];                         /* buffer size?  */
01580   fstring upperbuf;
01581   
01582   memset(param, 0, sizeof(param));
01583 
01584   /* send a SMBtrans command with api NetWkstaUserLogoff */
01585   p = make_header(param, RAP_WWkstaUserLogoff,
01586                   RAP_NetWkstaUserLogoff_REQ, RAP_USER_LOGOFF_INFO_L1);
01587   PUTDWORD(p, 0); /* Null pointer */
01588   PUTDWORD(p, 0); /* Null pointer */
01589   fstrcpy(upperbuf, user);
01590   strupper_m(upperbuf);
01591   PUTSTRINGF(p, upperbuf, RAP_USERNAME_LEN);
01592   p++; /* strange format, but ok */
01593   fstrcpy(upperbuf, workstation);
01594   strupper_m(upperbuf);
01595   PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN);
01596   PUTWORD(p, CLI_BUFFER_SIZE);
01597   PUTWORD(p, CLI_BUFFER_SIZE);
01598   
01599   if (cli_api(cli,
01600               param, PTR_DIFF(p,param),1024,  /* param, length, max */
01601               NULL, 0, CLI_BUFFER_SIZE,       /* data, length, max */
01602               &rparam, &rprcnt,               /* return params, return size */
01603               &rdata, &rdrcnt                 /* return data, return size */
01604               )) {
01605     cli->rap_error = GETRES(rparam);
01606     
01607     if (cli->rap_error != 0) {
01608       DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli->rap_error));
01609     }
01610   }
01611   
01612   SAFE_FREE(rparam);
01613   SAFE_FREE(rdata);
01614   return (cli->rap_error == 0);
01615 }
01616  
01617 int cli_NetPrintQEnum(struct cli_state *cli,
01618                 void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16),
01619                 void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*))
01620 {
01621   char param[WORDSIZE                         /* api number    */
01622             +sizeof(RAP_NetPrintQEnum_REQ)    /* req string    */
01623             +sizeof(RAP_PRINTQ_INFO_L2)       /* return string */
01624             +WORDSIZE                         /* info level    */
01625             +WORDSIZE                         /* buffer size   */
01626             +sizeof(RAP_SMB_PRINT_JOB_L1)];   /* more ret data */
01627   char *p;
01628   char *rparam = NULL;
01629   char *rdata = NULL; 
01630   unsigned int rprcnt, rdrcnt;
01631   int res = -1;
01632   
01633 
01634   memset(param, '\0',sizeof(param));
01635   p = make_header(param, RAP_WPrintQEnum, 
01636                   RAP_NetPrintQEnum_REQ, RAP_PRINTQ_INFO_L2);
01637   PUTWORD(p,2); /* Info level 2 */
01638   PUTWORD(p,0xFFE0); /* Return buffer size */
01639   PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0);
01640 
01641   if (cli_api(cli,
01642               param, PTR_DIFF(p,param),1024,
01643               NULL, 0, CLI_BUFFER_SIZE,
01644               &rparam, &rprcnt,
01645               &rdata, &rdrcnt)) {
01646     res = GETRES(rparam);
01647     cli->rap_error = res;
01648     if (res != 0) {
01649       DEBUG(1,("NetPrintQEnum gave error %d\n", res));
01650     }
01651   }
01652 
01653   if (rdata) {
01654     if (res == 0 || res == ERRmoredata) {
01655       int i, converter, count;
01656 
01657       p = rparam + WORDSIZE;
01658       GETWORD(p, converter);
01659       GETWORD(p, count);
01660 
01661       p = rdata;
01662       for (i=0;i<count;i++) {
01663         pstring qname, sep_file, print_proc, dest, parms, comment;
01664         uint16 jobcount, priority, start_time, until_time, status;
01665 
01666         GETSTRINGF(p, qname, RAP_SHARENAME_LEN);
01667         p++; /* pad */
01668         GETWORD(p, priority);
01669         GETWORD(p, start_time);
01670         GETWORD(p, until_time);
01671         GETSTRINGP(p, sep_file, rdata, converter);
01672         GETSTRINGP(p, print_proc, rdata, converter);
01673         GETSTRINGP(p, dest, rdata, converter);
01674         GETSTRINGP(p, parms, rdata, converter);
01675         GETSTRINGP(p, parms, comment, converter);
01676         GETWORD(p, status);
01677         GETWORD(p, jobcount);
01678 
01679         qfn(qname, priority, start_time, until_time, sep_file, print_proc,
01680             dest, parms, comment, status, jobcount);
01681 
01682         if (jobcount) {
01683           int j;
01684           for (j=0;j<jobcount;j++) {
01685             uint16 jid, pos, fsstatus;
01686             pstring ownername, notifyname, datatype, jparms, jstatus, jcomment;
01687             unsigned int submitted, jsize;
01688             
01689             GETWORD(p, jid);
01690             GETSTRINGF(p, ownername, RAP_USERNAME_LEN);
01691             p++; /* pad byte */
01692             GETSTRINGF(p, notifyname, RAP_MACHNAME_LEN);
01693             GETSTRINGF(p, datatype, RAP_DATATYPE_LEN);
01694             GETSTRINGP(p, jparms, rdata, converter);
01695             GETWORD(p, pos);
01696             GETWORD(p, fsstatus);
01697             GETSTRINGP(p, jstatus, rdata, converter);
01698             GETDWORD(p, submitted);
01699             GETDWORD(p, jsize);
01700             GETSTRINGP(p, jcomment, rdata, converter);
01701           
01702             jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus,
01703                 jstatus, submitted, jsize, jcomment);
01704           }
01705         }
01706       }
01707     } else {
01708       DEBUG(4,("NetPrintQEnum res=%d\n", res));
01709     }
01710   } else {
01711     DEBUG(4,("NetPrintQEnum no data returned\n"));
01712   }
01713     
01714   SAFE_FREE(rparam);
01715   SAFE_FREE(rdata);
01716 
01717   return res;  
01718 }
01719 
01720 int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer,
01721         void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16),
01722         void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*))
01723 {
01724   char param[WORDSIZE                         /* api number    */
01725             +sizeof(RAP_NetPrintQGetInfo_REQ) /* req string    */
01726             +sizeof(RAP_PRINTQ_INFO_L2)       /* return string */ 
01727             +RAP_SHARENAME_LEN                /* printer name  */
01728             +WORDSIZE                         /* info level    */
01729             +WORDSIZE                         /* buffer size   */
01730             +sizeof(RAP_SMB_PRINT_JOB_L1)];   /* more ret data */
01731   char *p;
01732   char *rparam = NULL;
01733   char *rdata = NULL; 
01734   unsigned int rprcnt, rdrcnt;
01735   int res = -1;
01736   
01737 
01738   memset(param, '\0',sizeof(param));
01739   p = make_header(param, RAP_WPrintQGetInfo,
01740                   RAP_NetPrintQGetInfo_REQ, RAP_PRINTQ_INFO_L2);
01741   PUTSTRING(p, printer, RAP_SHARENAME_LEN-1);
01742   PUTWORD(p, 2);     /* Info level 2 */
01743   PUTWORD(p,0xFFE0); /* Return buffer size */
01744   PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0);
01745 
01746   if (cli_api(cli,
01747               param, PTR_DIFF(p,param),1024,
01748               NULL, 0, CLI_BUFFER_SIZE,
01749               &rparam, &rprcnt,
01750               &rdata, &rdrcnt)) {
01751     res = GETRES(rparam);
01752     cli->rap_error = res;
01753     if (res != 0) {
01754       DEBUG(1,("NetPrintQGetInfo gave error %d\n", res));
01755     }
01756   }
01757 
01758   if (rdata) {
01759     if (res == 0 || res == ERRmoredata) {
01760       int rsize, converter;
01761       pstring qname, sep_file, print_proc, dest, parms, comment;
01762       uint16 jobcount, priority, start_time, until_time, status;
01763       
01764       p = rparam + WORDSIZE;
01765       GETWORD(p, converter);
01766       GETWORD(p, rsize);
01767 
01768       p = rdata;
01769       GETSTRINGF(p, qname, RAP_SHARENAME_LEN);
01770       p++; /* pad */
01771       GETWORD(p, priority);
01772       GETWORD(p, start_time);
01773       GETWORD(p, until_time);
01774       GETSTRINGP(p, sep_file, rdata, converter);
01775       GETSTRINGP(p, print_proc, rdata, converter);
01776       GETSTRINGP(p, dest, rdata, converter);
01777       GETSTRINGP(p, parms, rdata, converter);
01778       GETSTRINGP(p, comment, rdata, converter);
01779       GETWORD(p, status);
01780       GETWORD(p, jobcount);
01781       qfn(qname, priority, start_time, until_time, sep_file, print_proc,
01782           dest, parms, comment, status, jobcount);
01783       if (jobcount) {
01784         int j;
01785         for (j=0;(j<jobcount)&&(PTR_DIFF(p,rdata)< rsize);j++) {
01786           uint16 jid, pos, fsstatus;
01787           pstring ownername, notifyname, datatype, jparms, jstatus, jcomment;
01788           unsigned int submitted, jsize;
01789 
01790           GETWORD(p, jid);
01791           GETSTRINGF(p, ownername, RAP_USERNAME_LEN);
01792           p++; /* pad byte */
01793           GETSTRINGF(p, notifyname, RAP_MACHNAME_LEN);
01794           GETSTRINGF(p, datatype, RAP_DATATYPE_LEN);
01795           GETSTRINGP(p, jparms, rdata, converter);
01796           GETWORD(p, pos);
01797           GETWORD(p, fsstatus);
01798           GETSTRINGP(p, jstatus, rdata, converter);
01799           GETDWORD(p, submitted);
01800           GETDWORD(p, jsize);
01801           GETSTRINGP(p, jcomment, rdata, converter);
01802           
01803           jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus,
01804               jstatus, submitted, jsize, jcomment);
01805         }
01806       }
01807     } else {
01808       DEBUG(4,("NetPrintQGetInfo res=%d\n", res));
01809     }
01810   } else {
01811     DEBUG(4,("NetPrintQGetInfo no data returned\n"));
01812   }
01813     
01814   SAFE_FREE(rparam);
01815   SAFE_FREE(rdata);
01816 
01817   return res;  
01818 }
01819 
01820 /****************************************************************************
01821 call a NetServiceEnum - list running services on a different host
01822 ****************************************************************************/
01823 int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state)
01824 {
01825   char param[WORDSIZE                     /* api number    */
01826             +sizeof(RAP_NetServiceEnum_REQ) /* parm string   */
01827             +sizeof(RAP_SERVICE_INFO_L2)    /* return string */
01828             +WORDSIZE                     /* info level    */
01829             +WORDSIZE];                   /* buffer size   */
01830   char *p;
01831   char *rparam = NULL;
01832   char *rdata = NULL; 
01833   unsigned int rprcnt, rdrcnt;
01834   int res = -1;
01835   
01836   
01837   memset(param, '\0', sizeof(param));
01838   p = make_header(param, RAP_WServiceEnum,
01839                   RAP_NetServiceEnum_REQ, RAP_SERVICE_INFO_L2);
01840   PUTWORD(p,2); /* Info level 2 */  
01841   PUTWORD(p,0xFFE0); /* Return buffer size */
01842 
01843   if (cli_api(cli,
01844               param, PTR_DIFF(p,param),8,
01845               NULL, 0, 0xFFE0 /* data area size */,
01846               &rparam, &rprcnt,
01847               &rdata, &rdrcnt)) {
01848     res = GETRES(rparam);
01849     cli->rap_error = res;
01850     if(cli->rap_error == 234) 
01851         DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n"));
01852     else if (cli->rap_error != 0) {
01853       DEBUG(1,("NetServiceEnum gave error %d\n", cli->rap_error));
01854     }
01855   }
01856 
01857   if (rdata) {
01858     if (res == 0 || res == ERRmoredata) {
01859       int i, count;
01860 
01861       p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */
01862       GETWORD(p, count);
01863 
01864       for (i=0,p=rdata;i<count;i++) {
01865             pstring comment;
01866             char servicename[RAP_SRVCNAME_LEN];
01867 
01868             GETSTRINGF(p, servicename, RAP_SRVCNAME_LEN);
01869             p+=8; /* pass status words */
01870             GETSTRINGF(p, comment, RAP_SRVCCMNT_LEN);
01871 
01872             fn(servicename, comment, cli);  /* BB add status too */
01873       } 
01874     } else {
01875       DEBUG(4,("NetServiceEnum res=%d\n", res));
01876     }
01877   } else {
01878     DEBUG(4,("NetServiceEnum no data returned\n"));
01879   }
01880     
01881   SAFE_FREE(rparam);
01882   SAFE_FREE(rdata);
01883 
01884   return res;
01885 }
01886 
01887 
01888 /****************************************************************************
01889 call a NetSessionEnum - list workstations with sessions to an SMB server
01890 ****************************************************************************/
01891 int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, uint16, uint16, uint, uint, uint, char *))
01892 {
01893   char param[WORDSIZE                       /* api number    */
01894             +sizeof(RAP_NetSessionEnum_REQ) /* parm string   */
01895             +sizeof(RAP_SESSION_INFO_L2)    /* return string */
01896             +WORDSIZE                       /* info level    */
01897             +WORDSIZE];                     /* buffer size   */
01898   char *p;
01899   char *rparam = NULL;
01900   char *rdata = NULL; 
01901   unsigned int rprcnt, rdrcnt;
01902   int res = -1;
01903   
01904   memset(param, '\0', sizeof(param));
01905   p = make_header(param, RAP_WsessionEnum, 
01906                   RAP_NetSessionEnum_REQ, RAP_SESSION_INFO_L2);
01907   PUTWORD(p,2);    /* Info level 2 */
01908   PUTWORD(p,0xFF); /* Return buffer size */
01909 
01910   if (cli_api(cli,
01911               param, PTR_DIFF(p,param),8,
01912               NULL, 0, CLI_BUFFER_SIZE,
01913               &rparam, &rprcnt,
01914               &rdata, &rdrcnt)) {
01915     res = GETRES(rparam);
01916     cli->rap_error = res;
01917     if (res != 0) {
01918       DEBUG(1,("NetSessionEnum gave error %d\n", res));
01919     }
01920   }
01921 
01922   if (rdata) {
01923     if (res == 0 || res == ERRmoredata) {
01924       int i, converter, count;
01925       
01926       p = rparam + WORDSIZE;
01927       GETWORD(p, converter);
01928       GETWORD(p, count);
01929 
01930       for (i=0,p=rdata;i<count;i++) {
01931         pstring wsname, username, clitype_name;
01932         uint16  num_conns, num_opens, num_users;
01933         unsigned int    sess_time, idle_time, user_flags;
01934 
01935         GETSTRINGP(p, wsname, rdata, converter);
01936         GETSTRINGP(p, username, rdata, converter);
01937         GETWORD(p, num_conns);
01938         GETWORD(p, num_opens);
01939         GETWORD(p, num_users);
01940         GETDWORD(p, sess_time);
01941         GETDWORD(p, idle_time);
01942         GETDWORD(p, user_flags);
01943         GETSTRINGP(p, clitype_name, rdata, converter);
01944 
01945         fn(wsname, username, num_conns, num_opens, num_users, sess_time,
01946            idle_time, user_flags, clitype_name);
01947       }
01948         
01949     } else {
01950       DEBUG(4,("NetSessionEnum res=%d\n", res));
01951     }
01952   } else {
01953     DEBUG(4,("NetSesssionEnum no data returned\n"));
01954   }
01955     
01956   SAFE_FREE(rparam);
01957   SAFE_FREE(rdata);
01958 
01959   return res;
01960 }
01961 
01962 /****************************************************************************
01963  Call a NetSessionGetInfo - get information about other session to an SMB server.
01964 ****************************************************************************/
01965 
01966 int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void (*fn)(const char *, const char *, uint16, uint16, uint16, uint, uint, uint, const char *))
01967 {
01968   char param[WORDSIZE                          /* api number    */
01969             +sizeof(RAP_NetSessionGetInfo_REQ) /* req string    */
01970             +sizeof(RAP_SESSION_INFO_L2)       /* return string */ 
01971             +RAP_MACHNAME_LEN                  /* wksta name    */
01972             +WORDSIZE                          /* info level    */
01973             +WORDSIZE];                        /* buffer size   */
01974   char *p;
01975   char *rparam = NULL;
01976   char *rdata = NULL; 
01977   unsigned int rprcnt, rdrcnt;
01978   int res = -1;
01979   
01980 
01981   memset(param, '\0', sizeof(param));
01982   p = make_header(param, RAP_WsessionGetInfo, 
01983                   RAP_NetSessionGetInfo_REQ, RAP_SESSION_INFO_L2);
01984   PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1);
01985   PUTWORD(p,2); /* Info level 2 */
01986   PUTWORD(p,0xFF); /* Return buffer size */
01987 
01988   if (cli_api(cli,
01989               param, PTR_DIFF(p,param),PTR_DIFF(p,param),
01990               NULL, 0, CLI_BUFFER_SIZE,
01991               &rparam, &rprcnt,
01992               &rdata, &rdrcnt)) {
01993     cli->rap_error = SVAL(rparam,0);
01994     if (cli->rap_error != 0) {
01995       DEBUG(1,("NetSessionGetInfo gave error %d\n", cli->rap_error));
01996     }
01997   }
01998 
01999   if (rdata) {
02000     res = GETRES(rparam);
02001     
02002     if (res == 0 || res == ERRmoredata) {
02003       int converter;
02004       pstring wsname, username, clitype_name;
02005       uint16  num_conns, num_opens, num_users;
02006       unsigned int    sess_time, idle_time, user_flags;
02007 
02008       p = rparam + WORDSIZE;
02009       GETWORD(p, converter);
02010       p += WORDSIZE;            /* skip rsize */
02011 
02012       p = rdata;
02013       GETSTRINGP(p, wsname, rdata, converter);
02014       GETSTRINGP(p, username, rdata, converter);
02015       GETWORD(p, num_conns);
02016       GETWORD(p, num_opens);
02017       GETWORD(p, num_users);
02018       GETDWORD(p, sess_time);
02019       GETDWORD(p, idle_time);
02020       GETDWORD(p, user_flags);
02021       GETSTRINGP(p, clitype_name, rdata, converter);
02022       
02023       fn(wsname, username, num_conns, num_opens, num_users, sess_time,
02024          idle_time, user_flags, clitype_name);
02025     } else {
02026       DEBUG(4,("NetSessionGetInfo res=%d\n", res));
02027     }
02028   } else {
02029     DEBUG(4,("NetSessionGetInfo no data returned\n"));
02030   }
02031     
02032   SAFE_FREE(rparam);
02033   SAFE_FREE(rdata);
02034 
02035   return res;  
02036 }
02037 
02038 /****************************************************************************
02039 call a NetSessionDel - close a session to an SMB server
02040 ****************************************************************************/
02041 int cli_NetSessionDel(struct cli_state *cli, const char *workstation)
02042 {
02043   char param[WORDSIZE                      /* api number       */
02044             +sizeof(RAP_NetSessionDel_REQ) /* req string       */
02045             +1                             /* no return string */
02046             +RAP_MACHNAME_LEN              /* workstation name */
02047             +WORDSIZE];                    /* reserved (0)     */
02048   char *p;
02049   char *rparam = NULL;
02050   char *rdata = NULL;
02051   unsigned int rprcnt, rdrcnt;
02052   int res;
02053 
02054   memset(param, '\0', sizeof(param));
02055   p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL);
02056   PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1);
02057   PUTWORD(p,0); /* reserved word of 0 */
02058   if (cli_api(cli, 
02059               param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
02060               NULL, 0, 200,       /* data, length, maxlen */
02061               &rparam, &rprcnt,   /* return params, length */
02062               &rdata, &rdrcnt))   /* return data, length */
02063     {
02064       res = GETRES(rparam);
02065       cli->rap_error = res;
02066       
02067       if (res == 0) {
02068         /* nothing to do */             
02069       }
02070       else {
02071         DEBUG(4,("NetFileClose2 res=%d\n", res));
02072       }      
02073     } else {
02074       res = -1;
02075       DEBUG(4,("NetFileClose2 failed\n"));
02076     }
02077   
02078   SAFE_FREE(rparam);
02079   SAFE_FREE(rdata);
02080 
02081   return res;
02082 }
02083   
02084 
02085 int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*fn)(uint16 conid, uint16 contype, uint16 numopens, uint16 numusers, uint32 contime, const char *username, const char *netname))
02086 {
02087   char param[WORDSIZE                          /* api number    */
02088             +sizeof(RAP_NetConnectionEnum_REQ) /* req string    */
02089             +sizeof(RAP_CONNECTION_INFO_L1)    /* return string */ 
02090             +RAP_MACHNAME_LEN                  /* wksta name    */
02091             +WORDSIZE                          /* info level    */
02092             +WORDSIZE];                        /* buffer size   */
02093   char *p;
02094   char *rparam = NULL;
02095   char *rdata = NULL; 
02096   unsigned int rprcnt, rdrcnt;
02097   int res = -1;
02098 
02099   memset(param, '\0', sizeof(param));
02100   p = make_header(param, RAP_WconnectionEnum,
02101                   RAP_NetConnectionEnum_REQ, RAP_CONNECTION_INFO_L1);
02102   PUTSTRING(p, qualifier, RAP_MACHNAME_LEN-1);/* Workstation name */
02103   PUTWORD(p,1);            /* Info level 1 */
02104   PUTWORD(p,0xFFE0);       /* Return buffer size */
02105 
02106   if (cli_api(cli,
02107               param, PTR_DIFF(p,param),PTR_DIFF(p,param),
02108               NULL, 0, CLI_BUFFER_SIZE,
02109               &rparam, &rprcnt,
02110               &rdata, &rdrcnt)) {
02111     res = GETRES(rparam);
02112     cli->rap_error = res;
02113     if (res != 0) {
02114       DEBUG(1,("NetConnectionEnum gave error %d\n", res));
02115     }
02116   }
02117   if (rdata) {
02118     if (res == 0 || res == ERRmoredata) {
02119       int i, converter, count;
02120 
02121       p = rparam + WORDSIZE;
02122       GETWORD(p, converter);
02123       GETWORD(p, count);
02124 
02125       for (i=0,p=rdata;i<count;i++) {
02126         pstring netname, username;
02127         uint16  conn_id, conn_type, num_opens, num_users;
02128         unsigned int    conn_time;
02129 
02130         GETWORD(p,conn_id);
02131         GETWORD(p,conn_type);
02132         GETWORD(p,num_opens);
02133         GETWORD(p,num_users);
02134         GETDWORD(p,conn_time);
02135         GETSTRINGP(p, username, rdata, converter);
02136         GETSTRINGP(p, netname, rdata, converter);
02137 
02138         fn(conn_id, conn_type, num_opens, num_users, conn_time,
02139            username, netname);
02140       }
02141         
02142     } else {
02143       DEBUG(4,("NetConnectionEnum res=%d\n", res));
02144     }
02145   } else {
02146     DEBUG(4,("NetConnectionEnum no data returned\n"));
02147   }
02148   SAFE_FREE(rdata);
02149   SAFE_FREE(rparam);
02150   return res;
02151 }

Sambaに対してSat Aug 29 21:23:04 2009に生成されました。  doxygen 1.4.7