00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "includes.h"
00030
00031 extern struct current_user current_user;
00032 extern userdom_struct current_user_info;
00033
00034 #ifdef CHECK_TYPES
00035 #undef CHECK_TYPES
00036 #endif
00037 #define CHECK_TYPES 0
00038
00039 #define NERR_Success 0
00040 #define NERR_badpass 86
00041 #define NERR_notsupported 50
00042
00043 #define NERR_BASE (2100)
00044 #define NERR_BufTooSmall (NERR_BASE+23)
00045 #define NERR_JobNotFound (NERR_BASE+51)
00046 #define NERR_DestNotFound (NERR_BASE+52)
00047
00048 #define ACCESS_READ 0x01
00049 #define ACCESS_WRITE 0x02
00050 #define ACCESS_CREATE 0x04
00051
00052 #define SHPWLEN 8
00053
00054 static BOOL api_Unsupported(connection_struct *conn, uint16 vuid,
00055 char *param, int tpscnt,
00056 char *data, int tdscnt,
00057 int mdrcnt, int mprcnt,
00058 char **rdata, char **rparam,
00059 int *rdata_len, int *rparam_len);
00060
00061 static BOOL api_TooSmall(connection_struct *conn, uint16 vuid, char *param, char *data,
00062 int mdrcnt, int mprcnt,
00063 char **rdata, char **rparam,
00064 int *rdata_len, int *rparam_len);
00065
00066
00067 static int CopyExpanded(connection_struct *conn,
00068 int snum, char **dst, char *src, int *n)
00069 {
00070 pstring buf;
00071 int l;
00072
00073 if (!src || !dst || !n || !(*dst)) {
00074 return 0;
00075 }
00076
00077 StrnCpy(buf,src,sizeof(buf)/2);
00078 pstring_sub(buf,"%S",lp_servicename(snum));
00079 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00080 conn->connectpath, conn->gid,
00081 get_current_username(),
00082 current_user_info.domain,
00083 buf, sizeof(buf));
00084 l = push_ascii(*dst,buf,*n, STR_TERMINATE);
00085 if (l == -1) {
00086 return 0;
00087 }
00088 (*dst) += l;
00089 (*n) -= l;
00090 return l;
00091 }
00092
00093 static int CopyAndAdvance(char **dst, char *src, int *n)
00094 {
00095 int l;
00096 if (!src || !dst || !n || !(*dst)) {
00097 return 0;
00098 }
00099 l = push_ascii(*dst,src,*n, STR_TERMINATE);
00100 if (l == -1) {
00101 return 0;
00102 }
00103 (*dst) += l;
00104 (*n) -= l;
00105 return l;
00106 }
00107
00108 static int StrlenExpanded(connection_struct *conn, int snum, char *s)
00109 {
00110 pstring buf;
00111 if (!s) {
00112 return 0;
00113 }
00114 StrnCpy(buf,s,sizeof(buf)/2);
00115 pstring_sub(buf,"%S",lp_servicename(snum));
00116 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00117 conn->connectpath, conn->gid,
00118 get_current_username(),
00119 current_user_info.domain,
00120 buf, sizeof(buf));
00121 return strlen(buf) + 1;
00122 }
00123
00124 static char *Expand(connection_struct *conn, int snum, char *s)
00125 {
00126 static pstring buf;
00127 if (!s) {
00128 return NULL;
00129 }
00130 StrnCpy(buf,s,sizeof(buf)/2);
00131 pstring_sub(buf,"%S",lp_servicename(snum));
00132 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
00133 conn->connectpath, conn->gid,
00134 get_current_username(),
00135 current_user_info.domain,
00136 buf, sizeof(buf));
00137 return &buf[0];
00138 }
00139
00140
00141
00142
00143
00144 static BOOL prefix_ok(const char *str, const char *prefix)
00145 {
00146 return(strncmp(str,prefix,strlen(prefix)) == 0);
00147 }
00148
00149 struct pack_desc {
00150 const char *format;
00151 const char *subformat;
00152 char *base;
00153 int buflen;
00154 int subcount;
00155 char *structbuf;
00156 int stringlen;
00157 char *stringbuf;
00158 int neededlen;
00159 int usedlen;
00160 const char *curpos;
00161 int errcode;
00162 };
00163
00164 static int get_counter(const char **p)
00165 {
00166 int i, n;
00167 if (!p || !(*p)) {
00168 return 1;
00169 }
00170 if (!isdigit((int)**p)) {
00171 return 1;
00172 }
00173 for (n = 0;;) {
00174 i = **p;
00175 if (isdigit(i)) {
00176 n = 10 * n + (i - '0');
00177 } else {
00178 return n;
00179 }
00180 (*p)++;
00181 }
00182 }
00183
00184 static int getlen(const char *p)
00185 {
00186 int n = 0;
00187 if (!p) {
00188 return 0;
00189 }
00190
00191 while (*p) {
00192 switch( *p++ ) {
00193 case 'W':
00194 n += 2;
00195 break;
00196 case 'K':
00197 n += 2;
00198 break;
00199 case 'N':
00200 n += 2;
00201 break;
00202 case 'D':
00203 case 'z':
00204 case 'l':
00205 n += 4;
00206 break;
00207 case 'b':
00208 n += 4;
00209 get_counter(&p);
00210 break;
00211 case 'B':
00212 n += get_counter(&p);
00213 break;
00214 }
00215 }
00216 return n;
00217 }
00218
00219 static BOOL init_package(struct pack_desc *p, int count, int subcount)
00220 {
00221 int n = p->buflen;
00222 int i;
00223
00224 if (!p->format || !p->base) {
00225 return False;
00226 }
00227
00228 i = count * getlen(p->format);
00229 if (p->subformat) {
00230 i += subcount * getlen(p->subformat);
00231 }
00232 p->structbuf = p->base;
00233 p->neededlen = 0;
00234 p->usedlen = 0;
00235 p->subcount = 0;
00236 p->curpos = p->format;
00237 if (i > n) {
00238 p->neededlen = i;
00239 i = n = 0;
00240 #if 0
00241
00242
00243
00244
00245
00246
00247 p->errcode = ERRmoredata;
00248 #else
00249 p->errcode = ERRbuftoosmall;
00250 #endif
00251 } else {
00252 p->errcode = NERR_Success;
00253 }
00254 p->buflen = i;
00255 n -= i;
00256 p->stringbuf = p->base + i;
00257 p->stringlen = n;
00258 return (p->errcode == NERR_Success);
00259 }
00260
00261 static int package(struct pack_desc *p, ...)
00262 {
00263 va_list args;
00264 int needed=0, stringneeded;
00265 const char *str=NULL;
00266 int is_string=0, stringused;
00267 int32 temp;
00268
00269 va_start(args,p);
00270
00271 if (!*p->curpos) {
00272 if (!p->subcount) {
00273 p->curpos = p->format;
00274 } else {
00275 p->curpos = p->subformat;
00276 p->subcount--;
00277 }
00278 }
00279 #if CHECK_TYPES
00280 str = va_arg(args,char*);
00281 SMB_ASSERT(strncmp(str,p->curpos,strlen(str)) == 0);
00282 #endif
00283 stringneeded = -1;
00284
00285 if (!p->curpos) {
00286 va_end(args);
00287 return 0;
00288 }
00289
00290 switch( *p->curpos++ ) {
00291 case 'W':
00292 needed = 2;
00293 temp = va_arg(args,int);
00294 if (p->buflen >= needed) {
00295 SSVAL(p->structbuf,0,temp);
00296 }
00297 break;
00298 case 'K':
00299 needed = 2;
00300 temp = va_arg(args,int);
00301 if (p->buflen >= needed) {
00302 SSVAL(p->structbuf,0,temp);
00303 }
00304 break;
00305 case 'N':
00306 needed = 2;
00307 p->subcount = va_arg(args,int);
00308 if (p->buflen >= needed) {
00309 SSVAL(p->structbuf,0,p->subcount);
00310 }
00311 break;
00312 case 'D':
00313 needed = 4;
00314 temp = va_arg(args,int);
00315 if (p->buflen >= needed) {
00316 SIVAL(p->structbuf,0,temp);
00317 }
00318 break;
00319 case 'B':
00320 needed = get_counter(&p->curpos);
00321 {
00322 char *s = va_arg(args,char*);
00323 if (p->buflen >= needed) {
00324 StrnCpy(p->structbuf,s?s:"",needed-1);
00325 }
00326 }
00327 break;
00328 case 'z':
00329 str = va_arg(args,char*);
00330 stringneeded = (str ? strlen(str)+1 : 0);
00331 is_string = 1;
00332 break;
00333 case 'l':
00334 str = va_arg(args,char*);
00335 stringneeded = va_arg(args,int);
00336 is_string = 0;
00337 break;
00338 case 'b':
00339 str = va_arg(args,char*);
00340 stringneeded = get_counter(&p->curpos);
00341 is_string = 0;
00342 break;
00343 }
00344
00345 va_end(args);
00346 if (stringneeded >= 0) {
00347 needed = 4;
00348 if (p->buflen >= needed) {
00349 stringused = stringneeded;
00350 if (stringused > p->stringlen) {
00351 stringused = (is_string ? p->stringlen : 0);
00352 if (p->errcode == NERR_Success) {
00353 p->errcode = ERRmoredata;
00354 }
00355 }
00356 if (!stringused) {
00357 SIVAL(p->structbuf,0,0);
00358 } else {
00359 SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
00360 memcpy(p->stringbuf,str?str:"",stringused);
00361 if (is_string) {
00362 p->stringbuf[stringused-1] = '\0';
00363 }
00364 p->stringbuf += stringused;
00365 p->stringlen -= stringused;
00366 p->usedlen += stringused;
00367 }
00368 }
00369 p->neededlen += stringneeded;
00370 }
00371
00372 p->neededlen += needed;
00373 if (p->buflen >= needed) {
00374 p->structbuf += needed;
00375 p->buflen -= needed;
00376 p->usedlen += needed;
00377 } else {
00378 if (p->errcode == NERR_Success) {
00379 p->errcode = ERRmoredata;
00380 }
00381 }
00382 return 1;
00383 }
00384
00385 #if CHECK_TYPES
00386 #define PACK(desc,t,v) package(desc,t,v,0,0,0,0)
00387 #define PACKl(desc,t,v,l) package(desc,t,v,l,0,0,0,0)
00388 #else
00389 #define PACK(desc,t,v) package(desc,v)
00390 #define PACKl(desc,t,v,l) package(desc,v,l)
00391 #endif
00392
00393 static void PACKI(struct pack_desc* desc, const char *t,int v)
00394 {
00395 PACK(desc,t,v);
00396 }
00397
00398 static void PACKS(struct pack_desc* desc,const char *t,const char *v)
00399 {
00400 PACK(desc,t,v);
00401 }
00402
00403
00404
00405
00406
00407 static void PackDriverData(struct pack_desc* desc)
00408 {
00409 char drivdata[4+4+32];
00410 SIVAL(drivdata,0,sizeof drivdata);
00411 SIVAL(drivdata,4,1000);
00412 memset(drivdata+8,0,32);
00413 push_ascii(drivdata+8,"NULL",32, STR_TERMINATE);
00414 PACKl(desc,"l",drivdata,sizeof drivdata);
00415 }
00416
00417 static int check_printq_info(struct pack_desc* desc,
00418 unsigned int uLevel, char *id1, char *id2)
00419 {
00420 desc->subformat = NULL;
00421 switch( uLevel ) {
00422 case 0:
00423 desc->format = "B13";
00424 break;
00425 case 1:
00426 desc->format = "B13BWWWzzzzzWW";
00427 break;
00428 case 2:
00429 desc->format = "B13BWWWzzzzzWN";
00430 desc->subformat = "WB21BB16B10zWWzDDz";
00431 break;
00432 case 3:
00433 desc->format = "zWWWWzzzzWWzzl";
00434 break;
00435 case 4:
00436 desc->format = "zWWWWzzzzWNzzl";
00437 desc->subformat = "WWzWWDDzz";
00438 break;
00439 case 5:
00440 desc->format = "z";
00441 break;
00442 case 51:
00443 desc->format = "K";
00444 break;
00445 case 52:
00446 desc->format = "WzzzzzzzzN";
00447 desc->subformat = "z";
00448 break;
00449 default:
00450 DEBUG(0,("check_printq_info: invalid level %d\n",
00451 uLevel ));
00452 return False;
00453 }
00454 if (id1 == NULL || strcmp(desc->format,id1) != 0) {
00455 DEBUG(0,("check_printq_info: invalid format %s\n",
00456 id1 ? id1 : "<NULL>" ));
00457 return False;
00458 }
00459 if (desc->subformat && (id2 == NULL || strcmp(desc->subformat,id2) != 0)) {
00460 DEBUG(0,("check_printq_info: invalid subformat %s\n",
00461 id2 ? id2 : "<NULL>" ));
00462 return False;
00463 }
00464 return True;
00465 }
00466
00467
00468 #define RAP_JOB_STATUS_QUEUED 0
00469 #define RAP_JOB_STATUS_PAUSED 1
00470 #define RAP_JOB_STATUS_SPOOLING 2
00471 #define RAP_JOB_STATUS_PRINTING 3
00472 #define RAP_JOB_STATUS_PRINTED 4
00473
00474 #define RAP_QUEUE_STATUS_PAUSED 1
00475 #define RAP_QUEUE_STATUS_ERROR 2
00476
00477
00478
00479 static int printj_status(int v)
00480 {
00481 switch (v) {
00482 case LPQ_QUEUED:
00483 return RAP_JOB_STATUS_QUEUED;
00484 case LPQ_PAUSED:
00485 return RAP_JOB_STATUS_PAUSED;
00486 case LPQ_SPOOLING:
00487 return RAP_JOB_STATUS_SPOOLING;
00488 case LPQ_PRINTING:
00489 return RAP_JOB_STATUS_PRINTING;
00490 }
00491 return 0;
00492 }
00493
00494
00495
00496 static int printq_status(int v)
00497 {
00498 switch (v) {
00499 case LPQ_QUEUED:
00500 return 0;
00501 case LPQ_PAUSED:
00502 return RAP_QUEUE_STATUS_PAUSED;
00503 }
00504 return RAP_QUEUE_STATUS_ERROR;
00505 }
00506
00507 static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
00508 struct pack_desc *desc,
00509 print_queue_struct *queue, int n)
00510 {
00511 time_t t = queue->time;
00512
00513
00514 t -= get_time_zone(t);
00515
00516 PACKI(desc,"W",pjobid_to_rap(lp_const_servicename(snum),queue->job));
00517 if (uLevel == 1) {
00518 PACKS(desc,"B21",queue->fs_user);
00519 PACKS(desc,"B","");
00520 PACKS(desc,"B16","");
00521 PACKS(desc,"B10","PM_Q_RAW");
00522 PACKS(desc,"z","");
00523 PACKI(desc,"W",n+1);
00524 PACKI(desc,"W",printj_status(queue->status));
00525 PACKS(desc,"z","");
00526 PACKI(desc,"D",t);
00527 PACKI(desc,"D",queue->size);
00528 PACKS(desc,"z",queue->fs_file);
00529 }
00530 if (uLevel == 2 || uLevel == 3 || uLevel == 4) {
00531 PACKI(desc,"W",queue->priority);
00532 PACKS(desc,"z",queue->fs_user);
00533 PACKI(desc,"W",n+1);
00534 PACKI(desc,"W",printj_status(queue->status));
00535 PACKI(desc,"D",t);
00536 PACKI(desc,"D",queue->size);
00537 PACKS(desc,"z","Samba");
00538 PACKS(desc,"z",queue->fs_file);
00539 if (uLevel == 3) {
00540 PACKS(desc,"z","");
00541 PACKS(desc,"z","PM_Q_RAW");
00542 PACKS(desc,"z","");
00543 PACKS(desc,"z","");
00544 PACKS(desc,"z",SERVICE(snum));
00545 PACKS(desc,"z","lpd");
00546 PACKS(desc,"z","");
00547 PACKS(desc,"z","NULL");
00548 PackDriverData(desc);
00549 PACKS(desc,"z","");
00550 } else if (uLevel == 4) {
00551 PACKS(desc,"z","");
00552 PACKS(desc,"z","");
00553 PACKS(desc,"z","");
00554 PACKI(desc,"D",0);
00555 PACKI(desc,"D",0);
00556 PACKI(desc,"D",0);
00557 PACKI(desc,"D",0);
00558 PACKI(desc,"D",0);
00559 PACKI(desc,"D",0);
00560 PACKI(desc,"D",0);
00561 }
00562 }
00563 }
00564
00565
00566
00567
00568
00569
00570 static BOOL get_driver_name(int snum, pstring drivername)
00571 {
00572 NT_PRINTER_INFO_LEVEL *info = NULL;
00573 BOOL in_tdb = False;
00574
00575 get_a_printer (NULL, &info, 2, lp_servicename(snum));
00576 if (info != NULL) {
00577 pstrcpy( drivername, info->info_2->drivername);
00578 in_tdb = True;
00579 free_a_printer(&info, 2);
00580 }
00581
00582 return in_tdb;
00583 }
00584
00585
00586
00587
00588
00589 static void fill_printq_info_52(connection_struct *conn, int snum,
00590 struct pack_desc* desc, int count )
00591 {
00592 int i;
00593 fstring location;
00594 NT_PRINTER_DRIVER_INFO_LEVEL driver;
00595 NT_PRINTER_INFO_LEVEL *printer = NULL;
00596
00597 ZERO_STRUCT(driver);
00598
00599 if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
00600 DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n",
00601 lp_servicename(snum)));
00602 goto err;
00603 }
00604
00605 if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
00606 "Windows 4.0", 0)) )
00607 {
00608 DEBUG(3,("fill_printq_info_52: Failed to lookup driver [%s]\n",
00609 printer->info_2->drivername));
00610 goto err;
00611 }
00612
00613 trim_string(driver.info_3->driverpath, "\\print$\\WIN40\\0\\", 0);
00614 trim_string(driver.info_3->datafile, "\\print$\\WIN40\\0\\", 0);
00615 trim_string(driver.info_3->helpfile, "\\print$\\WIN40\\0\\", 0);
00616
00617 PACKI(desc, "W", 0x0400);
00618 PACKS(desc, "z", driver.info_3->name);
00619 PACKS(desc, "z", driver.info_3->driverpath);
00620 PACKS(desc, "z", driver.info_3->datafile);
00621 PACKS(desc, "z", driver.info_3->monitorname);
00622
00623 fstrcpy(location, "\\\\%L\\print$\\WIN40\\0");
00624 standard_sub_basic( "", "", location, sizeof(location)-1 );
00625 PACKS(desc,"z", location);
00626
00627 PACKS(desc,"z", driver.info_3->defaultdatatype);
00628 PACKS(desc,"z", driver.info_3->helpfile);
00629 PACKS(desc,"z", driver.info_3->driverpath);
00630
00631 DEBUG(3,("Printer Driver Name: %s:\n",driver.info_3->name));
00632 DEBUG(3,("Driver: %s:\n",driver.info_3->driverpath));
00633 DEBUG(3,("Data File: %s:\n",driver.info_3->datafile));
00634 DEBUG(3,("Language Monitor: %s:\n",driver.info_3->monitorname));
00635 DEBUG(3,("Driver Location: %s:\n",location));
00636 DEBUG(3,("Data Type: %s:\n",driver.info_3->defaultdatatype));
00637 DEBUG(3,("Help File: %s:\n",driver.info_3->helpfile));
00638 PACKI(desc,"N",count);
00639
00640 for ( i=0; i<count && driver.info_3->dependentfiles && *driver.info_3->dependentfiles[i]; i++)
00641 {
00642 trim_string(driver.info_3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
00643 PACKS(desc,"z",driver.info_3->dependentfiles[i]);
00644 DEBUG(3,("Dependent File: %s:\n",driver.info_3->dependentfiles[i]));
00645 }
00646
00647
00648 if ( i != count )
00649 DEBUG(3,("fill_printq_info_52: file count specified by client [%d] != number of dependent files [%i]\n",
00650 count, i));
00651
00652 DEBUG(3,("fill_printq_info on <%s> gave %d entries\n", SERVICE(snum),i));
00653
00654 desc->errcode=NERR_Success;
00655 goto done;
00656
00657 err:
00658 DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
00659 desc->errcode=NERR_notsupported;
00660
00661 done:
00662 if ( printer )
00663 free_a_printer( &printer, 2 );
00664
00665 if ( driver.info_3 )
00666 free_a_printer_driver( driver, 3 );
00667 }
00668
00669
00670 static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
00671 struct pack_desc* desc,
00672 int count, print_queue_struct* queue,
00673 print_status_struct* status)
00674 {
00675 switch (uLevel) {
00676 case 1:
00677 case 2:
00678 PACKS(desc,"B13",SERVICE(snum));
00679 break;
00680 case 3:
00681 case 4:
00682 case 5:
00683 PACKS(desc,"z",Expand(conn,snum,SERVICE(snum)));
00684 break;
00685 case 51:
00686 PACKI(desc,"K",printq_status(status->status));
00687 break;
00688 }
00689
00690 if (uLevel == 1 || uLevel == 2) {
00691 PACKS(desc,"B","");
00692 PACKI(desc,"W",5);
00693 PACKI(desc,"W",0);
00694 PACKI(desc,"W",0);
00695 PACKS(desc,"z","");
00696 PACKS(desc,"z","lpd");
00697 PACKS(desc,"z",SERVICE(snum));
00698 PACKS(desc,"z","");
00699 if (snum < 0) {
00700 PACKS(desc,"z","UNKNOWN PRINTER");
00701 PACKI(desc,"W",LPSTAT_ERROR);
00702 }
00703 else if (!status || !status->message[0]) {
00704 PACKS(desc,"z",Expand(conn,snum,lp_comment(snum)));
00705 PACKI(desc,"W",LPSTAT_OK);
00706 } else {
00707 PACKS(desc,"z",status->message);
00708 PACKI(desc,"W",printq_status(status->status));
00709 }
00710 PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
00711 }
00712
00713 if (uLevel == 3 || uLevel == 4) {
00714 pstring drivername;
00715
00716 PACKI(desc,"W",5);
00717 PACKI(desc,"W",0);
00718 PACKI(desc,"W",0);
00719 PACKI(desc,"W",5);
00720 PACKS(desc,"z","");
00721 PACKS(desc,"z","WinPrint");
00722 PACKS(desc,"z",NULL);
00723 PACKS(desc,"z",NULL);
00724
00725
00726 if (!status) {
00727 PACKI(desc,"W",LPSTAT_OK);
00728 } else {
00729 PACKI(desc,"W",printq_status(status->status));
00730 }
00731 PACKI(desc,(uLevel == 3 ? "W" : "N"),count);
00732 PACKS(desc,"z",SERVICE(snum));
00733 get_driver_name(snum,drivername);
00734 PACKS(desc,"z",drivername);
00735 PackDriverData(desc);
00736 }
00737
00738 if (uLevel == 2 || uLevel == 4) {
00739 int i;
00740 for (i=0;i<count;i++)
00741 fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
00742 }
00743
00744 if (uLevel==52)
00745 fill_printq_info_52( conn, snum, desc, count );
00746 }
00747
00748
00749 static int get_printerdrivernumber(int snum)
00750 {
00751 int result = 0;
00752 NT_PRINTER_DRIVER_INFO_LEVEL driver;
00753 NT_PRINTER_INFO_LEVEL *printer = NULL;
00754
00755 ZERO_STRUCT(driver);
00756
00757 if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
00758 DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n",
00759 lp_servicename(snum)));
00760 goto done;
00761 }
00762
00763 if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
00764 "Windows 4.0", 0)) )
00765 {
00766 DEBUG(3,("get_printerdrivernumber: Failed to lookup driver [%s]\n",
00767 printer->info_2->drivername));
00768 goto done;
00769 }
00770
00771
00772 while ( driver.info_3->dependentfiles && *driver.info_3->dependentfiles[result] )
00773 result++;
00774 \
00775 done:
00776 if ( printer )
00777 free_a_printer( &printer, 2 );
00778
00779 if ( driver.info_3 )
00780 free_a_printer_driver( driver, 3 );
00781
00782 return result;
00783 }
00784
00785 static BOOL api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
00786 char *param, int tpscnt,
00787 char *data, int tdscnt,
00788 int mdrcnt,int mprcnt,
00789 char **rdata,char **rparam,
00790 int *rdata_len,int *rparam_len)
00791 {
00792 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
00793 char *str2 = skip_string(param,tpscnt,str1);
00794 char *p = skip_string(param,tpscnt,str2);
00795 char *QueueName = p;
00796 unsigned int uLevel;
00797 int count=0;
00798 int snum;
00799 char *str3;
00800 struct pack_desc desc;
00801 print_queue_struct *queue=NULL;
00802 print_status_struct status;
00803 char* tmpdata=NULL;
00804
00805 if (!str1 || !str2 || !p) {
00806 return False;
00807 }
00808 memset((char *)&status,'\0',sizeof(status));
00809 memset((char *)&desc,'\0',sizeof(desc));
00810
00811 p = skip_string(param,tpscnt,p);
00812 if (!p) {
00813 return False;
00814 }
00815 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
00816 str3 = get_safe_str_ptr(param,tpscnt,p,4);
00817
00818
00819
00820 if ((p = strchr_m(QueueName,'%')))
00821 *p = 0;
00822
00823 DEBUG(3,("api_DosPrintQGetInfo uLevel=%d name=%s\n",uLevel,QueueName));
00824
00825
00826 if (!prefix_ok(str1,"zWrLh"))
00827 return False;
00828 if (!check_printq_info(&desc,uLevel,str2,str3)) {
00829
00830
00831
00832
00833
00834 *rdata_len = 0;
00835 *rparam_len = 6;
00836 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
00837 if (!*rparam) {
00838 return False;
00839 }
00840 SSVALS(*rparam,0,ERRunknownlevel);
00841 SSVAL(*rparam,2,0);
00842 SSVAL(*rparam,4,0);
00843 return(True);
00844 }
00845
00846 snum = find_service(QueueName);
00847 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
00848 return False;
00849
00850 if (uLevel==52) {
00851 count = get_printerdrivernumber(snum);
00852 DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
00853 } else {
00854 count = print_queue_status(snum, &queue,&status);
00855 }
00856
00857 if (mdrcnt > 0) {
00858 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
00859 if (!*rdata) {
00860 return False;
00861 }
00862 desc.base = *rdata;
00863 desc.buflen = mdrcnt;
00864 } else {
00865
00866
00867
00868
00869 desc.buflen = getlen(desc.format);
00870 desc.base = tmpdata = (char *) SMB_MALLOC (desc.buflen);
00871 }
00872
00873 if (init_package(&desc,1,count)) {
00874 desc.subcount = count;
00875 fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
00876 }
00877
00878 *rdata_len = desc.usedlen;
00879
00880
00881
00882
00883
00884
00885 if (!mdrcnt && lp_disable_spoolss())
00886 desc.errcode = ERRbuftoosmall;
00887
00888 *rdata_len = desc.usedlen;
00889 *rparam_len = 6;
00890 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
00891 if (!*rparam) {
00892 return False;
00893 }
00894 SSVALS(*rparam,0,desc.errcode);
00895 SSVAL(*rparam,2,0);
00896 SSVAL(*rparam,4,desc.neededlen);
00897
00898 DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
00899
00900 SAFE_FREE(queue);
00901 SAFE_FREE(tmpdata);
00902
00903 return(True);
00904 }
00905
00906
00907
00908
00909
00910 static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
00911 char *param, int tpscnt,
00912 char *data, int tdscnt,
00913 int mdrcnt, int mprcnt,
00914 char **rdata, char** rparam,
00915 int *rdata_len, int *rparam_len)
00916 {
00917 char *param_format = get_safe_str_ptr(param,tpscnt,param,2);
00918 char *output_format1 = skip_string(param,tpscnt,param_format);
00919 char *p = skip_string(param,tpscnt,output_format1);
00920 unsigned int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
00921 char *output_format2 = get_safe_str_ptr(param,tpscnt,p,4);
00922 int services = lp_numservices();
00923 int i, n;
00924 struct pack_desc desc;
00925 print_queue_struct **queue = NULL;
00926 print_status_struct *status = NULL;
00927 int *subcntarr = NULL;
00928 int queuecnt = 0, subcnt = 0, succnt = 0;
00929
00930 if (!param_format || !output_format1 || !p) {
00931 return False;
00932 }
00933
00934 memset((char *)&desc,'\0',sizeof(desc));
00935
00936 DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
00937
00938 if (!prefix_ok(param_format,"WrLeh")) {
00939 return False;
00940 }
00941 if (!check_printq_info(&desc,uLevel,output_format1,output_format2)) {
00942
00943
00944
00945
00946
00947 *rdata_len = 0;
00948 *rparam_len = 6;
00949 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
00950 if (!*rparam) {
00951 return False;
00952 }
00953 SSVALS(*rparam,0,ERRunknownlevel);
00954 SSVAL(*rparam,2,0);
00955 SSVAL(*rparam,4,0);
00956 return(True);
00957 }
00958
00959 for (i = 0; i < services; i++) {
00960 if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
00961 queuecnt++;
00962 }
00963 }
00964
00965 if((queue = SMB_MALLOC_ARRAY(print_queue_struct*, queuecnt)) == NULL) {
00966 DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
00967 goto err;
00968 }
00969 memset(queue,0,queuecnt*sizeof(print_queue_struct*));
00970 if((status = SMB_MALLOC_ARRAY(print_status_struct,queuecnt)) == NULL) {
00971 DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
00972 goto err;
00973 }
00974 memset(status,0,queuecnt*sizeof(print_status_struct));
00975 if((subcntarr = SMB_MALLOC_ARRAY(int,queuecnt)) == NULL) {
00976 DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
00977 goto err;
00978 }
00979
00980 subcnt = 0;
00981 n = 0;
00982 for (i = 0; i < services; i++) {
00983 if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
00984 subcntarr[n] = print_queue_status(i, &queue[n],&status[n]);
00985 subcnt += subcntarr[n];
00986 n++;
00987 }
00988 }
00989
00990 if (mdrcnt > 0) {
00991 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
00992 if (!*rdata) {
00993 goto err;
00994 }
00995 }
00996 desc.base = *rdata;
00997 desc.buflen = mdrcnt;
00998
00999 if (init_package(&desc,queuecnt,subcnt)) {
01000 n = 0;
01001 succnt = 0;
01002 for (i = 0; i < services; i++) {
01003 if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
01004 fill_printq_info(conn,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
01005 n++;
01006 if (desc.errcode == NERR_Success) {
01007 succnt = n;
01008 }
01009 }
01010 }
01011 }
01012
01013 SAFE_FREE(subcntarr);
01014
01015 *rdata_len = desc.usedlen;
01016 *rparam_len = 8;
01017 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
01018 if (!*rparam) {
01019 goto err;
01020 }
01021 SSVALS(*rparam,0,desc.errcode);
01022 SSVAL(*rparam,2,0);
01023 SSVAL(*rparam,4,succnt);
01024 SSVAL(*rparam,6,queuecnt);
01025
01026 for (i = 0; i < queuecnt; i++) {
01027 if (queue) {
01028 SAFE_FREE(queue[i]);
01029 }
01030 }
01031
01032 SAFE_FREE(queue);
01033 SAFE_FREE(status);
01034
01035 return True;
01036
01037 err:
01038
01039 SAFE_FREE(subcntarr);
01040 for (i = 0; i < queuecnt; i++) {
01041 if (queue) {
01042 SAFE_FREE(queue[i]);
01043 }
01044 }
01045 SAFE_FREE(queue);
01046 SAFE_FREE(status);
01047
01048 return False;
01049 }
01050
01051
01052
01053
01054
01055 static BOOL check_server_info(int uLevel, char* id)
01056 {
01057 switch( uLevel ) {
01058 case 0:
01059 if (strcmp(id,"B16") != 0) {
01060 return False;
01061 }
01062 break;
01063 case 1:
01064 if (strcmp(id,"B16BBDz") != 0) {
01065 return False;
01066 }
01067 break;
01068 default:
01069 return False;
01070 }
01071 return True;
01072 }
01073
01074 struct srv_info_struct {
01075 fstring name;
01076 uint32 type;
01077 fstring comment;
01078 fstring domain;
01079 BOOL server_added;
01080 };
01081
01082
01083
01084
01085
01086
01087 static int get_server_info(uint32 servertype,
01088 struct srv_info_struct **servers,
01089 const char *domain)
01090 {
01091 int count=0;
01092 int alloced=0;
01093 char **lines;
01094 BOOL local_list_only;
01095 int i;
01096
01097 lines = file_lines_load(lock_path(SERVER_LIST), NULL, 0);
01098 if (!lines) {
01099 DEBUG(4,("Can't open %s - %s\n",lock_path(SERVER_LIST),strerror(errno)));
01100 return 0;
01101 }
01102
01103
01104 if (servertype == SV_TYPE_ALL) {
01105 servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
01106 }
01107
01108 local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY);
01109
01110 DEBUG(4,("Servertype search: %8x\n",servertype));
01111
01112 for (i=0;lines[i];i++) {
01113 fstring stype;
01114 struct srv_info_struct *s;
01115 const char *ptr = lines[i];
01116 BOOL ok = True;
01117
01118 if (!*ptr) {
01119 continue;
01120 }
01121
01122 if (count == alloced) {
01123 alloced += 10;
01124 *servers = SMB_REALLOC_ARRAY(*servers,struct srv_info_struct, alloced);
01125 if (!*servers) {
01126 DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
01127 file_lines_free(lines);
01128 return 0;
01129 }
01130 memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
01131 }
01132 s = &(*servers)[count];
01133
01134 if (!next_token(&ptr,s->name, NULL, sizeof(s->name))) {
01135 continue;
01136 }
01137 if (!next_token(&ptr,stype, NULL, sizeof(stype))) {
01138 continue;
01139 }
01140 if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) {
01141 continue;
01142 }
01143 if (!next_token(&ptr,s->domain, NULL, sizeof(s->domain))) {
01144
01145 fstrcpy(s->domain,lp_workgroup());
01146 }
01147
01148 if (sscanf(stype,"%X",&s->type) != 1) {
01149 DEBUG(4,("r:host file "));
01150 ok = False;
01151 }
01152
01153
01154
01155
01156 if(local_list_only && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0)) {
01157 DEBUG(4,("r: local list only"));
01158 ok = False;
01159 }
01160
01161
01162 if (!(servertype & s->type)) {
01163 DEBUG(4,("r:serv type "));
01164 ok = False;
01165 }
01166
01167 if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
01168 (s->type & SV_TYPE_DOMAIN_ENUM)) {
01169 DEBUG(4,("s: dom mismatch "));
01170 ok = False;
01171 }
01172
01173 if (!strequal(domain, s->domain) && !(servertype & SV_TYPE_DOMAIN_ENUM)) {
01174 ok = False;
01175 }
01176
01177
01178 s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
01179
01180 if (ok) {
01181 DEBUG(4,("**SV** %20s %8x %25s %15s\n",
01182 s->name, s->type, s->comment, s->domain));
01183 s->server_added = True;
01184 count++;
01185 } else {
01186 DEBUG(4,("%20s %8x %25s %15s\n",
01187 s->name, s->type, s->comment, s->domain));
01188 }
01189 }
01190
01191 file_lines_free(lines);
01192 return count;
01193 }
01194
01195
01196
01197
01198
01199 static int fill_srv_info(struct srv_info_struct *service,
01200 int uLevel, char **buf, int *buflen,
01201 char **stringbuf, int *stringspace, char *baseaddr)
01202 {
01203 int struct_len;
01204 char* p;
01205 char* p2;
01206 int l2;
01207 int len;
01208
01209 switch (uLevel) {
01210 case 0:
01211 struct_len = 16;
01212 break;
01213 case 1:
01214 struct_len = 26;
01215 break;
01216 default:
01217 return -1;
01218 }
01219
01220 if (!buf) {
01221 len = 0;
01222 switch (uLevel) {
01223 case 1:
01224 len = strlen(service->comment)+1;
01225 break;
01226 }
01227
01228 *buflen = struct_len;
01229 *stringspace = len;
01230 return struct_len + len;
01231 }
01232
01233 len = struct_len;
01234 p = *buf;
01235 if (*buflen < struct_len) {
01236 return -1;
01237 }
01238 if (stringbuf) {
01239 p2 = *stringbuf;
01240 l2 = *stringspace;
01241 } else {
01242 p2 = p + struct_len;
01243 l2 = *buflen - struct_len;
01244 }
01245 if (!baseaddr) {
01246 baseaddr = p;
01247 }
01248
01249 switch (uLevel) {
01250 case 0:
01251 push_ascii(p,service->name, MAX_NETBIOSNAME_LEN, STR_TERMINATE);
01252 break;
01253
01254 case 1:
01255 push_ascii(p,service->name,MAX_NETBIOSNAME_LEN, STR_TERMINATE);
01256 SIVAL(p,18,service->type);
01257 SIVAL(p,22,PTR_DIFF(p2,baseaddr));
01258 len += CopyAndAdvance(&p2,service->comment,&l2);
01259 break;
01260 }
01261
01262 if (stringbuf) {
01263 *buf = p + struct_len;
01264 *buflen -= struct_len;
01265 *stringbuf = p2;
01266 *stringspace = l2;
01267 } else {
01268 *buf = p2;
01269 *buflen -= len;
01270 }
01271 return len;
01272 }
01273
01274
01275 static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
01276 {
01277 return(strcmp(s1->name,s2->name));
01278 }
01279
01280
01281
01282
01283
01284
01285 static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid,
01286 char *param, int tpscnt,
01287 char *data, int tdscnt,
01288 int mdrcnt, int mprcnt, char **rdata,
01289 char **rparam, int *rdata_len, int *rparam_len)
01290 {
01291 char *str1 = get_safe_str_ptr(param, tpscnt, param, 2);
01292 char *str2 = skip_string(param,tpscnt,str1);
01293 char *p = skip_string(param,tpscnt,str2);
01294 int uLevel = get_safe_SVAL(param, tpscnt, p, 0, -1);
01295 int buf_len = get_safe_SVAL(param,tpscnt, p, 2, 0);
01296 uint32 servertype = get_safe_IVAL(param,tpscnt,p,4, 0);
01297 char *p2;
01298 int data_len, fixed_len, string_len;
01299 int f_len = 0, s_len = 0;
01300 struct srv_info_struct *servers=NULL;
01301 int counted=0,total=0;
01302 int i,missed;
01303 fstring domain;
01304 BOOL domain_request;
01305 BOOL local_request;
01306
01307 if (!str1 || !str2 || !p) {
01308 return False;
01309 }
01310
01311
01312
01313
01314
01315 if (servertype == SV_TYPE_ALL) {
01316 servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
01317 }
01318
01319
01320
01321
01322
01323
01324
01325 if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM)) {
01326 servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
01327 }
01328
01329 domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
01330 local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
01331
01332 p += 8;
01333
01334 if (!prefix_ok(str1,"WrLehD")) {
01335 return False;
01336 }
01337 if (!check_server_info(uLevel,str2)) {
01338 return False;
01339 }
01340
01341 DEBUG(4, ("server request level: %s %8x ", str2, servertype));
01342 DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
01343 DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
01344
01345 if (strcmp(str1, "WrLehDz") == 0) {
01346 if (skip_string(param,tpscnt,p) == NULL) {
01347 return False;
01348 }
01349 pull_ascii_fstring(domain, p);
01350 } else {
01351 fstrcpy(domain, lp_workgroup());
01352 }
01353
01354 if (lp_browse_list()) {
01355 total = get_server_info(servertype,&servers,domain);
01356 }
01357
01358 data_len = fixed_len = string_len = 0;
01359 missed = 0;
01360
01361 if (total > 0) {
01362 qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp);
01363 }
01364
01365 {
01366 char *lastname=NULL;
01367
01368 for (i=0;i<total;i++) {
01369 struct srv_info_struct *s = &servers[i];
01370
01371 if (lastname && strequal(lastname,s->name)) {
01372 continue;
01373 }
01374 lastname = s->name;
01375 data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
01376 DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
01377 s->name, s->type, s->comment, s->domain));
01378
01379 if (data_len <= buf_len) {
01380 counted++;
01381 fixed_len += f_len;
01382 string_len += s_len;
01383 } else {
01384 missed++;
01385 }
01386 }
01387 }
01388
01389 *rdata_len = fixed_len + string_len;
01390 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
01391 if (!*rdata) {
01392 return False;
01393 }
01394 memset(*rdata,'\0',*rdata_len);
01395
01396 p2 = (*rdata) + fixed_len;
01397 p = *rdata;
01398 f_len = fixed_len;
01399 s_len = string_len;
01400
01401 {
01402 char *lastname=NULL;
01403 int count2 = counted;
01404
01405 for (i = 0; i < total && count2;i++) {
01406 struct srv_info_struct *s = &servers[i];
01407
01408 if (lastname && strequal(lastname,s->name)) {
01409 continue;
01410 }
01411 lastname = s->name;
01412 fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
01413 DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
01414 s->name, s->type, s->comment, s->domain));
01415 count2--;
01416 }
01417 }
01418
01419 *rparam_len = 8;
01420 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
01421 if (!*rparam) {
01422 return False;
01423 }
01424 SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata));
01425 SSVAL(*rparam,2,0);
01426 SSVAL(*rparam,4,counted);
01427 SSVAL(*rparam,6,counted+missed);
01428
01429 SAFE_FREE(servers);
01430
01431 DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
01432 domain,uLevel,counted,counted+missed));
01433
01434 return True;
01435 }
01436
01437
01438
01439
01440
01441 static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid,
01442 char *param, int tpscnt,
01443 char *data, int tdscnt,
01444 int mdrcnt, int mprcnt, char **rdata,
01445 char **rparam, int *rdata_len, int *rparam_len)
01446 {
01447 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
01448 char *str2 = skip_string(param,tpscnt,str1);
01449 char *p = skip_string(param,tpscnt,str2);
01450 int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
01451 int buf_len = get_safe_SVAL(param,tpscnt,p,2,0);
01452 int counted=0;
01453 int missed=0;
01454
01455 if (!str1 || !str2 || !p) {
01456 return False;
01457 }
01458
01459 DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
01460 str1, str2, p, uLevel, buf_len));
01461
01462 if (!prefix_ok(str1,"zWrLeh")) {
01463 return False;
01464 }
01465
01466 *rdata_len = 0;
01467
01468 *rparam_len = 8;
01469 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
01470 if (!*rparam) {
01471 return False;
01472 }
01473
01474 SSVAL(*rparam,0,0x08AC);
01475 SSVAL(*rparam,2,0);
01476 SSVAL(*rparam,4,counted);
01477 SSVAL(*rparam,6,counted+missed);
01478
01479 return True;
01480 }
01481
01482
01483
01484
01485
01486 static BOOL check_share_info(int uLevel, char* id)
01487 {
01488 switch( uLevel ) {
01489 case 0:
01490 if (strcmp(id,"B13") != 0) {
01491 return False;
01492 }
01493 break;
01494 case 1:
01495 if (strcmp(id,"B13BWz") != 0) {
01496 return False;
01497 }
01498 break;
01499 case 2:
01500 if (strcmp(id,"B13BWzWWWzB9B") != 0) {
01501 return False;
01502 }
01503 break;
01504 case 91:
01505 if (strcmp(id,"B13BWzWWWzB9BB9BWzWWzWW") != 0) {
01506 return False;
01507 }
01508 break;
01509 default:
01510 return False;
01511 }
01512 return True;
01513 }
01514
01515 static int fill_share_info(connection_struct *conn, int snum, int uLevel,
01516 char** buf, int* buflen,
01517 char** stringbuf, int* stringspace, char* baseaddr)
01518 {
01519 int struct_len;
01520 char* p;
01521 char* p2;
01522 int l2;
01523 int len;
01524
01525 switch( uLevel ) {
01526 case 0:
01527 struct_len = 13;
01528 break;
01529 case 1:
01530 struct_len = 20;
01531 break;
01532 case 2:
01533 struct_len = 40;
01534 break;
01535 case 91:
01536 struct_len = 68;
01537 break;
01538 default:
01539 return -1;
01540 }
01541
01542
01543 if (!buf) {
01544 len = 0;
01545
01546 if (uLevel > 0) {
01547 len += StrlenExpanded(conn,snum,lp_comment(snum));
01548 }
01549 if (uLevel > 1) {
01550 len += strlen(lp_pathname(snum)) + 1;
01551 }
01552 if (buflen) {
01553 *buflen = struct_len;
01554 }
01555 if (stringspace) {
01556 *stringspace = len;
01557 }
01558 return struct_len + len;
01559 }
01560
01561 len = struct_len;
01562 p = *buf;
01563 if ((*buflen) < struct_len) {
01564 return -1;
01565 }
01566
01567 if (stringbuf) {
01568 p2 = *stringbuf;
01569 l2 = *stringspace;
01570 } else {
01571 p2 = p + struct_len;
01572 l2 = (*buflen) - struct_len;
01573 }
01574
01575 if (!baseaddr) {
01576 baseaddr = p;
01577 }
01578
01579 push_ascii(p,lp_servicename(snum),13, STR_TERMINATE);
01580
01581 if (uLevel > 0) {
01582 int type;
01583
01584 SCVAL(p,13,0);
01585 type = STYPE_DISKTREE;
01586 if (lp_print_ok(snum)) {
01587 type = STYPE_PRINTQ;
01588 }
01589 if (strequal("IPC",lp_fstype(snum))) {
01590 type = STYPE_IPC;
01591 }
01592 SSVAL(p,14,type);
01593 SIVAL(p,16,PTR_DIFF(p2,baseaddr));
01594 len += CopyExpanded(conn,snum,&p2,lp_comment(snum),&l2);
01595 }
01596
01597 if (uLevel > 1) {
01598 SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE);
01599 SSVALS(p,22,-1);
01600 SSVAL(p,24,1);
01601 SIVAL(p,26,PTR_DIFF(p2,baseaddr));
01602 len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
01603 memset(p+30,0,SHPWLEN+2);
01604 }
01605
01606 if (uLevel > 2) {
01607 memset(p+40,0,SHPWLEN+2);
01608 SSVAL(p,50,0);
01609 SIVAL(p,52,0);
01610 SSVAL(p,56,0);
01611 SSVAL(p,58,0);
01612 SIVAL(p,60,0);
01613 SSVAL(p,64,0);
01614 SSVAL(p,66,0);
01615 }
01616
01617 if (stringbuf) {
01618 (*buf) = p + struct_len;
01619 (*buflen) -= struct_len;
01620 (*stringbuf) = p2;
01621 (*stringspace) = l2;
01622 } else {
01623 (*buf) = p2;
01624 (*buflen) -= len;
01625 }
01626
01627 return len;
01628 }
01629
01630 static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
01631 char *param, int tpscnt,
01632 char *data, int tdscnt,
01633 int mdrcnt,int mprcnt,
01634 char **rdata,char **rparam,
01635 int *rdata_len,int *rparam_len)
01636 {
01637 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
01638 char *str2 = skip_string(param,tpscnt,str1);
01639 char *netname = skip_string(param,tpscnt,str2);
01640 char *p = skip_string(param,tpscnt,netname);
01641 int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
01642 int snum;
01643
01644 if (!str1 || !str2 || !netname || !p) {
01645 return False;
01646 }
01647
01648 snum = find_service(netname);
01649 if (snum < 0) {
01650 return False;
01651 }
01652
01653
01654 if (!prefix_ok(str1,"zWrLh")) {
01655 return False;
01656 }
01657 if (!check_share_info(uLevel,str2)) {
01658 return False;
01659 }
01660
01661 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
01662 if (!*rdata) {
01663 return False;
01664 }
01665 p = *rdata;
01666 *rdata_len = fill_share_info(conn,snum,uLevel,&p,&mdrcnt,0,0,0);
01667 if (*rdata_len < 0) {
01668 return False;
01669 }
01670
01671 *rparam_len = 6;
01672 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
01673 if (!*rparam) {
01674 return False;
01675 }
01676 SSVAL(*rparam,0,NERR_Success);
01677 SSVAL(*rparam,2,0);
01678 SSVAL(*rparam,4,*rdata_len);
01679
01680 return True;
01681 }
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693 static BOOL api_RNetShareEnum( connection_struct *conn, uint16 vuid,
01694 char *param, int tpscnt,
01695 char *data, int tdscnt,
01696 int mdrcnt,
01697 int mprcnt,
01698 char **rdata,
01699 char **rparam,
01700 int *rdata_len,
01701 int *rparam_len )
01702 {
01703 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
01704 char *str2 = skip_string(param,tpscnt,str1);
01705 char *p = skip_string(param,tpscnt,str2);
01706 int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
01707 int buf_len = get_safe_SVAL(param,tpscnt,p,2,0);
01708 char *p2;
01709 int count = 0;
01710 int total=0,counted=0;
01711 BOOL missed = False;
01712 int i;
01713 int data_len, fixed_len, string_len;
01714 int f_len = 0, s_len = 0;
01715
01716 if (!str1 || !str2 || !p) {
01717 return False;
01718 }
01719
01720 if (!prefix_ok(str1,"WrLeh")) {
01721 return False;
01722 }
01723 if (!check_share_info(uLevel,str2)) {
01724 return False;
01725 }
01726
01727
01728 become_root();
01729 count = load_usershare_shares();
01730 unbecome_root();
01731
01732 data_len = fixed_len = string_len = 0;
01733 for (i=0;i<count;i++) {
01734 fstring servicename_dos;
01735 if (!(lp_browseable(i) && lp_snum_ok(i))) {
01736 continue;
01737 }
01738 push_ascii_fstring(servicename_dos, lp_servicename(i));
01739
01740 if( lp_browseable( i ) && lp_snum_ok( i ) && (strlen(servicename_dos) < 13)) {
01741 total++;
01742 data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0);
01743 if (data_len <= buf_len) {
01744 counted++;
01745 fixed_len += f_len;
01746 string_len += s_len;
01747 } else {
01748 missed = True;
01749 }
01750 }
01751 }
01752
01753 *rdata_len = fixed_len + string_len;
01754 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
01755 if (!*rdata) {
01756 return False;
01757 }
01758 memset(*rdata,0,*rdata_len);
01759
01760 p2 = (*rdata) + fixed_len;
01761 p = *rdata;
01762 f_len = fixed_len;
01763 s_len = string_len;
01764
01765 for( i = 0; i < count; i++ ) {
01766 fstring servicename_dos;
01767 if (!(lp_browseable(i) && lp_snum_ok(i))) {
01768 continue;
01769 }
01770
01771 push_ascii_fstring(servicename_dos, lp_servicename(i));
01772 if (lp_browseable(i) && lp_snum_ok(i) && (strlen(servicename_dos) < 13)) {
01773 if (fill_share_info( conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata ) < 0) {
01774 break;
01775 }
01776 }
01777 }
01778
01779 *rparam_len = 8;
01780 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
01781 if (!*rparam) {
01782 return False;
01783 }
01784 SSVAL(*rparam,0,missed ? ERRmoredata : NERR_Success);
01785 SSVAL(*rparam,2,0);
01786 SSVAL(*rparam,4,counted);
01787 SSVAL(*rparam,6,total);
01788
01789 DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
01790 counted,total,uLevel,
01791 buf_len,*rdata_len,mdrcnt));
01792
01793 return True;
01794 }
01795
01796
01797
01798
01799
01800 static BOOL api_RNetShareAdd(connection_struct *conn,uint16 vuid,
01801 char *param, int tpscnt,
01802 char *data, int tdscnt,
01803 int mdrcnt,int mprcnt,
01804 char **rdata,char **rparam,
01805 int *rdata_len,int *rparam_len)
01806 {
01807 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
01808 char *str2 = skip_string(param,tpscnt,str1);
01809 char *p = skip_string(param,tpscnt,str2);
01810 int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
01811 fstring sharename;
01812 fstring comment;
01813 pstring pathname;
01814 char *command, *cmdname;
01815 unsigned int offset;
01816 int snum;
01817 int res = ERRunsup;
01818
01819 if (!str1 || !str2 || !p) {
01820 return False;
01821 }
01822
01823
01824 if (!prefix_ok(str1,RAP_WShareAdd_REQ)) {
01825 return False;
01826 }
01827 if (!check_share_info(uLevel,str2)) {
01828 return False;
01829 }
01830 if (uLevel != 2) {
01831 return False;
01832 }
01833
01834
01835 if (skip_string(data,mdrcnt,data) == NULL) {
01836 return False;
01837 }
01838 pull_ascii_fstring(sharename,data);
01839 snum = find_service(sharename);
01840 if (snum >= 0) {
01841 res = ERRfilexists;
01842 goto error_exit;
01843 }
01844
01845 if (mdrcnt < 28) {
01846 return False;
01847 }
01848
01849
01850 if (SVAL(data,14)!=STYPE_DISKTREE) {
01851 return False;
01852 }
01853
01854 offset = IVAL(data, 16);
01855 if (offset >= mdrcnt) {
01856 res = ERRinvalidparam;
01857 goto error_exit;
01858 }
01859
01860
01861 if (skip_string(data,mdrcnt,data+offset) == NULL) {
01862 return False;
01863 }
01864 pull_ascii_fstring(comment, offset? (data+offset) : "");
01865
01866 offset = IVAL(data, 26);
01867
01868 if (offset >= mdrcnt) {
01869 res = ERRinvalidparam;
01870 goto error_exit;
01871 }
01872
01873
01874 if (skip_string(data,mdrcnt,data+offset) == NULL) {
01875 return False;
01876 }
01877 pull_ascii_pstring(pathname, offset? (data+offset) : "");
01878
01879 string_replace(sharename, '"', ' ');
01880 string_replace(pathname, '"', ' ');
01881 string_replace(comment, '"', ' ');
01882
01883 cmdname = lp_add_share_cmd();
01884
01885 if (!cmdname || *cmdname == '\0') {
01886 return False;
01887 }
01888
01889 asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
01890 lp_add_share_cmd(), dyn_CONFIGFILE, sharename, pathname, comment);
01891
01892 if (command) {
01893 DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command ));
01894
01895 if ((res = smbrun(command, NULL)) != 0) {
01896 DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n", command, res ));
01897 SAFE_FREE(command);
01898 res = ERRnoaccess;
01899 goto error_exit;
01900 } else {
01901 SAFE_FREE(command);
01902 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
01903 }
01904 } else {
01905 return False;
01906 }
01907
01908 *rparam_len = 6;
01909 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
01910 if (!*rparam) {
01911 return False;
01912 }
01913 SSVAL(*rparam,0,NERR_Success);
01914 SSVAL(*rparam,2,0);
01915 SSVAL(*rparam,4,*rdata_len);
01916 *rdata_len = 0;
01917
01918 return True;
01919
01920 error_exit:
01921
01922 *rparam_len = 4;
01923 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
01924 if (!*rparam) {
01925 return False;
01926 }
01927 *rdata_len = 0;
01928 SSVAL(*rparam,0,res);
01929 SSVAL(*rparam,2,0);
01930 return True;
01931 }
01932
01933
01934
01935
01936
01937 static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
01938 char *param, int tpscnt,
01939 char *data, int tdscnt,
01940 int mdrcnt,int mprcnt,
01941 char **rdata,char **rparam,
01942 int *rdata_len,int *rparam_len)
01943 {
01944 int i;
01945 int errflags=0;
01946 int resume_context, cli_buf_size;
01947 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
01948 char *str2 = skip_string(param,tpscnt,str1);
01949 char *p = skip_string(param,tpscnt,str2);
01950
01951 struct pdb_search *search;
01952 struct samr_displayentry *entries;
01953
01954 int num_entries;
01955
01956 if (!str1 || !str2 || !p) {
01957 return False;
01958 }
01959
01960 if (strcmp(str1,"WrLeh") != 0) {
01961 return False;
01962 }
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972 if (strcmp("B21",str2) != 0) {
01973 return False;
01974 }
01975
01976
01977 become_root();
01978 search = pdb_search_groups();
01979 unbecome_root();
01980
01981 if (search == NULL) {
01982 DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
01983 return False;
01984 }
01985
01986 resume_context = get_safe_SVAL(param,tpscnt,p,0,-1);
01987 cli_buf_size= get_safe_SVAL(param,tpscnt,p,2,0);
01988 DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: "
01989 "%d\n", resume_context, cli_buf_size));
01990
01991 become_root();
01992 num_entries = pdb_search_entries(search, resume_context, 0xffffffff,
01993 &entries);
01994 unbecome_root();
01995
01996 *rdata_len = cli_buf_size;
01997 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
01998 if (!*rdata) {
01999 return False;
02000 }
02001
02002 p = *rdata;
02003
02004 for(i=0; i<num_entries; i++) {
02005 fstring name;
02006 fstrcpy(name, entries[i].account_name);
02007 if( ((PTR_DIFF(p,*rdata)+21) <= *rdata_len) ) {
02008
02009 memcpy(p, name, 21);
02010 DEBUG(10,("adding entry %d group %s\n", i, p));
02011 p += 21;
02012 p += 5;
02013
02014 } else {
02015
02016 DEBUG(3,("overflow on entry %d group %s\n", i, name));
02017 errflags=234;
02018 break;
02019 }
02020 }
02021
02022 pdb_search_destroy(search);
02023
02024 *rdata_len = PTR_DIFF(p,*rdata);
02025
02026 *rparam_len = 8;
02027 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02028 if (!*rparam) {
02029 return False;
02030 }
02031 SSVAL(*rparam, 0, errflags);
02032 SSVAL(*rparam, 2, 0);
02033 SSVAL(*rparam, 4, i);
02034 SSVAL(*rparam, 6, resume_context+num_entries);
02035
02036 return(True);
02037 }
02038
02039
02040
02041
02042
02043 static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
02044 char *param, int tpscnt,
02045 char *data, int tdscnt,
02046 int mdrcnt,int mprcnt,
02047 char **rdata,char **rparam,
02048 int *rdata_len,int *rparam_len)
02049 {
02050 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
02051 char *str2 = skip_string(param,tpscnt,str1);
02052 char *UserName = skip_string(param,tpscnt,str2);
02053 char *p = skip_string(param,tpscnt,UserName);
02054 int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
02055 const char *level_string;
02056 int count=0;
02057 struct samu *sampw = NULL;
02058 BOOL ret = False;
02059 DOM_SID *sids;
02060 gid_t *gids;
02061 size_t num_groups;
02062 size_t i;
02063 NTSTATUS result;
02064 DOM_SID user_sid;
02065 enum lsa_SidType type;
02066 TALLOC_CTX *mem_ctx;
02067
02068 if (!str1 || !str2 || !UserName || !p) {
02069 return False;
02070 }
02071
02072 *rparam_len = 8;
02073 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02074 if (!*rparam) {
02075 return False;
02076 }
02077
02078
02079
02080 if ( strcmp(str1,"zWrLeh") != 0 )
02081 return False;
02082
02083 switch( uLevel ) {
02084 case 0:
02085 level_string = "B21";
02086 break;
02087 default:
02088 return False;
02089 }
02090
02091 if (strcmp(level_string,str2) != 0)
02092 return False;
02093
02094 *rdata_len = mdrcnt + 1024;
02095 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
02096 if (!*rdata) {
02097 return False;
02098 }
02099 SSVAL(*rparam,0,NERR_Success);
02100 SSVAL(*rparam,2,0);
02101
02102 p = *rdata;
02103
02104 mem_ctx = talloc_new(NULL);
02105 if (mem_ctx == NULL) {
02106 DEBUG(0, ("talloc_new failed\n"));
02107 return False;
02108 }
02109
02110 if ( !(sampw = samu_new(mem_ctx)) ) {
02111 DEBUG(0, ("samu_new() failed!\n"));
02112 TALLOC_FREE(mem_ctx);
02113 return False;
02114 }
02115
02116
02117
02118
02119 become_root();
02120
02121 if (!lookup_name(mem_ctx, UserName, LOOKUP_NAME_ALL,
02122 NULL, NULL, &user_sid, &type)) {
02123 DEBUG(10, ("lookup_name(%s) failed\n", UserName));
02124 goto done;
02125 }
02126
02127 if (type != SID_NAME_USER) {
02128 DEBUG(10, ("%s is a %s, not a user\n", UserName,
02129 sid_type_lookup(type)));
02130 goto done;
02131 }
02132
02133 if ( !pdb_getsampwsid(sampw, &user_sid) ) {
02134 DEBUG(10, ("pdb_getsampwsid(%s) failed for user %s\n",
02135 sid_string_static(&user_sid), UserName));
02136 goto done;
02137 }
02138
02139 gids = NULL;
02140 sids = NULL;
02141 num_groups = 0;
02142
02143 result = pdb_enum_group_memberships(mem_ctx, sampw,
02144 &sids, &gids, &num_groups);
02145
02146 if (!NT_STATUS_IS_OK(result)) {
02147 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
02148 UserName));
02149 goto done;
02150 }
02151
02152 for (i=0; i<num_groups; i++) {
02153
02154 const char *grp_name;
02155
02156 if ( lookup_sid(mem_ctx, &sids[i], NULL, &grp_name, NULL) ) {
02157 pstrcpy(p, grp_name);
02158 p += 21;
02159 count++;
02160 }
02161 }
02162
02163 *rdata_len = PTR_DIFF(p,*rdata);
02164
02165 SSVAL(*rparam,4,count);
02166 SSVAL(*rparam,6,count);
02167
02168 ret = True;
02169
02170 done:
02171 unbecome_root();
02172
02173 TALLOC_FREE(mem_ctx);
02174
02175 return ret;
02176 }
02177
02178
02179
02180
02181
02182 static BOOL api_RNetUserEnum(connection_struct *conn, uint16 vuid,
02183 char *param, int tpscnt,
02184 char *data, int tdscnt,
02185 int mdrcnt,int mprcnt,
02186 char **rdata,char **rparam,
02187 int *rdata_len,int *rparam_len)
02188 {
02189 int count_sent=0;
02190 int num_users=0;
02191 int errflags=0;
02192 int i, resume_context, cli_buf_size;
02193 struct pdb_search *search;
02194 struct samr_displayentry *users;
02195
02196 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
02197 char *str2 = skip_string(param,tpscnt,str1);
02198 char *p = skip_string(param,tpscnt,str2);
02199
02200 if (!str1 || !str2 || !p) {
02201 return False;
02202 }
02203
02204 if (strcmp(str1,"WrLeh") != 0)
02205 return False;
02206
02207
02208
02209
02210
02211
02212
02213
02214 resume_context = get_safe_SVAL(param,tpscnt,p,0,-1);
02215 cli_buf_size= get_safe_SVAL(param,tpscnt,p,2,0);
02216 DEBUG(10,("api_RNetUserEnum:resume context: %d, client buffer size: %d\n",
02217 resume_context, cli_buf_size));
02218
02219 *rparam_len = 8;
02220 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02221 if (!*rparam) {
02222 return False;
02223 }
02224
02225
02226 if (strcmp("B21",str2) != 0)
02227 return False;
02228
02229 *rdata_len = cli_buf_size;
02230 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
02231 if (!*rdata) {
02232 return False;
02233 }
02234
02235 p = *rdata;
02236
02237 become_root();
02238 search = pdb_search_users(ACB_NORMAL);
02239 unbecome_root();
02240 if (search == NULL) {
02241 DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
02242 return False;
02243 }
02244
02245 become_root();
02246 num_users = pdb_search_entries(search, resume_context, 0xffffffff,
02247 &users);
02248 unbecome_root();
02249
02250 errflags=NERR_Success;
02251
02252 for (i=0; i<num_users; i++) {
02253 const char *name = users[i].account_name;
02254
02255 if(((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21)) {
02256 pstrcpy(p,name);
02257 DEBUG(10,("api_RNetUserEnum:adding entry %d username "
02258 "%s\n",count_sent,p));
02259 p += 21;
02260 count_sent++;
02261 } else {
02262
02263 DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
02264 "username %s\n",count_sent,name));
02265 errflags=234;
02266 break;
02267 }
02268 }
02269
02270 pdb_search_destroy(search);
02271
02272 *rdata_len = PTR_DIFF(p,*rdata);
02273
02274 SSVAL(*rparam,0,errflags);
02275 SSVAL(*rparam,2,0);
02276 SSVAL(*rparam,4,count_sent);
02277 SSVAL(*rparam,6,num_users);
02278
02279 return True;
02280 }
02281
02282
02283
02284
02285
02286 static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid,
02287 char *param, int tpscnt,
02288 char *data, int tdscnt,
02289 int mdrcnt,int mprcnt,
02290 char **rdata,char **rparam,
02291 int *rdata_len,int *rparam_len)
02292 {
02293 struct tm *t;
02294 time_t unixdate = time(NULL);
02295 char *p;
02296
02297 *rparam_len = 4;
02298 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02299 if (!*rparam) {
02300 return False;
02301 }
02302
02303 *rdata_len = 21;
02304 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
02305 if (!*rdata) {
02306 return False;
02307 }
02308
02309 SSVAL(*rparam,0,NERR_Success);
02310 SSVAL(*rparam,2,0);
02311
02312 p = *rdata;
02313
02314 srv_put_dos_date3(p,0,unixdate);
02315
02316
02317
02318
02319
02320 t = localtime(&unixdate);
02321 if (!t) {
02322 return False;
02323 }
02324
02325 SIVAL(p,4,0);
02326 SCVAL(p,8,t->tm_hour);
02327 SCVAL(p,9,t->tm_min);
02328 SCVAL(p,10,t->tm_sec);
02329 SCVAL(p,11,0);
02330 SSVALS(p,12,get_time_zone(unixdate)/60);
02331 SSVAL(p,14,10000);
02332 SCVAL(p,16,t->tm_mday);
02333 SCVAL(p,17,t->tm_mon + 1);
02334 SSVAL(p,18,1900+t->tm_year);
02335 SCVAL(p,20,t->tm_wday);
02336
02337 return True;
02338 }
02339
02340
02341
02342
02343
02344 static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid,
02345 char *param, int tpscnt,
02346 char *data, int tdscnt,
02347 int mdrcnt,int mprcnt,
02348 char **rdata,char **rparam,
02349 int *rdata_len,int *rparam_len)
02350 {
02351 char *np = get_safe_str_ptr(param,tpscnt,param,2);
02352 char *p = NULL;
02353 fstring user;
02354 fstring pass1,pass2;
02355
02356
02357 p = skip_string(param,tpscnt,np);
02358 p = skip_string(param,tpscnt,p);
02359
02360 if (!np || !p) {
02361 return False;
02362 }
02363
02364
02365 if (skip_string(param,tpscnt,p) == NULL) {
02366 return False;
02367 }
02368 pull_ascii_fstring(user,p);
02369
02370 p = skip_string(param,tpscnt,p);
02371 if (!p) {
02372 return False;
02373 }
02374
02375 memset(pass1,'\0',sizeof(pass1));
02376 memset(pass2,'\0',sizeof(pass2));
02377
02378
02379
02380
02381 if (!is_offset_safe(param,tpscnt,p,31)) {
02382 return False;
02383 }
02384 memcpy(pass1,p,16);
02385 memcpy(pass2,p+16,16);
02386
02387 *rparam_len = 4;
02388 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02389 if (!*rparam) {
02390 return False;
02391 }
02392
02393 *rdata_len = 0;
02394
02395 SSVAL(*rparam,0,NERR_badpass);
02396 SSVAL(*rparam,2,0);
02397
02398 DEBUG(3,("Set password for <%s>\n",user));
02399
02400
02401
02402
02403
02404
02405 {
02406 auth_serversupplied_info *server_info = NULL;
02407 DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
02408
02409 if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
02410
02411 become_root();
02412 if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2, False, NULL))) {
02413 SSVAL(*rparam,0,NERR_Success);
02414 }
02415 unbecome_root();
02416
02417 TALLOC_FREE(server_info);
02418 }
02419 data_blob_clear_free(&password);
02420 }
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432 if(SVAL(*rparam,0) != NERR_Success) {
02433 struct samu *hnd = NULL;
02434
02435 if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) {
02436 become_root();
02437 if (change_lanman_password(hnd,(uchar *)pass2)) {
02438 SSVAL(*rparam,0,NERR_Success);
02439 }
02440 unbecome_root();
02441 TALLOC_FREE(hnd);
02442 }
02443 }
02444
02445 memset((char *)pass1,'\0',sizeof(fstring));
02446 memset((char *)pass2,'\0',sizeof(fstring));
02447
02448 return(True);
02449 }
02450
02451
02452
02453
02454
02455 static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
02456 char *param, int tpscnt,
02457 char *data, int tdscnt,
02458 int mdrcnt,int mprcnt,
02459 char **rdata,char **rparam,
02460 int *rdata_len,int *rparam_len)
02461 {
02462 fstring user;
02463 char *p = get_safe_str_ptr(param,tpscnt,param,2);
02464 *rparam_len = 2;
02465 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02466 if (!*rparam) {
02467 return False;
02468 }
02469
02470 if (!p) {
02471 return False;
02472 }
02473 *rdata_len = 0;
02474
02475 SSVAL(*rparam,0,NERR_badpass);
02476
02477
02478
02479
02480
02481
02482 if (skip_string(param,tpscnt,p) == 0) {
02483 return False;
02484 }
02485 if(!strequal(p, "zsT")) {
02486 DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", p));
02487 return False;
02488 }
02489 p = skip_string(param, tpscnt, p);
02490 if (!p) {
02491 return False;
02492 }
02493
02494
02495 if (skip_string(param,tpscnt,p) == 0) {
02496 return False;
02497 }
02498 if(!strequal(p, "B516B16")) {
02499 DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
02500 return False;
02501 }
02502 p = skip_string(param,tpscnt,p);
02503 if (!p) {
02504 return False;
02505 }
02506
02507 if (skip_string(param,tpscnt,p) == 0) {
02508 return False;
02509 }
02510 p += pull_ascii_fstring(user,p);
02511
02512 DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
02513
02514
02515
02516
02517
02518
02519 (void)map_username(user);
02520
02521 if (NT_STATUS_IS_OK(pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL, NULL))) {
02522 SSVAL(*rparam,0,NERR_Success);
02523 }
02524
02525 return(True);
02526 }
02527
02528
02529
02530
02531
02532
02533 static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
02534 char *param, int tpscnt,
02535 char *data, int tdscnt,
02536 int mdrcnt,int mprcnt,
02537 char **rdata,char **rparam,
02538 int *rdata_len,int *rparam_len)
02539 {
02540 int function = get_safe_SVAL(param,tpscnt,param,0,0);
02541 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
02542 char *str2 = skip_string(param,tpscnt,str1);
02543 char *p = skip_string(param,tpscnt,str2);
02544 uint32 jobid;
02545 int snum;
02546 fstring sharename;
02547 int errcode;
02548 WERROR werr = WERR_OK;
02549
02550 if (!str1 || !str2 || !p) {
02551 return False;
02552 }
02553
02554
02555
02556
02557 if (!is_offset_safe(param,tpscnt,p,1)) {
02558 return False;
02559 }
02560 if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
02561 return False;
02562
02563
02564 if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
02565 return(False);
02566
02567 *rparam_len = 4;
02568 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02569 if (!*rparam) {
02570 return False;
02571 }
02572 *rdata_len = 0;
02573
02574 if (!print_job_exists(sharename, jobid)) {
02575 errcode = NERR_JobNotFound;
02576 goto out;
02577 }
02578
02579 snum = lp_servicenumber( sharename);
02580 if (snum == -1) {
02581 errcode = NERR_DestNotFound;
02582 goto out;
02583 }
02584
02585 errcode = NERR_notsupported;
02586
02587 switch (function) {
02588 case 81:
02589 if (print_job_delete(¤t_user, snum, jobid, &werr))
02590 errcode = NERR_Success;
02591 break;
02592 case 82:
02593 if (print_job_pause(¤t_user, snum, jobid, &werr))
02594 errcode = NERR_Success;
02595 break;
02596 case 83:
02597 if (print_job_resume(¤t_user, snum, jobid, &werr))
02598 errcode = NERR_Success;
02599 break;
02600 }
02601
02602 if (!W_ERROR_IS_OK(werr))
02603 errcode = W_ERROR_V(werr);
02604
02605 out:
02606 SSVAL(*rparam,0,errcode);
02607 SSVAL(*rparam,2,0);
02608
02609 return(True);
02610 }
02611
02612
02613
02614
02615
02616 static BOOL api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
02617 char *param, int tpscnt,
02618 char *data, int tdscnt,
02619 int mdrcnt,int mprcnt,
02620 char **rdata,char **rparam,
02621 int *rdata_len,int *rparam_len)
02622 {
02623 int function = get_safe_SVAL(param,tpscnt,param,0,0);
02624 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
02625 char *str2 = skip_string(param,tpscnt,str1);
02626 char *QueueName = skip_string(param,tpscnt,str2);
02627 int errcode = NERR_notsupported;
02628 int snum;
02629 WERROR werr = WERR_OK;
02630
02631 if (!str1 || !str2 || !QueueName) {
02632 return False;
02633 }
02634
02635
02636 if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
02637 return(False);
02638
02639 *rparam_len = 4;
02640 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02641 if (!*rparam) {
02642 return False;
02643 }
02644 *rdata_len = 0;
02645
02646 if (skip_string(param,tpscnt,QueueName) == NULL) {
02647 return False;
02648 }
02649 snum = print_queue_snum(QueueName);
02650
02651 if (snum == -1) {
02652 errcode = NERR_JobNotFound;
02653 goto out;
02654 }
02655
02656 switch (function) {
02657 case 74:
02658 if (print_queue_pause(¤t_user, snum, &werr)) errcode = NERR_Success;
02659 break;
02660 case 75:
02661 if (print_queue_resume(¤t_user, snum, &werr)) errcode = NERR_Success;
02662 break;
02663 case 103:
02664 if (print_queue_purge(¤t_user, snum, &werr)) errcode = NERR_Success;
02665 break;
02666 }
02667
02668 if (!W_ERROR_IS_OK(werr)) errcode = W_ERROR_V(werr);
02669
02670 out:
02671 SSVAL(*rparam,0,errcode);
02672 SSVAL(*rparam,2,0);
02673
02674 return(True);
02675 }
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685 static int check_printjob_info(struct pack_desc* desc,
02686 int uLevel, char* id)
02687 {
02688 desc->subformat = NULL;
02689 switch( uLevel ) {
02690 case 0: desc->format = "W"; break;
02691 case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
02692 case 2: desc->format = "WWzWWDDzz"; break;
02693 case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
02694 case 4: desc->format = "WWzWWDDzzzzzDDDDDDD"; break;
02695 default:
02696 DEBUG(0,("check_printjob_info: invalid level %d\n",
02697 uLevel ));
02698 return False;
02699 }
02700 if (id == NULL || strcmp(desc->format,id) != 0) {
02701 DEBUG(0,("check_printjob_info: invalid format %s\n",
02702 id ? id : "<NULL>" ));
02703 return False;
02704 }
02705 return True;
02706 }
02707
02708 static BOOL api_PrintJobInfo(connection_struct *conn, uint16 vuid,
02709 char *param, int tpscnt,
02710 char *data, int tdscnt,
02711 int mdrcnt,int mprcnt,
02712 char **rdata,char **rparam,
02713 int *rdata_len,int *rparam_len)
02714 {
02715 struct pack_desc desc;
02716 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
02717 char *str2 = skip_string(param,tpscnt,str1);
02718 char *p = skip_string(param,tpscnt,str2);
02719 uint32 jobid;
02720 fstring sharename;
02721 int uLevel = get_safe_SVAL(param,tpscnt,p,2,-1);
02722 int function = get_safe_SVAL(param,tpscnt,p,4,-1);
02723 int place, errcode;
02724
02725 if (!str1 || !str2 || !p) {
02726 return False;
02727 }
02728
02729
02730
02731
02732 if (!is_offset_safe(param,tpscnt,p,1)) {
02733 return False;
02734 }
02735 if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
02736 return False;
02737 *rparam_len = 4;
02738 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02739 if (!*rparam) {
02740 return False;
02741 }
02742
02743 if (!share_defined(sharename)) {
02744 DEBUG(0,("api_PrintJobInfo: sharen [%s] not defined\n",
02745 sharename));
02746 return False;
02747 }
02748
02749 *rdata_len = 0;
02750
02751
02752 if ((strcmp(str1,"WWsTP")) ||
02753 (!check_printjob_info(&desc,uLevel,str2)))
02754 return(False);
02755
02756 if (!print_job_exists(sharename, jobid)) {
02757 errcode=NERR_JobNotFound;
02758 goto out;
02759 }
02760
02761 errcode = NERR_notsupported;
02762
02763 switch (function) {
02764 case 0x6:
02765
02766
02767 place = SVAL(data,0);
02768 if (print_job_set_place(sharename, jobid, place)) {
02769 errcode=NERR_Success;
02770 }
02771 break;
02772
02773 case 0xb:
02774
02775 if (print_job_set_name(sharename, jobid, data)) {
02776 errcode=NERR_Success;
02777 }
02778 break;
02779
02780 default:
02781 return False;
02782 }
02783
02784 out:
02785 SSVALS(*rparam,0,errcode);
02786 SSVAL(*rparam,2,0);
02787
02788 return(True);
02789 }
02790
02791
02792
02793
02794
02795
02796 static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
02797 char *param, int tpscnt,
02798 char *data, int tdscnt,
02799 int mdrcnt,int mprcnt,
02800 char **rdata,char **rparam,
02801 int *rdata_len,int *rparam_len)
02802 {
02803 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
02804 char *str2 = skip_string(param,tpscnt,str1);
02805 char *p = skip_string(param,tpscnt,str2);
02806 int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
02807 char *p2;
02808 int struct_len;
02809
02810 if (!str1 || !str2 || !p) {
02811 return False;
02812 }
02813
02814 DEBUG(4,("NetServerGetInfo level %d\n",uLevel));
02815
02816
02817 if (!prefix_ok(str1,"WrLh")) {
02818 return False;
02819 }
02820
02821 switch( uLevel ) {
02822 case 0:
02823 if (strcmp(str2,"B16") != 0) {
02824 return False;
02825 }
02826 struct_len = 16;
02827 break;
02828 case 1:
02829 if (strcmp(str2,"B16BBDz") != 0) {
02830 return False;
02831 }
02832 struct_len = 26;
02833 break;
02834 case 2:
02835 if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")!= 0) {
02836 return False;
02837 }
02838 struct_len = 134;
02839 break;
02840 case 3:
02841 if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz") != 0) {
02842 return False;
02843 }
02844 struct_len = 144;
02845 break;
02846 case 20:
02847 if (strcmp(str2,"DN") != 0) {
02848 return False;
02849 }
02850 struct_len = 6;
02851 break;
02852 case 50:
02853 if (strcmp(str2,"B16BBDzWWzzz") != 0) {
02854 return False;
02855 }
02856 struct_len = 42;
02857 break;
02858 default:
02859 return False;
02860 }
02861
02862 *rdata_len = mdrcnt;
02863 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
02864 if (!*rdata) {
02865 return False;
02866 }
02867
02868 p = *rdata;
02869 p2 = p + struct_len;
02870 if (uLevel != 20) {
02871 srvstr_push(NULL, p,global_myname(),16,
02872 STR_ASCII|STR_UPPER|STR_TERMINATE);
02873 }
02874 p += 16;
02875 if (uLevel > 0) {
02876 struct srv_info_struct *servers=NULL;
02877 int i,count;
02878 pstring comment;
02879 uint32 servertype= lp_default_server_announce();
02880
02881 push_ascii(comment,lp_serverstring(), MAX_SERVER_STRING_LENGTH,STR_TERMINATE);
02882
02883 if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
02884 for (i=0;i<count;i++) {
02885 if (strequal(servers[i].name,global_myname())) {
02886 servertype = servers[i].type;
02887 push_ascii(comment,servers[i].comment,sizeof(pstring),STR_TERMINATE);
02888 }
02889 }
02890 }
02891
02892 SAFE_FREE(servers);
02893
02894 SCVAL(p,0,lp_major_announce_version());
02895 SCVAL(p,1,lp_minor_announce_version());
02896 SIVAL(p,2,servertype);
02897
02898 if (mdrcnt == struct_len) {
02899 SIVAL(p,6,0);
02900 } else {
02901 SIVAL(p,6,PTR_DIFF(p2,*rdata));
02902 standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
02903 conn->connectpath, conn->gid,
02904 get_current_username(),
02905 current_user_info.domain,
02906 comment, sizeof(comment));
02907 StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
02908 p2 = skip_string(*rdata,*rdata_len,p2);
02909 if (!p2) {
02910 return False;
02911 }
02912 }
02913 }
02914
02915 if (uLevel > 1) {
02916 return False;
02917 }
02918
02919 *rdata_len = PTR_DIFF(p2,*rdata);
02920
02921 *rparam_len = 6;
02922 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02923 if (!*rparam) {
02924 return False;
02925 }
02926 SSVAL(*rparam,0,NERR_Success);
02927 SSVAL(*rparam,2,0);
02928 SSVAL(*rparam,4,*rdata_len);
02929
02930 return True;
02931 }
02932
02933
02934
02935
02936
02937 static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid,
02938 char *param, int tpscnt,
02939 char *data, int tdscnt,
02940 int mdrcnt,int mprcnt,
02941 char **rdata,char **rparam,
02942 int *rdata_len,int *rparam_len)
02943 {
02944 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
02945 char *str2 = skip_string(param,tpscnt,str1);
02946 char *p = skip_string(param,tpscnt,str2);
02947 char *p2;
02948 int level = get_safe_SVAL(param,tpscnt,p,0,-1);
02949
02950 if (!str1 || !str2 || !p) {
02951 return False;
02952 }
02953
02954 DEBUG(4,("NetWkstaGetInfo level %d\n",level));
02955
02956 *rparam_len = 6;
02957 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
02958 if (!*rparam) {
02959 return False;
02960 }
02961
02962
02963 if (!(level==10 && strcsequal(str1,"WrLh") && strcsequal(str2,"zzzBBzz"))) {
02964 return False;
02965 }
02966
02967 *rdata_len = mdrcnt + 1024;
02968 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
02969 if (!*rdata) {
02970 return False;
02971 }
02972
02973 SSVAL(*rparam,0,NERR_Success);
02974 SSVAL(*rparam,2,0);
02975
02976 p = *rdata;
02977 p2 = get_safe_ptr(*rdata,*rdata_len,p,22);
02978 if (!p2) {
02979 return False;
02980 }
02981
02982 SIVAL(p,0,PTR_DIFF(p2,*rdata));
02983 pstrcpy(p2,get_local_machine_name());
02984 strupper_m(p2);
02985 p2 = skip_string(*rdata,*rdata_len,p2);
02986 if (!p2) {
02987 return False;
02988 }
02989 p += 4;
02990
02991 SIVAL(p,0,PTR_DIFF(p2,*rdata));
02992 pstrcpy(p2,current_user_info.smb_name);
02993 p2 = skip_string(*rdata,*rdata_len,p2);
02994 if (!p2) {
02995 return False;
02996 }
02997 p += 4;
02998
02999 SIVAL(p,0,PTR_DIFF(p2,*rdata));
03000 pstrcpy(p2,lp_workgroup());
03001 strupper_m(p2);
03002 p2 = skip_string(*rdata,*rdata_len,p2);
03003 if (!p2) {
03004 return False;
03005 }
03006 p += 4;
03007
03008 SCVAL(p,0,lp_major_announce_version());
03009 SCVAL(p,1,lp_minor_announce_version());
03010 p += 2;
03011
03012 SIVAL(p,0,PTR_DIFF(p2,*rdata));
03013 pstrcpy(p2,lp_workgroup());
03014 p2 = skip_string(*rdata,*rdata_len,p2);
03015 if (!p2) {
03016 return False;
03017 }
03018 p += 4;
03019
03020 SIVAL(p,0,PTR_DIFF(p2,*rdata));
03021 pstrcpy(p2,"");
03022 p2 = skip_string(*rdata,*rdata_len,p2);
03023 if (!p2) {
03024 return False;
03025 }
03026 p += 4;
03027
03028 *rdata_len = PTR_DIFF(p2,*rdata);
03029
03030 SSVAL(*rparam,4,*rdata_len);
03031
03032 return True;
03033 }
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172 #define usri11_name 0
03173 #define usri11_pad 21
03174 #define usri11_comment 22
03175 #define usri11_usr_comment 26
03176 #define usri11_full_name 30
03177 #define usri11_priv 34
03178 #define usri11_auth_flags 36
03179 #define usri11_password_age 40
03180 #define usri11_homedir 44
03181 #define usri11_parms 48
03182 #define usri11_last_logon 52
03183 #define usri11_last_logoff 56
03184 #define usri11_bad_pw_count 60
03185 #define usri11_num_logons 62
03186 #define usri11_logon_server 64
03187 #define usri11_country_code 68
03188 #define usri11_workstations 70
03189 #define usri11_max_storage 74
03190 #define usri11_units_per_week 78
03191 #define usri11_logon_hours 80
03192 #define usri11_code_page 84
03193 #define usri11_end 86
03194
03195 #define USER_PRIV_GUEST 0
03196 #define USER_PRIV_USER 1
03197 #define USER_PRIV_ADMIN 2
03198
03199 #define AF_OP_PRINT 0
03200 #define AF_OP_COMM 1
03201 #define AF_OP_SERVER 2
03202 #define AF_OP_ACCOUNTS 3
03203
03204
03205 static BOOL api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
03206 char *param, int tpscnt,
03207 char *data, int tdscnt,
03208 int mdrcnt,int mprcnt,
03209 char **rdata,char **rparam,
03210 int *rdata_len,int *rparam_len)
03211 {
03212 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
03213 char *str2 = skip_string(param,tpscnt,str1);
03214 char *UserName = skip_string(param,tpscnt,str2);
03215 char *p = skip_string(param,tpscnt,UserName);
03216 int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
03217 char *p2;
03218 const char *level_string;
03219
03220
03221
03222
03223 user_struct *vuser = get_valid_user_struct(vuid);
03224 if(vuser != NULL) {
03225 DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid,
03226 vuser->user.unix_name));
03227 }
03228
03229 if (!str1 || !str2 || !UserName || !p) {
03230 return False;
03231 }
03232
03233 *rparam_len = 6;
03234 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
03235 if (!*rparam) {
03236 return False;
03237 }
03238
03239 DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel));
03240
03241
03242 if (strcmp(str1,"zWrLh") != 0) {
03243 return False;
03244 }
03245 switch( uLevel ) {
03246 case 0: level_string = "B21"; break;
03247 case 1: level_string = "B21BB16DWzzWz"; break;
03248 case 2: level_string = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
03249 case 10: level_string = "B21Bzzz"; break;
03250 case 11: level_string = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
03251 default: return False;
03252 }
03253
03254 if (strcmp(level_string,str2) != 0) {
03255 return False;
03256 }
03257
03258 *rdata_len = mdrcnt + 1024;
03259 *rdata = SMB_REALLOC_LIMIT(*rdata,*rdata_len);
03260 if (!*rdata) {
03261 return False;
03262 }
03263
03264 SSVAL(*rparam,0,NERR_Success);
03265 SSVAL(*rparam,2,0);
03266
03267 p = *rdata;
03268 p2 = get_safe_ptr(*rdata,*rdata_len,p,usri11_end);
03269 if (!p2) {
03270 return False;
03271 }
03272
03273 memset(p,0,21);
03274 fstrcpy(p+usri11_name,UserName);
03275
03276 if (uLevel > 0) {
03277 SCVAL(p,usri11_pad,0);
03278 *p2 = 0;
03279 }
03280
03281 if (uLevel >= 10) {
03282 SIVAL(p,usri11_comment,PTR_DIFF(p2,p));
03283 pstrcpy(p2,"Comment");
03284 p2 = skip_string(*rdata,*rdata_len,p2);
03285 if (!p2) {
03286 return False;
03287 }
03288
03289 SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p));
03290 pstrcpy(p2,"UserComment");
03291 p2 = skip_string(*rdata,*rdata_len,p2);
03292 if (!p2) {
03293 return False;
03294 }
03295
03296
03297 SIVAL(p,usri11_full_name,PTR_DIFF(p2,p));
03298 pstrcpy(p2,((vuser != NULL) ? vuser->user.full_name : UserName));
03299 p2 = skip_string(*rdata,*rdata_len,p2);
03300 if (!p2) {
03301 return False;
03302 }
03303 }
03304
03305 if (uLevel == 11) {
03306
03307 SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
03308 SIVAL(p,usri11_auth_flags,AF_OP_PRINT);
03309 SIVALS(p,usri11_password_age,-1);
03310 SIVAL(p,usri11_homedir,PTR_DIFF(p2,p));
03311 pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
03312 p2 = skip_string(*rdata,*rdata_len,p2);
03313 if (!p2) {
03314 return False;
03315 }
03316 SIVAL(p,usri11_parms,PTR_DIFF(p2,p));
03317 pstrcpy(p2,"");
03318 p2 = skip_string(*rdata,*rdata_len,p2);
03319 if (!p2) {
03320 return False;
03321 }
03322 SIVAL(p,usri11_last_logon,0);
03323 SIVAL(p,usri11_last_logoff,0);
03324 SSVALS(p,usri11_bad_pw_count,-1);
03325 SSVALS(p,usri11_num_logons,-1);
03326 SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p));
03327 pstrcpy(p2,"\\\\*");
03328 p2 = skip_string(*rdata,*rdata_len,p2);
03329 if (!p2) {
03330 return False;
03331 }
03332 SSVAL(p,usri11_country_code,0);
03333
03334 SIVAL(p,usri11_workstations,PTR_DIFF(p2,p));
03335 pstrcpy(p2,"");
03336 p2 = skip_string(*rdata,*rdata_len,p2);
03337 if (!p2) {
03338 return False;
03339 }
03340
03341 SIVALS(p,usri11_max_storage,-1);
03342 SSVAL(p,usri11_units_per_week,168);
03343 SIVAL(p,usri11_logon_hours,PTR_DIFF(p2,p));
03344
03345
03346 memset(p2,0xff,21);
03347 SCVAL(p2,21,0);
03348 p2 = skip_string(*rdata,*rdata_len,p2);
03349 if (!p2) {
03350 return False;
03351 }
03352
03353 SSVAL(p,usri11_code_page,0);
03354 }
03355
03356 if (uLevel == 1 || uLevel == 2) {
03357 memset(p+22,' ',16);
03358 SIVALS(p,38,-1);
03359 SSVAL(p,42,
03360 conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
03361 SIVAL(p,44,PTR_DIFF(p2,*rdata));
03362 pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
03363 p2 = skip_string(*rdata,*rdata_len,p2);
03364 if (!p2) {
03365 return False;
03366 }
03367 SIVAL(p,48,PTR_DIFF(p2,*rdata));
03368 *p2++ = 0;
03369 SSVAL(p,52,0);
03370 SIVAL(p,54,PTR_DIFF(p2,*rdata));
03371 pstrcpy(p2,vuser && vuser->logon_script ? vuser->logon_script : "");
03372 p2 = skip_string(*rdata,*rdata_len,p2);
03373 if (!p2) {
03374 return False;
03375 }
03376 if (uLevel == 2) {
03377 SIVAL(p,60,0);
03378 SIVAL(p,64,PTR_DIFF(p2,*rdata));
03379 pstrcpy(p2,((vuser != NULL) ? vuser->user.full_name : UserName));
03380 p2 = skip_string(*rdata,*rdata_len,p2);
03381 if (!p2) {
03382 return False;
03383 }
03384 SIVAL(p,68,0);
03385 SIVAL(p,72,PTR_DIFF(p2,*rdata));
03386 pstrcpy(p2,"");
03387 p2 = skip_string(*rdata,*rdata_len,p2);
03388 if (!p2) {
03389 return False;
03390 }
03391 SIVAL(p,76,0);
03392 SIVAL(p,80,0);
03393 SIVAL(p,84,0);
03394 SIVALS(p,88,-1);
03395 SIVALS(p,92,-1);
03396 SSVAL(p,96,168);
03397 SIVAL(p,98,PTR_DIFF(p2,*rdata));
03398 memset(p2,-1,21);
03399 p2 += 21;
03400 SSVALS(p,102,-1);
03401 SSVALS(p,104,-1);
03402 SIVAL(p,106,PTR_DIFF(p2,*rdata));
03403 {
03404 pstring tmp;
03405 pstrcpy(tmp, "\\\\%L");
03406 standard_sub_basic("", "", tmp, sizeof(tmp));
03407 pstrcpy(p2, tmp);
03408 }
03409 p2 = skip_string(*rdata,*rdata_len,p2);
03410 if (!p2) {
03411 return False;
03412 }
03413 SSVAL(p,110,49);
03414 SSVAL(p,112,860);
03415 }
03416 }
03417
03418 *rdata_len = PTR_DIFF(p2,*rdata);
03419
03420 SSVAL(*rparam,4,*rdata_len);
03421
03422 return(True);
03423 }
03424
03425 static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid,
03426 char *param, int tpscnt,
03427 char *data, int tdscnt,
03428 int mdrcnt,int mprcnt,
03429 char **rdata,char **rparam,
03430 int *rdata_len,int *rparam_len)
03431 {
03432 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
03433 char *str2 = skip_string(param,tpscnt,str1);
03434 char *p = skip_string(param,tpscnt,str2);
03435 int uLevel;
03436 struct pack_desc desc;
03437 char* name;
03438
03439
03440 user_struct *vuser = get_valid_user_struct(vuid);
03441
03442 if (!str1 || !str2 || !p) {
03443 return False;
03444 }
03445
03446 if(vuser != NULL) {
03447 DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid,
03448 vuser->user.unix_name));
03449 }
03450
03451 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
03452 name = get_safe_str_ptr(param,tpscnt,p,2);
03453 if (!name) {
03454 return False;
03455 }
03456
03457 memset((char *)&desc,'\0',sizeof(desc));
03458
03459 DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
03460
03461
03462 if (strcmp(str1,"OOWb54WrLh") != 0) {
03463 return False;
03464 }
03465 if (uLevel != 1 || strcmp(str2,"WB21BWDWWDDDDDDDzzzD") != 0) {
03466 return False;
03467 }
03468 if (mdrcnt > 0) {
03469 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
03470 if (!*rdata) {
03471 return False;
03472 }
03473 }
03474
03475 desc.base = *rdata;
03476 desc.buflen = mdrcnt;
03477 desc.subformat = NULL;
03478 desc.format = str2;
03479
03480 if (init_package(&desc,1,0)) {
03481 PACKI(&desc,"W",0);
03482 PACKS(&desc,"B21",name);
03483 PACKS(&desc,"B","");
03484 PACKI(&desc,"W", conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
03485 PACKI(&desc,"D",0);
03486 PACKI(&desc,"W",0);
03487 PACKI(&desc,"W",0);
03488 PACKI(&desc,"D",0);
03489 PACKI(&desc,"D",-1);
03490 PACKI(&desc,"D",-1);
03491 PACKI(&desc,"D",-1);
03492 PACKI(&desc,"D",0);
03493 PACKI(&desc,"D",0);
03494 PACKI(&desc,"D",-1);
03495
03496 {
03497 fstring mypath;
03498 fstrcpy(mypath,"\\\\");
03499 fstrcat(mypath,get_local_machine_name());
03500 strupper_m(mypath);
03501 PACKS(&desc,"z",mypath);
03502 }
03503
03504 PACKS(&desc,"z",lp_workgroup());
03505 PACKS(&desc,"z", vuser && vuser->logon_script ? vuser->logon_script :"");
03506 PACKI(&desc,"D",0x00000000);
03507 }
03508
03509 *rdata_len = desc.usedlen;
03510 *rparam_len = 6;
03511 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
03512 if (!*rparam) {
03513 return False;
03514 }
03515 SSVALS(*rparam,0,desc.errcode);
03516 SSVAL(*rparam,2,0);
03517 SSVAL(*rparam,4,desc.neededlen);
03518
03519 DEBUG(4,("WWkstaUserLogon: errorcode %d\n",desc.errcode));
03520
03521 return True;
03522 }
03523
03524
03525
03526
03527
03528 static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid,
03529 char *param, int tpscnt,
03530 char *data, int tdscnt,
03531 int mdrcnt,int mprcnt,
03532 char **rdata,char **rparam,
03533 int *rdata_len,int *rparam_len)
03534 {
03535 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
03536 char *str2 = skip_string(param,tpscnt,str1);
03537 char *user = skip_string(param,tpscnt,str2);
03538 char *resource = skip_string(param,tpscnt,user);
03539
03540 if (!str1 || !str2 || !user || !resource) {
03541 return False;
03542 }
03543
03544 if (skip_string(param,tpscnt,resource) == NULL) {
03545 return False;
03546 }
03547 DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
03548
03549
03550 if (strcmp(str1,"zzh") != 0) {
03551 return False;
03552 }
03553 if (strcmp(str2,"") != 0) {
03554 return False;
03555 }
03556
03557 *rparam_len = 6;
03558 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
03559 if (!*rparam) {
03560 return False;
03561 }
03562 SSVALS(*rparam,0,0);
03563 SSVAL(*rparam,2,0);
03564 SSVAL(*rparam,4,0x7f);
03565
03566 return True;
03567 }
03568
03569
03570
03571
03572
03573 static BOOL api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
03574 char *param, int tpscnt,
03575 char *data, int tdscnt,
03576 int mdrcnt,int mprcnt,
03577 char **rdata,char **rparam,
03578 int *rdata_len,int *rparam_len)
03579 {
03580 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
03581 char *str2 = skip_string(param,tpscnt,str1);
03582 char *p = skip_string(param,tpscnt,str2);
03583 int uLevel;
03584 int count;
03585 int i;
03586 int snum;
03587 fstring sharename;
03588 uint32 jobid;
03589 struct pack_desc desc;
03590 print_queue_struct *queue=NULL;
03591 print_status_struct status;
03592 char *tmpdata=NULL;
03593
03594 if (!str1 || !str2 || !p) {
03595 return False;
03596 }
03597
03598 uLevel = get_safe_SVAL(param,tpscnt,p,2,-1);
03599
03600 memset((char *)&desc,'\0',sizeof(desc));
03601 memset((char *)&status,'\0',sizeof(status));
03602
03603 DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,SVAL(p,0)));
03604
03605
03606 if (strcmp(str1,"WWrLh") != 0) {
03607 return False;
03608 }
03609 if (!check_printjob_info(&desc,uLevel,str2)) {
03610 return False;
03611 }
03612
03613 if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid)) {
03614 return False;
03615 }
03616
03617 snum = lp_servicenumber( sharename);
03618 if (snum < 0 || !VALID_SNUM(snum)) {
03619 return(False);
03620 }
03621
03622 count = print_queue_status(snum,&queue,&status);
03623 for (i = 0; i < count; i++) {
03624 if (queue[i].job == jobid) {
03625 break;
03626 }
03627 }
03628
03629 if (mdrcnt > 0) {
03630 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
03631 if (!*rdata) {
03632 return False;
03633 }
03634 desc.base = *rdata;
03635 desc.buflen = mdrcnt;
03636 } else {
03637
03638
03639
03640
03641 desc.buflen = getlen(desc.format);
03642 desc.base = tmpdata = (char *)SMB_MALLOC( desc.buflen );
03643 }
03644
03645 if (init_package(&desc,1,0)) {
03646 if (i < count) {
03647 fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
03648 *rdata_len = desc.usedlen;
03649 } else {
03650 desc.errcode = NERR_JobNotFound;
03651 *rdata_len = 0;
03652 }
03653 }
03654
03655 *rparam_len = 6;
03656 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
03657 if (!*rparam) {
03658 return False;
03659 }
03660 SSVALS(*rparam,0,desc.errcode);
03661 SSVAL(*rparam,2,0);
03662 SSVAL(*rparam,4,desc.neededlen);
03663
03664 SAFE_FREE(queue);
03665 SAFE_FREE(tmpdata);
03666
03667 DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
03668
03669 return True;
03670 }
03671
03672 static BOOL api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
03673 char *param, int tpscnt,
03674 char *data, int tdscnt,
03675 int mdrcnt,int mprcnt,
03676 char **rdata,char **rparam,
03677 int *rdata_len,int *rparam_len)
03678 {
03679 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
03680 char *str2 = skip_string(param,tpscnt,str1);
03681 char *p = skip_string(param,tpscnt,str2);
03682 char *name = p;
03683 int uLevel;
03684 int count;
03685 int i, succnt=0;
03686 int snum;
03687 struct pack_desc desc;
03688 print_queue_struct *queue=NULL;
03689 print_status_struct status;
03690
03691 if (!str1 || !str2 || !p) {
03692 return False;
03693 }
03694
03695 memset((char *)&desc,'\0',sizeof(desc));
03696 memset((char *)&status,'\0',sizeof(status));
03697
03698 p = skip_string(param,tpscnt,p);
03699 if (!p) {
03700 return False;
03701 }
03702 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
03703
03704 DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
03705
03706
03707 if (strcmp(str1,"zWrLeh") != 0) {
03708 return False;
03709 }
03710
03711 if (uLevel > 2) {
03712 return False;
03713 }
03714
03715 if (!check_printjob_info(&desc,uLevel,str2)) {
03716 return False;
03717 }
03718
03719 snum = find_service(name);
03720 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
03721 return False;
03722 }
03723
03724 count = print_queue_status(snum,&queue,&status);
03725 if (mdrcnt > 0) {
03726 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
03727 if (!*rdata) {
03728 return False;
03729 }
03730 }
03731 desc.base = *rdata;
03732 desc.buflen = mdrcnt;
03733
03734 if (init_package(&desc,count,0)) {
03735 succnt = 0;
03736 for (i = 0; i < count; i++) {
03737 fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
03738 if (desc.errcode == NERR_Success) {
03739 succnt = i+1;
03740 }
03741 }
03742 }
03743
03744 *rdata_len = desc.usedlen;
03745
03746 *rparam_len = 8;
03747 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
03748 if (!*rparam) {
03749 return False;
03750 }
03751 SSVALS(*rparam,0,desc.errcode);
03752 SSVAL(*rparam,2,0);
03753 SSVAL(*rparam,4,succnt);
03754 SSVAL(*rparam,6,count);
03755
03756 SAFE_FREE(queue);
03757
03758 DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
03759
03760 return True;
03761 }
03762
03763 static int check_printdest_info(struct pack_desc* desc,
03764 int uLevel, char* id)
03765 {
03766 desc->subformat = NULL;
03767 switch( uLevel ) {
03768 case 0:
03769 desc->format = "B9";
03770 break;
03771 case 1:
03772 desc->format = "B9B21WWzW";
03773 break;
03774 case 2:
03775 desc->format = "z";
03776 break;
03777 case 3:
03778 desc->format = "zzzWWzzzWW";
03779 break;
03780 default:
03781 DEBUG(0,("check_printdest_info: invalid level %d\n",
03782 uLevel));
03783 return False;
03784 }
03785 if (id == NULL || strcmp(desc->format,id) != 0) {
03786 DEBUG(0,("check_printdest_info: invalid string %s\n",
03787 id ? id : "<NULL>" ));
03788 return False;
03789 }
03790 return True;
03791 }
03792
03793 static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
03794 struct pack_desc* desc)
03795 {
03796 char buf[100];
03797
03798 strncpy(buf,SERVICE(snum),sizeof(buf)-1);
03799 buf[sizeof(buf)-1] = 0;
03800 strupper_m(buf);
03801
03802 if (uLevel <= 1) {
03803 PACKS(desc,"B9",buf);
03804 if (uLevel == 1) {
03805 PACKS(desc,"B21","");
03806 PACKI(desc,"W",0);
03807 PACKI(desc,"W",0);
03808 PACKS(desc,"z","");
03809 PACKI(desc,"W",0);
03810 }
03811 }
03812
03813 if (uLevel == 2 || uLevel == 3) {
03814 PACKS(desc,"z",buf);
03815 if (uLevel == 3) {
03816 PACKS(desc,"z","");
03817 PACKS(desc,"z","");
03818 PACKI(desc,"W",0);
03819 PACKI(desc,"W",0);
03820 PACKS(desc,"z","");
03821 PACKS(desc,"z","");
03822 PACKS(desc,"z","NULL");
03823 PACKI(desc,"W",0);
03824 PACKI(desc,"W",0);
03825 }
03826 }
03827 }
03828
03829 static BOOL api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
03830 char *param, int tpscnt,
03831 char *data, int tdscnt,
03832 int mdrcnt,int mprcnt,
03833 char **rdata,char **rparam,
03834 int *rdata_len,int *rparam_len)
03835 {
03836 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
03837 char *str2 = skip_string(param,tpscnt,str1);
03838 char *p = skip_string(param,tpscnt,str2);
03839 char* PrinterName = p;
03840 int uLevel;
03841 struct pack_desc desc;
03842 int snum;
03843 char *tmpdata=NULL;
03844
03845 if (!str1 || !str2 || !p) {
03846 return False;
03847 }
03848
03849 memset((char *)&desc,'\0',sizeof(desc));
03850
03851 p = skip_string(param,tpscnt,p);
03852 if (!p) {
03853 return False;
03854 }
03855 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
03856
03857 DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
03858
03859
03860 if (strcmp(str1,"zWrLh") != 0) {
03861 return False;
03862 }
03863 if (!check_printdest_info(&desc,uLevel,str2)) {
03864 return False;
03865 }
03866
03867 snum = find_service(PrinterName);
03868 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
03869 *rdata_len = 0;
03870 desc.errcode = NERR_DestNotFound;
03871 desc.neededlen = 0;
03872 } else {
03873 if (mdrcnt > 0) {
03874 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
03875 if (!*rdata) {
03876 return False;
03877 }
03878 desc.base = *rdata;
03879 desc.buflen = mdrcnt;
03880 } else {
03881
03882
03883
03884
03885 desc.buflen = getlen(desc.format);
03886 desc.base = tmpdata = (char *)SMB_MALLOC( desc.buflen );
03887 }
03888 if (init_package(&desc,1,0)) {
03889 fill_printdest_info(conn,snum,uLevel,&desc);
03890 }
03891 *rdata_len = desc.usedlen;
03892 }
03893
03894 *rparam_len = 6;
03895 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
03896 if (!*rparam) {
03897 return False;
03898 }
03899 SSVALS(*rparam,0,desc.errcode);
03900 SSVAL(*rparam,2,0);
03901 SSVAL(*rparam,4,desc.neededlen);
03902
03903 DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
03904 SAFE_FREE(tmpdata);
03905
03906 return True;
03907 }
03908
03909 static BOOL api_WPrintDestEnum(connection_struct *conn, uint16 vuid,
03910 char *param, int tpscnt,
03911 char *data, int tdscnt,
03912 int mdrcnt,int mprcnt,
03913 char **rdata,char **rparam,
03914 int *rdata_len,int *rparam_len)
03915 {
03916 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
03917 char *str2 = skip_string(param,tpscnt,str1);
03918 char *p = skip_string(param,tpscnt,str2);
03919 int uLevel;
03920 int queuecnt;
03921 int i, n, succnt=0;
03922 struct pack_desc desc;
03923 int services = lp_numservices();
03924
03925 if (!str1 || !str2 || !p) {
03926 return False;
03927 }
03928
03929 memset((char *)&desc,'\0',sizeof(desc));
03930
03931 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
03932
03933 DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
03934
03935
03936 if (strcmp(str1,"WrLeh") != 0) {
03937 return False;
03938 }
03939 if (!check_printdest_info(&desc,uLevel,str2)) {
03940 return False;
03941 }
03942
03943 queuecnt = 0;
03944 for (i = 0; i < services; i++) {
03945 if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
03946 queuecnt++;
03947 }
03948 }
03949
03950 if (mdrcnt > 0) {
03951 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
03952 if (!*rdata) {
03953 return False;
03954 }
03955 }
03956
03957 desc.base = *rdata;
03958 desc.buflen = mdrcnt;
03959 if (init_package(&desc,queuecnt,0)) {
03960 succnt = 0;
03961 n = 0;
03962 for (i = 0; i < services; i++) {
03963 if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
03964 fill_printdest_info(conn,i,uLevel,&desc);
03965 n++;
03966 if (desc.errcode == NERR_Success) {
03967 succnt = n;
03968 }
03969 }
03970 }
03971 }
03972
03973 *rdata_len = desc.usedlen;
03974
03975 *rparam_len = 8;
03976 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
03977 if (!*rparam) {
03978 return False;
03979 }
03980 SSVALS(*rparam,0,desc.errcode);
03981 SSVAL(*rparam,2,0);
03982 SSVAL(*rparam,4,succnt);
03983 SSVAL(*rparam,6,queuecnt);
03984
03985 DEBUG(4,("WPrintDestEnumerate: errorcode %d\n",desc.errcode));
03986
03987 return True;
03988 }
03989
03990 static BOOL api_WPrintDriverEnum(connection_struct *conn, uint16 vuid,
03991 char *param, int tpscnt,
03992 char *data, int tdscnt,
03993 int mdrcnt,int mprcnt,
03994 char **rdata,char **rparam,
03995 int *rdata_len,int *rparam_len)
03996 {
03997 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
03998 char *str2 = skip_string(param,tpscnt,str1);
03999 char *p = skip_string(param,tpscnt,str2);
04000 int uLevel;
04001 int succnt;
04002 struct pack_desc desc;
04003
04004 if (!str1 || !str2 || !p) {
04005 return False;
04006 }
04007
04008 memset((char *)&desc,'\0',sizeof(desc));
04009
04010 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
04011
04012 DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
04013
04014
04015 if (strcmp(str1,"WrLeh") != 0) {
04016 return False;
04017 }
04018 if (uLevel != 0 || strcmp(str2,"B41") != 0) {
04019 return False;
04020 }
04021
04022 if (mdrcnt > 0) {
04023 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
04024 if (!*rdata) {
04025 return False;
04026 }
04027 }
04028 desc.base = *rdata;
04029 desc.buflen = mdrcnt;
04030 if (init_package(&desc,1,0)) {
04031 PACKS(&desc,"B41","NULL");
04032 }
04033
04034 succnt = (desc.errcode == NERR_Success ? 1 : 0);
04035
04036 *rdata_len = desc.usedlen;
04037
04038 *rparam_len = 8;
04039 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
04040 if (!*rparam) {
04041 return False;
04042 }
04043 SSVALS(*rparam,0,desc.errcode);
04044 SSVAL(*rparam,2,0);
04045 SSVAL(*rparam,4,succnt);
04046 SSVAL(*rparam,6,1);
04047
04048 DEBUG(4,("WPrintDriverEnum: errorcode %d\n",desc.errcode));
04049
04050 return True;
04051 }
04052
04053 static BOOL api_WPrintQProcEnum(connection_struct *conn, uint16 vuid,
04054 char *param, int tpscnt,
04055 char *data, int tdscnt,
04056 int mdrcnt,int mprcnt,
04057 char **rdata,char **rparam,
04058 int *rdata_len,int *rparam_len)
04059 {
04060 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
04061 char *str2 = skip_string(param,tpscnt,str1);
04062 char *p = skip_string(param,tpscnt,str2);
04063 int uLevel;
04064 int succnt;
04065 struct pack_desc desc;
04066
04067 if (!str1 || !str2 || !p) {
04068 return False;
04069 }
04070 memset((char *)&desc,'\0',sizeof(desc));
04071
04072 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
04073
04074 DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
04075
04076
04077 if (strcmp(str1,"WrLeh") != 0) {
04078 return False;
04079 }
04080 if (uLevel != 0 || strcmp(str2,"B13") != 0) {
04081 return False;
04082 }
04083
04084 if (mdrcnt > 0) {
04085 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
04086 if (!*rdata) {
04087 return False;
04088 }
04089 }
04090 desc.base = *rdata;
04091 desc.buflen = mdrcnt;
04092 desc.format = str2;
04093 if (init_package(&desc,1,0)) {
04094 PACKS(&desc,"B13","lpd");
04095 }
04096
04097 succnt = (desc.errcode == NERR_Success ? 1 : 0);
04098
04099 *rdata_len = desc.usedlen;
04100
04101 *rparam_len = 8;
04102 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
04103 if (!*rparam) {
04104 return False;
04105 }
04106 SSVALS(*rparam,0,desc.errcode);
04107 SSVAL(*rparam,2,0);
04108 SSVAL(*rparam,4,succnt);
04109 SSVAL(*rparam,6,1);
04110
04111 DEBUG(4,("WPrintQProcEnum: errorcode %d\n",desc.errcode));
04112
04113 return True;
04114 }
04115
04116 static BOOL api_WPrintPortEnum(connection_struct *conn, uint16 vuid,
04117 char *param, int tpscnt,
04118 char *data, int tdscnt,
04119 int mdrcnt,int mprcnt,
04120 char **rdata,char **rparam,
04121 int *rdata_len,int *rparam_len)
04122 {
04123 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
04124 char *str2 = skip_string(param,tpscnt,str1);
04125 char *p = skip_string(param,tpscnt,str2);
04126 int uLevel;
04127 int succnt;
04128 struct pack_desc desc;
04129
04130 if (!str1 || !str2 || !p) {
04131 return False;
04132 }
04133
04134 memset((char *)&desc,'\0',sizeof(desc));
04135
04136 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
04137
04138 DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
04139
04140
04141 if (strcmp(str1,"WrLeh") != 0) {
04142 return False;
04143 }
04144 if (uLevel != 0 || strcmp(str2,"B9") != 0) {
04145 return False;
04146 }
04147
04148 if (mdrcnt > 0) {
04149 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
04150 if (!*rdata) {
04151 return False;
04152 }
04153 }
04154 memset((char *)&desc,'\0',sizeof(desc));
04155 desc.base = *rdata;
04156 desc.buflen = mdrcnt;
04157 desc.format = str2;
04158 if (init_package(&desc,1,0)) {
04159 PACKS(&desc,"B13","lp0");
04160 }
04161
04162 succnt = (desc.errcode == NERR_Success ? 1 : 0);
04163
04164 *rdata_len = desc.usedlen;
04165
04166 *rparam_len = 8;
04167 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
04168 if (!*rparam) {
04169 return False;
04170 }
04171 SSVALS(*rparam,0,desc.errcode);
04172 SSVAL(*rparam,2,0);
04173 SSVAL(*rparam,4,succnt);
04174 SSVAL(*rparam,6,1);
04175
04176 DEBUG(4,("WPrintPortEnum: errorcode %d\n",desc.errcode));
04177
04178 return True;
04179 }
04180
04181
04182
04183
04184
04185 static BOOL api_RNetSessionEnum(connection_struct *conn, uint16 vuid,
04186 char *param, int tpscnt,
04187 char *data, int tdscnt,
04188 int mdrcnt,int mprcnt,
04189 char **rdata,char **rparam,
04190 int *rdata_len,int *rparam_len)
04191
04192 {
04193 char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
04194 char *str2 = skip_string(param,tpscnt,str1);
04195 char *p = skip_string(param,tpscnt,str2);
04196 int uLevel;
04197 struct pack_desc desc;
04198 struct sessionid *session_list = NULL;
04199 int i, num_sessions;
04200
04201 if (!str1 || !str2 || !p) {
04202 return False;
04203 }
04204
04205 memset((char *)&desc,'\0',sizeof(desc));
04206
04207 uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
04208
04209 DEBUG(3,("RNetSessionEnum uLevel=%d\n",uLevel));
04210 DEBUG(7,("RNetSessionEnum req string=%s\n",str1));
04211 DEBUG(7,("RNetSessionEnum ret string=%s\n",str2));
04212
04213
04214 if (strcmp(str1,RAP_NetSessionEnum_REQ) != 0) {
04215 return False;
04216 }
04217 if (uLevel != 2 || strcmp(str2,RAP_SESSION_INFO_L2) != 0) {
04218 return False;
04219 }
04220
04221 num_sessions = list_sessions(&session_list);
04222
04223 if (mdrcnt > 0) {
04224 *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
04225 if (!*rdata) {
04226 SAFE_FREE(session_list);
04227 return False;
04228 }
04229 }
04230 memset((char *)&desc,'\0',sizeof(desc));
04231 desc.base = *rdata;
04232 desc.buflen = mdrcnt;
04233 desc.format = str2;
04234 if (!init_package(&desc,num_sessions,0)) {
04235 SAFE_FREE(session_list);
04236 return False;
04237 }
04238
04239 for(i=0; i<num_sessions; i++) {
04240 PACKS(&desc, "z", session_list[i].remote_machine);
04241 PACKS(&desc, "z", session_list[i].username);
04242 PACKI(&desc, "W", 1);
04243 PACKI(&desc, "W", 0);
04244 PACKI(&desc, "W", 1);
04245 PACKI(&desc, "D", 0);
04246 PACKI(&desc, "D", 0);
04247 PACKI(&desc, "D", 0);
04248 PACKS(&desc, "z", "Unknown Client");
04249 }
04250
04251 *rdata_len = desc.usedlen;
04252
04253 *rparam_len = 8;
04254 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
04255 if (!*rparam) {
04256 SAFE_FREE(session_list);
04257 return False;
04258 }
04259 SSVALS(*rparam,0,desc.errcode);
04260 SSVAL(*rparam,2,0);
04261 SSVAL(*rparam,4,num_sessions);
04262
04263 DEBUG(4,("RNetSessionEnum: errorcode %d\n",desc.errcode));
04264
04265 SAFE_FREE(session_list);
04266 return True;
04267 }
04268
04269
04270
04271
04272
04273
04274 static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param, char *data,
04275 int mdrcnt, int mprcnt,
04276 char **rdata, char **rparam,
04277 int *rdata_len, int *rparam_len)
04278 {
04279 *rparam_len = MIN(*rparam_len,mprcnt);
04280 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
04281 if (!*rparam) {
04282 return False;
04283 }
04284
04285 *rdata_len = 0;
04286
04287 SSVAL(*rparam,0,NERR_BufTooSmall);
04288
04289 DEBUG(3,("Supplied buffer too small in API command\n"));
04290
04291 return True;
04292 }
04293
04294
04295
04296
04297
04298 static BOOL api_Unsupported(connection_struct *conn, uint16 vuid,
04299 char *param, int tpscnt,
04300 char *data, int tdscnt,
04301 int mdrcnt, int mprcnt,
04302 char **rdata, char **rparam,
04303 int *rdata_len, int *rparam_len)
04304 {
04305 *rparam_len = 4;
04306 *rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
04307 if (!*rparam) {
04308 return False;
04309 }
04310
04311 *rdata_len = 0;
04312
04313 SSVAL(*rparam,0,NERR_notsupported);
04314 SSVAL(*rparam,2,0);
04315
04316 DEBUG(3,("Unsupported API command\n"));
04317
04318 return True;
04319 }
04320
04321 static const struct {
04322 const char *name;
04323 int id;
04324 BOOL (*fn)(connection_struct *, uint16,
04325 char *, int,
04326 char *, int,
04327 int,int,char **,char **,int *,int *);
04328 BOOL auth_user;
04329 } api_commands[] = {
04330 {"RNetShareEnum", RAP_WshareEnum, api_RNetShareEnum, True},
04331 {"RNetShareGetInfo", RAP_WshareGetInfo, api_RNetShareGetInfo},
04332 {"RNetShareAdd", RAP_WshareAdd, api_RNetShareAdd},
04333 {"RNetSessionEnum", RAP_WsessionEnum, api_RNetSessionEnum, True},
04334 {"RNetServerGetInfo", RAP_WserverGetInfo, api_RNetServerGetInfo},
04335 {"RNetGroupEnum", RAP_WGroupEnum, api_RNetGroupEnum, True},
04336 {"RNetGroupGetUsers", RAP_WGroupGetUsers, api_RNetGroupGetUsers, True},
04337 {"RNetUserEnum", RAP_WUserEnum, api_RNetUserEnum, True},
04338 {"RNetUserGetInfo", RAP_WUserGetInfo, api_RNetUserGetInfo},
04339 {"NetUserGetGroups", RAP_WUserGetGroups, api_NetUserGetGroups},
04340 {"NetWkstaGetInfo", RAP_WWkstaGetInfo, api_NetWkstaGetInfo},
04341 {"DosPrintQEnum", RAP_WPrintQEnum, api_DosPrintQEnum, True},
04342 {"DosPrintQGetInfo", RAP_WPrintQGetInfo, api_DosPrintQGetInfo},
04343 {"WPrintQueuePause", RAP_WPrintQPause, api_WPrintQueueCtrl},
04344 {"WPrintQueueResume", RAP_WPrintQContinue, api_WPrintQueueCtrl},
04345 {"WPrintJobEnumerate",RAP_WPrintJobEnum, api_WPrintJobEnumerate},
04346 {"WPrintJobGetInfo", RAP_WPrintJobGetInfo, api_WPrintJobGetInfo},
04347 {"RDosPrintJobDel", RAP_WPrintJobDel, api_RDosPrintJobDel},
04348 {"RDosPrintJobPause", RAP_WPrintJobPause, api_RDosPrintJobDel},
04349 {"RDosPrintJobResume",RAP_WPrintJobContinue, api_RDosPrintJobDel},
04350 {"WPrintDestEnum", RAP_WPrintDestEnum, api_WPrintDestEnum},
04351 {"WPrintDestGetInfo", RAP_WPrintDestGetInfo, api_WPrintDestGetInfo},
04352 {"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD},
04353 {"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl},
04354 {"NetServerEnum", RAP_NetServerEnum2, api_RNetServerEnum},
04355 {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms},
04356 {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword},
04357 {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon},
04358 {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo},
04359 {"WPrintDriverEnum", RAP_WPrintDriverEnum, api_WPrintDriverEnum},
04360 {"WPrintQProcEnum", RAP_WPrintQProcessorEnum,api_WPrintQProcEnum},
04361 {"WPrintPortEnum", RAP_WPrintPortEnum, api_WPrintPortEnum},
04362 {"SamOEMChangePassword",RAP_SamOEMChgPasswordUser2_P,api_SamOEMChangePassword},
04363 {NULL, -1, api_Unsupported}
04364
04365
04366
04367
04368 };
04369
04370
04371
04372
04373
04374
04375 int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
04376 int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
04377 {
04378 int api_command;
04379 char *rdata = NULL;
04380 char *rparam = NULL;
04381 const char *name1 = NULL;
04382 const char *name2 = NULL;
04383 int rdata_len = 0;
04384 int rparam_len = 0;
04385 BOOL reply=False;
04386 int i;
04387
04388 if (!params) {
04389 DEBUG(0,("ERROR: NULL params in api_reply()\n"));
04390 return 0;
04391 }
04392
04393 if (tpscnt < 2) {
04394 return 0;
04395 }
04396 api_command = SVAL(params,0);
04397
04398 if (skip_string(params,tpscnt,params+2)) {
04399 name1 = params + 2;
04400 } else {
04401 name1 = "";
04402 }
04403 name2 = skip_string(params,tpscnt,params+2);
04404 if (!name2) {
04405 name2 = "";
04406 }
04407
04408 DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
04409 api_command,
04410 name1,
04411 name2,
04412 tdscnt,tpscnt,mdrcnt,mprcnt));
04413
04414 for (i=0;api_commands[i].name;i++) {
04415 if (api_commands[i].id == api_command && api_commands[i].fn) {
04416 DEBUG(3,("Doing %s\n",api_commands[i].name));
04417 break;
04418 }
04419 }
04420
04421
04422
04423 if (api_commands[i].auth_user && lp_restrict_anonymous()) {
04424 user_struct *user = get_valid_user_struct(vuid);
04425
04426 if (!user || user->guest) {
04427 return ERROR_NT(NT_STATUS_ACCESS_DENIED);
04428 }
04429 }
04430
04431 rdata = (char *)SMB_MALLOC(1024);
04432 if (rdata) {
04433 memset(rdata,'\0',1024);
04434 }
04435
04436 rparam = (char *)SMB_MALLOC(1024);
04437 if (rparam) {
04438 memset(rparam,'\0',1024);
04439 }
04440
04441 if(!rdata || !rparam) {
04442 DEBUG(0,("api_reply: malloc fail !\n"));
04443 SAFE_FREE(rdata);
04444 SAFE_FREE(rparam);
04445 return -1;
04446 }
04447
04448 reply = api_commands[i].fn(conn,
04449 vuid,
04450 params,tpscnt,
04451 data,tdscnt,
04452 mdrcnt,mprcnt,
04453 &rdata,&rparam,&rdata_len,&rparam_len);
04454
04455
04456 if (rdata_len > mdrcnt || rparam_len > mprcnt) {
04457 reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
04458 &rdata,&rparam,&rdata_len,&rparam_len);
04459 }
04460
04461
04462 if (!reply) {
04463 reply = api_Unsupported(conn,vuid,params,tpscnt,data,tdscnt,mdrcnt,mprcnt,
04464 &rdata,&rparam,&rdata_len,&rparam_len);
04465 }
04466
04467
04468 if (reply) {
04469 send_trans_reply(outbuf, rparam, rparam_len, rdata, rdata_len, False);
04470 }
04471
04472 SAFE_FREE(rdata);
04473 SAFE_FREE(rparam);
04474 return -1;
04475 }