-/*
+/*
Unix SMB/CIFS implementation.
Inter-process communication and named pipe handling
Copyright (C) Andrew Tridgell 1992-1998
SMB Version handling
Copyright (C) John H Terpstra 1995-1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "includes.h"
-
-extern struct current_user current_user;
-extern userdom_struct current_user_info;
+#include "smbd/globals.h"
+#include "../librpc/gen_ndr/ndr_samr_c.h"
+#include "../librpc/gen_ndr/ndr_spoolss_c.h"
+#include "rpc_client/cli_spoolss.h"
+#include "rpc_client/init_spoolss.h"
+#include "../librpc/gen_ndr/ndr_srvsvc_c.h"
+#include "../librpc/gen_ndr/srv_samr.h"
+#include "../librpc/gen_ndr/srv_srvsvc.h"
+#include "../librpc/gen_ndr/rap.h"
+#include "../lib/util/binsearch.h"
+#include "../libcli/auth/libcli_auth.h"
+#include "rpc_client/init_lsa.h"
+#include "rpc_server/rpc_ncacn_np.h"
+#include "../libcli/security/security.h"
+#include "printing.h"
+#include "passdb/machine_sid.h"
#ifdef CHECK_TYPES
#undef CHECK_TYPES
return val;
}
-static bool api_Unsupported(connection_struct *conn, uint16 vuid,
+static bool api_Unsupported(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt, int mprcnt,
char **rdata, char **rparam,
int *rdata_len, int *rparam_len);
-static bool api_TooSmall(connection_struct *conn, uint16 vuid, char *param, char *data,
+static bool api_TooSmall(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid, char *param, char *data,
int mdrcnt, int mprcnt,
char **rdata, char **rparam,
int *rdata_len, int *rparam_len);
}
buf = talloc_sub_advanced(ctx,
lp_servicename(SNUM(conn)),
- conn->server_info->unix_name,
+ conn->session_info->unix_name,
conn->connectpath,
- conn->server_info->gid,
- get_current_username(),
- current_user_info.domain,
+ conn->session_info->utok.gid,
+ conn->session_info->sanitized_username,
+ conn->session_info->info3->base.domain.string,
buf);
if (!buf) {
*p_space_remaining = 0;
}
buf = talloc_sub_advanced(ctx,
lp_servicename(SNUM(conn)),
- conn->server_info->unix_name,
+ conn->session_info->unix_name,
conn->connectpath,
- conn->server_info->gid,
- get_current_username(),
- current_user_info.domain,
+ conn->session_info->utok.gid,
+ conn->session_info->sanitized_username,
+ conn->session_info->info3->base.domain.string,
buf);
if (!buf) {
return 0;
return strlen(buf) + 1;
}
-static char *Expand(connection_struct *conn, int snum, char *s)
-{
- TALLOC_CTX *ctx = talloc_tos();
- char *buf = NULL;
-
- if (!s) {
- return NULL;
- }
- buf = talloc_strdup(ctx,s);
- if (!buf) {
- return 0;
- }
- buf = talloc_string_sub(ctx,buf,"%S",lp_servicename(snum));
- if (!buf) {
- return 0;
- }
- return talloc_sub_advanced(ctx,
- lp_servicename(SNUM(conn)),
- conn->server_info->unix_name,
- conn->connectpath,
- conn->server_info->gid,
- get_current_username(),
- current_user_info.domain,
- buf);
-}
-
/*******************************************************************
Check a API string for validity when we only need to check the prefix.
******************************************************************/
int buflen; /* remaining size for fixed part; on init: length of base */
int subcount; /* count of substructures */
char *structbuf; /* pointer into buffer for remaining fixed part */
- int stringlen; /* remaining size for variable part */
+ int stringlen; /* remaining size for variable part */
char *stringbuf; /* pointer into buffer for remaining variable part */
int neededlen; /* total needed size */
int usedlen; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
#define RAP_QUEUE_STATUS_PAUSED 1
#define RAP_QUEUE_STATUS_ERROR 2
-/* turn a print job status into a on the wire status
+/* turn a print job status into a on the wire status
*/
-static int printj_status(int v)
+static int printj_spoolss_status(int v)
{
- switch (v) {
- case LPQ_QUEUED:
+ if (v == JOB_STATUS_QUEUED)
return RAP_JOB_STATUS_QUEUED;
- case LPQ_PAUSED:
+ if (v & JOB_STATUS_PAUSED)
return RAP_JOB_STATUS_PAUSED;
- case LPQ_SPOOLING:
+ if (v & JOB_STATUS_SPOOLING)
return RAP_JOB_STATUS_SPOOLING;
- case LPQ_PRINTING:
+ if (v & JOB_STATUS_PRINTING)
return RAP_JOB_STATUS_PRINTING;
- }
return 0;
}
-/* turn a print queue status into a on the wire status
+/* turn a print queue status into a on the wire status
*/
-static int printq_status(int v)
+static int printq_spoolss_status(int v)
{
- switch (v) {
- case LPQ_QUEUED:
+ if (v == PRINTER_STATUS_OK)
return 0;
- case LPQ_PAUSED:
+ if (v & PRINTER_STATUS_PAUSED)
return RAP_QUEUE_STATUS_PAUSED;
- }
return RAP_QUEUE_STATUS_ERROR;
}
-static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
- struct pack_desc *desc,
- print_queue_struct *queue, int n)
+static void fill_spoolss_printjob_info(int uLevel,
+ struct pack_desc *desc,
+ struct spoolss_JobInfo2 *info2,
+ int n)
{
- time_t t = queue->time;
+ time_t t = spoolss_Time_to_time_t(&info2->submitted);
/* the client expects localtime */
t -= get_time_zone(t);
- PACKI(desc,"W",pjobid_to_rap(lp_const_servicename(snum),queue->job)); /* uJobId */
+ PACKI(desc,"W",pjobid_to_rap(info2->printer_name, info2->job_id)); /* uJobId */
if (uLevel == 1) {
- PACKS(desc,"B21",queue->fs_user); /* szUserName */
+ PACKS(desc,"B21", info2->user_name); /* szUserName */
PACKS(desc,"B",""); /* pad */
PACKS(desc,"B16",""); /* szNotifyName */
PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
PACKS(desc,"z",""); /* pszParms */
PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
+ PACKI(desc,"W", printj_spoolss_status(info2->status)); /* fsStatus */
PACKS(desc,"z",""); /* pszStatus */
- PACKI(desc,"D",t); /* ulSubmitted */
- PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z",queue->fs_file); /* pszComment */
+ PACKI(desc,"D", t); /* ulSubmitted */
+ PACKI(desc,"D", info2->size); /* ulSize */
+ PACKS(desc,"z", info2->document_name); /* pszComment */
}
if (uLevel == 2 || uLevel == 3 || uLevel == 4) {
- PACKI(desc,"W",queue->priority); /* uPriority */
- PACKS(desc,"z",queue->fs_user); /* pszUserName */
+ PACKI(desc,"W", info2->priority); /* uPriority */
+ PACKS(desc,"z", info2->user_name); /* pszUserName */
PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
+ PACKI(desc,"W", printj_spoolss_status(info2->status)); /* fsStatus */
PACKI(desc,"D",t); /* ulSubmitted */
- PACKI(desc,"D",queue->size); /* ulSize */
+ PACKI(desc,"D", info2->size); /* ulSize */
PACKS(desc,"z","Samba"); /* pszComment */
- PACKS(desc,"z",queue->fs_file); /* pszDocument */
+ PACKS(desc,"z", info2->document_name); /* pszDocument */
if (uLevel == 3) {
PACKS(desc,"z",""); /* pszNotifyName */
PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
PACKS(desc,"z",""); /* pszParms */
PACKS(desc,"z",""); /* pszStatus */
- PACKS(desc,"z",SERVICE(snum)); /* pszQueue */
+ PACKS(desc,"z", info2->printer_name); /* pszQueue */
PACKS(desc,"z","lpd"); /* pszQProcName */
PACKS(desc,"z",""); /* pszQProcParms */
PACKS(desc,"z","NULL"); /* pszDriverName */
}
}
-/********************************************************************
- Return a driver name given an snum.
- Returns True if from tdb, False otherwise.
- ********************************************************************/
-
-static bool get_driver_name(int snum, char **pp_drivername)
-{
- NT_PRINTER_INFO_LEVEL *info = NULL;
- bool in_tdb = false;
-
- get_a_printer (NULL, &info, 2, lp_servicename(snum));
- if (info != NULL) {
- *pp_drivername = talloc_strdup(talloc_tos(),
- info->info_2->drivername);
- in_tdb = true;
- free_a_printer(&info, 2);
- if (!*pp_drivername) {
- return false;
- }
- }
-
- return in_tdb;
-}
-
/********************************************************************
Respond to the DosPrintQInfo command with a level of 52
This is used to get printer driver information for Win9x clients
********************************************************************/
-static void fill_printq_info_52(connection_struct *conn, int snum,
- struct pack_desc* desc, int count )
+static void fill_printq_info_52(struct spoolss_DriverInfo3 *driver,
+ struct pack_desc* desc, int count,
+ const char *printer_name)
{
int i;
fstring location;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- ZERO_STRUCT(driver);
-
- if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
- DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n",
- lp_servicename(snum)));
- goto err;
- }
-
- if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
- "Windows 4.0", 0)) )
- {
- DEBUG(3,("fill_printq_info_52: Failed to lookup driver [%s]\n",
- printer->info_2->drivername));
- goto err;
- }
-
- trim_string(driver.info_3->driverpath, "\\print$\\WIN40\\0\\", 0);
- trim_string(driver.info_3->datafile, "\\print$\\WIN40\\0\\", 0);
- trim_string(driver.info_3->helpfile, "\\print$\\WIN40\\0\\", 0);
+ trim_string((char *)driver->driver_path, "\\print$\\WIN40\\0\\", 0);
+ trim_string((char *)driver->data_file, "\\print$\\WIN40\\0\\", 0);
+ trim_string((char *)driver->help_file, "\\print$\\WIN40\\0\\", 0);
PACKI(desc, "W", 0x0400); /* don't know */
- PACKS(desc, "z", driver.info_3->name); /* long printer name */
- PACKS(desc, "z", driver.info_3->driverpath); /* Driverfile Name */
- PACKS(desc, "z", driver.info_3->datafile); /* Datafile name */
- PACKS(desc, "z", driver.info_3->monitorname); /* language monitor */
+ PACKS(desc, "z", driver->driver_name); /* long printer name */
+ PACKS(desc, "z", driver->driver_path); /* Driverfile Name */
+ PACKS(desc, "z", driver->data_file); /* Datafile name */
+ PACKS(desc, "z", driver->monitor_name); /* language monitor */
fstrcpy(location, "\\\\%L\\print$\\WIN40\\0");
standard_sub_basic( "", "", location, sizeof(location)-1 );
PACKS(desc,"z", location); /* share to retrieve files */
- PACKS(desc,"z", driver.info_3->defaultdatatype); /* default data type */
- PACKS(desc,"z", driver.info_3->helpfile); /* helpfile name */
- PACKS(desc,"z", driver.info_3->driverpath); /* driver name */
+ PACKS(desc,"z", driver->default_datatype); /* default data type */
+ PACKS(desc,"z", driver->help_file); /* helpfile name */
+ PACKS(desc,"z", driver->driver_path); /* driver name */
- DEBUG(3,("Printer Driver Name: %s:\n",driver.info_3->name));
- DEBUG(3,("Driver: %s:\n",driver.info_3->driverpath));
- DEBUG(3,("Data File: %s:\n",driver.info_3->datafile));
- DEBUG(3,("Language Monitor: %s:\n",driver.info_3->monitorname));
+ DEBUG(3,("Printer Driver Name: %s:\n",driver->driver_name));
+ DEBUG(3,("Driver: %s:\n",driver->driver_path));
+ DEBUG(3,("Data File: %s:\n",driver->data_file));
+ DEBUG(3,("Language Monitor: %s:\n",driver->monitor_name));
DEBUG(3,("Driver Location: %s:\n",location));
- DEBUG(3,("Data Type: %s:\n",driver.info_3->defaultdatatype));
- DEBUG(3,("Help File: %s:\n",driver.info_3->helpfile));
+ DEBUG(3,("Data Type: %s:\n",driver->default_datatype));
+ DEBUG(3,("Help File: %s:\n",driver->help_file));
PACKI(desc,"N",count); /* number of files to copy */
- for ( i=0; i<count && driver.info_3->dependentfiles && *driver.info_3->dependentfiles[i]; i++)
+ for ( i=0; i<count && driver->dependent_files && *driver->dependent_files[i]; i++)
{
- trim_string(driver.info_3->dependentfiles[i], "\\print$\\WIN40\\0\\", 0);
- PACKS(desc,"z",driver.info_3->dependentfiles[i]); /* driver files to copy */
- DEBUG(3,("Dependent File: %s:\n",driver.info_3->dependentfiles[i]));
+ trim_string((char *)driver->dependent_files[i], "\\print$\\WIN40\\0\\", 0);
+ PACKS(desc,"z",driver->dependent_files[i]); /* driver files to copy */
+ DEBUG(3,("Dependent File: %s:\n", driver->dependent_files[i]));
}
/* sanity check */
DEBUG(3,("fill_printq_info_52: file count specified by client [%d] != number of dependent files [%i]\n",
count, i));
- DEBUG(3,("fill_printq_info on <%s> gave %d entries\n", SERVICE(snum),i));
+ DEBUG(3,("fill_printq_info on <%s> gave %d entries\n", printer_name, i));
desc->errcode=NERR_Success;
- goto done;
-err:
- DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
- desc->errcode=NERR_notsupported;
+}
+
+static const char *strip_unc(const char *unc)
+{
+ char *p;
+
+ if (unc == NULL) {
+ return NULL;
+ }
-done:
- if ( printer )
- free_a_printer( &printer, 2 );
+ if ((p = strrchr(unc, '\\')) != NULL) {
+ return p+1;
+ }
- if ( driver.info_3 )
- free_a_printer_driver( driver, 3 );
+ return unc;
}
-
-static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
+static void fill_printq_info(int uLevel,
struct pack_desc* desc,
- int count, print_queue_struct* queue,
- print_status_struct* status)
+ int count,
+ union spoolss_JobInfo *job_info,
+ struct spoolss_DriverInfo3 *driver_info,
+ struct spoolss_PrinterInfo2 *printer_info)
{
switch (uLevel) {
+ case 0:
case 1:
case 2:
- PACKS(desc,"B13",SERVICE(snum));
+ PACKS(desc,"B13", strip_unc(printer_info->printername));
break;
case 3:
case 4:
case 5:
- PACKS(desc,"z",Expand(conn,snum,SERVICE(snum)));
+ PACKS(desc,"z", strip_unc(printer_info->printername));
break;
case 51:
- PACKI(desc,"K",printq_status(status->status));
+ PACKI(desc,"K", printq_spoolss_status(printer_info->status));
break;
}
PACKI(desc,"W",0); /* until time */
PACKS(desc,"z",""); /* pSepFile */
PACKS(desc,"z","lpd"); /* pPrProc */
- PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
+ PACKS(desc,"z", strip_unc(printer_info->printername)); /* pDestinations */
PACKS(desc,"z",""); /* pParms */
- if (snum < 0) {
+ if (printer_info->printername == NULL) {
PACKS(desc,"z","UNKNOWN PRINTER");
PACKI(desc,"W",LPSTAT_ERROR);
- }
- else if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(conn,snum,lp_comment(snum)));
- PACKI(desc,"W",LPSTAT_OK); /* status */
} else {
- PACKS(desc,"z",status->message);
- PACKI(desc,"W",printq_status(status->status)); /* status */
+ PACKS(desc,"z", printer_info->comment);
+ PACKI(desc,"W", printq_spoolss_status(printer_info->status)); /* status */
}
PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
}
if (uLevel == 3 || uLevel == 4) {
- char *drivername = NULL;
-
PACKI(desc,"W",5); /* uPriority */
PACKI(desc,"W",0); /* uStarttime */
PACKI(desc,"W",0); /* uUntiltime */
PACKS(desc,"z",NULL); /* pszComment - don't ask.... JRA */
/* "don't ask" that it's done this way to fix corrupted
Win9X/ME printer comments. */
- if (!status) {
- PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
- } else {
- PACKI(desc,"W",printq_status(status->status)); /* fsStatus */
- }
+ PACKI(desc,"W", printq_spoolss_status(printer_info->status)); /* fsStatus */
PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
- PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
- get_driver_name(snum,&drivername);
- if (!drivername) {
- return;
- }
- PACKS(desc,"z",drivername); /* pszDriverName */
+ PACKS(desc,"z", strip_unc(printer_info->printername)); /* pszPrinters */
+ PACKS(desc,"z", printer_info->drivername); /* pszDriverName */
PackDriverData(desc); /* pDriverData */
}
if (uLevel == 2 || uLevel == 4) {
int i;
- for (i=0;i<count;i++)
- fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
+ for (i = 0; i < count; i++) {
+ fill_spoolss_printjob_info(uLevel == 2 ? 1 : 2, desc, &job_info[i].info2, i);
+ }
}
if (uLevel==52)
- fill_printq_info_52( conn, snum, desc, count );
+ fill_printq_info_52(driver_info, desc, count, printer_info->printername);
}
/* This function returns the number of files for a given driver */
-static int get_printerdrivernumber(int snum)
+static int get_printerdrivernumber(const struct spoolss_DriverInfo3 *driver)
{
int result = 0;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- ZERO_STRUCT(driver);
-
- if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
- DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n",
- lp_servicename(snum)));
- goto done;
- }
-
- if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername,
- "Windows 4.0", 0)) )
- {
- DEBUG(3,("get_printerdrivernumber: Failed to lookup driver [%s]\n",
- printer->info_2->drivername));
- goto done;
- }
/* count the number of files */
- while ( driver.info_3->dependentfiles && *driver.info_3->dependentfiles[result] )
- result++;
- \
- done:
- if ( printer )
- free_a_printer( &printer, 2 );
-
- if ( driver.info_3 )
- free_a_printer_driver( driver, 3 );
+ while (driver->dependent_files && *driver->dependent_files[result])
+ result++;
return result;
}
-static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid,
+static bool api_DosPrintQGetInfo(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *p = skip_string(param,tpscnt,str2);
char *QueueName = p;
unsigned int uLevel;
- int count=0;
- int snum;
+ uint32_t count = 0;
char *str3;
struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
char* tmpdata=NULL;
+ WERROR werr = WERR_OK;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct policy_handle handle;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ union spoolss_DriverInfo driver_info;
+ union spoolss_JobInfo *job_info = NULL;
+ union spoolss_PrinterInfo printer_info;
+
if (!str1 || !str2 || !p) {
return False;
}
- memset((char *)&status,'\0',sizeof(status));
memset((char *)&desc,'\0',sizeof(desc));
p = skip_string(param,tpscnt,p);
/* remove any trailing username */
if ((p = strchr_m(QueueName,'%')))
*p = 0;
-
+
DEBUG(3,("api_DosPrintQGetInfo uLevel=%d name=%s\n",uLevel,QueueName));
-
+
/* check it's a supported varient */
if (!prefix_ok(str1,"zWrLh"))
return False;
SSVAL(*rparam,4,0);
return(True);
}
-
- snum = find_service(QueueName);
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
- return False;
-
+
+ ZERO_STRUCT(handle);
+
+ if (QueueName == NULL || (strlen(QueueName) < 1)) {
+ desc.errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
+
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_DosPrintQGetInfo: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ b = cli->binding_handle;
+
+ ZERO_STRUCT(devmode_ctr);
+
+ status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
+ QueueName,
+ "RAW",
+ devmode_ctr,
+ PRINTER_ACCESS_USE,
+ &handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ werr = rpccli_spoolss_getprinter(cli, mem_ctx,
+ &handle,
+ 2,
+ 0,
+ &printer_info);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
if (uLevel==52) {
- count = get_printerdrivernumber(snum);
+ uint32_t server_major_version;
+ uint32_t server_minor_version;
+
+ werr = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
+ &handle,
+ "Windows 4.0",
+ 3, /* level */
+ 0,
+ 0, /* version */
+ 0,
+ &driver_info,
+ &server_major_version,
+ &server_minor_version);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ count = get_printerdrivernumber(&driver_info.info3);
DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
} else {
- count = print_queue_status(snum, &queue,&status);
+ uint32_t num_jobs;
+ werr = rpccli_spoolss_enumjobs(cli, mem_ctx,
+ &handle,
+ 0, /* firstjob */
+ 0xff, /* numjobs */
+ 2, /* level */
+ 0, /* offered */
+ &num_jobs,
+ &job_info);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ count = num_jobs;
}
if (mdrcnt > 0) {
*rdata = smb_realloc_limit(*rdata,mdrcnt);
if (!*rdata) {
- SAFE_FREE(queue);
return False;
}
desc.base = *rdata;
if (init_package(&desc,1,count)) {
desc.subcount = count;
- fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
+ fill_printq_info(uLevel,&desc,count, job_info, &driver_info.info3, &printer_info.info2);
}
*rdata_len = desc.usedlen;
-
+
/*
* We must set the return code to ERRbuftoosmall
* in order to support lanman style printing with Win NT/2k
*/
if (!mdrcnt && lp_disable_spoolss())
desc.errcode = ERRbuftoosmall;
-
+
+ out:
+ if (b && is_valid_policy_hnd(&handle)) {
+ dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
+ }
+
*rdata_len = desc.usedlen;
*rparam_len = 6;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
- SAFE_FREE(queue);
SAFE_FREE(tmpdata);
return False;
}
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
-
+
DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
- SAFE_FREE(queue);
SAFE_FREE(tmpdata);
return(True);
View list of all print jobs on all queues.
****************************************************************************/
-static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid,
+static bool api_DosPrintQEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt, int mprcnt,
char *p = skip_string(param,tpscnt,output_format1);
unsigned int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
char *output_format2 = get_safe_str_ptr(param,tpscnt,p,4);
- int services = lp_numservices();
- int i, n;
+ int i;
struct pack_desc desc;
- print_queue_struct **queue = NULL;
- print_status_struct *status = NULL;
int *subcntarr = NULL;
int queuecnt = 0, subcnt = 0, succnt = 0;
-
+
+ WERROR werr = WERR_OK;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ uint32_t num_printers;
+ union spoolss_PrinterInfo *printer_info;
+ union spoolss_DriverInfo *driver_info;
+ union spoolss_JobInfo **job_info;
+
if (!param_format || !output_format1 || !p) {
return False;
}
memset((char *)&desc,'\0',sizeof(desc));
DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
-
+
if (!prefix_ok(param_format,"WrLeh")) {
return False;
}
return(True);
}
- for (i = 0; i < services; i++) {
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- queuecnt++;
- }
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_DosPrintQEnum: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ b = cli->binding_handle;
+
+ werr = rpccli_spoolss_enumprinters(cli, mem_ctx,
+ PRINTER_ENUM_LOCAL,
+ cli->srv_name_slash,
+ 2,
+ 0,
+ &num_printers,
+ &printer_info);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
}
- if((queue = SMB_MALLOC_ARRAY(print_queue_struct*, queuecnt)) == NULL) {
- DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+ queuecnt = num_printers;
+
+ job_info = talloc_array(mem_ctx, union spoolss_JobInfo *, num_printers);
+ if (job_info == NULL) {
goto err;
}
- memset(queue,0,queuecnt*sizeof(print_queue_struct*));
- if((status = SMB_MALLOC_ARRAY(print_status_struct,queuecnt)) == NULL) {
- DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+
+ driver_info = talloc_array(mem_ctx, union spoolss_DriverInfo, num_printers);
+ if (driver_info == NULL) {
goto err;
}
- memset(status,0,queuecnt*sizeof(print_status_struct));
+
if((subcntarr = SMB_MALLOC_ARRAY(int,queuecnt)) == NULL) {
DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
goto err;
}
- subcnt = 0;
- n = 0;
- for (i = 0; i < services; i++) {
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- subcntarr[n] = print_queue_status(i, &queue[n],&status[n]);
- subcnt += subcntarr[n];
- n++;
- }
- }
-
if (mdrcnt > 0) {
*rdata = smb_realloc_limit(*rdata,mdrcnt);
if (!*rdata) {
desc.base = *rdata;
desc.buflen = mdrcnt;
+ subcnt = 0;
+ for (i = 0; i < num_printers; i++) {
+
+ uint32_t num_jobs;
+ struct policy_handle handle;
+ const char *printername;
+
+ printername = talloc_strdup(mem_ctx, printer_info[i].info2.printername);
+ if (printername == NULL) {
+ goto err;
+ }
+
+ ZERO_STRUCT(handle);
+ ZERO_STRUCT(devmode_ctr);
+
+ status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
+ printername,
+ "RAW",
+ devmode_ctr,
+ PRINTER_ACCESS_USE,
+ &handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ werr = rpccli_spoolss_enumjobs(cli, mem_ctx,
+ &handle,
+ 0, /* firstjob */
+ 0xff, /* numjobs */
+ 2, /* level */
+ 0, /* offered */
+ &num_jobs,
+ &job_info[i]);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ if (uLevel==52) {
+ uint32_t server_major_version;
+ uint32_t server_minor_version;
+
+ werr = rpccli_spoolss_getprinterdriver2(cli, mem_ctx,
+ &handle,
+ "Windows 4.0",
+ 3, /* level */
+ 0,
+ 0, /* version */
+ 0,
+ &driver_info[i],
+ &server_major_version,
+ &server_minor_version);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+ }
+
+ subcntarr[i] = num_jobs;
+ subcnt += subcntarr[i];
+
+ if (b && is_valid_policy_hnd(&handle)) {
+ dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
+ }
+ }
+
if (init_package(&desc,queuecnt,subcnt)) {
- n = 0;
- succnt = 0;
- for (i = 0; i < services; i++) {
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printq_info(conn,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
- n++;
- if (desc.errcode == NERR_Success) {
- succnt = n;
- }
+ for (i = 0; i < num_printers; i++) {
+ fill_printq_info(uLevel,&desc,subcntarr[i], job_info[i], &driver_info[i].info3, &printer_info[i].info2);
+ if (desc.errcode == NERR_Success) {
+ succnt = i;
}
}
}
SAFE_FREE(subcntarr);
-
+ out:
*rdata_len = desc.usedlen;
*rparam_len = 8;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,succnt);
SSVAL(*rparam,6,queuecnt);
-
- for (i = 0; i < queuecnt; i++) {
- if (queue) {
- SAFE_FREE(queue[i]);
- }
- }
- SAFE_FREE(queue);
- SAFE_FREE(status);
-
return True;
err:
SAFE_FREE(subcntarr);
- for (i = 0; i < queuecnt; i++) {
- if (queue) {
- SAFE_FREE(queue[i]);
- }
- }
- SAFE_FREE(queue);
- SAFE_FREE(status);
return False;
}
Get info level for a server list query.
****************************************************************************/
-static bool check_server_info(int uLevel, char* id)
+static bool check_session_info(int uLevel, char* id)
{
switch( uLevel ) {
case 0:
return False;
}
break;
- default:
+ default:
return False;
}
return True;
number of entries.
******************************************************************/
-static int get_server_info(uint32 servertype,
+static int get_session_info(uint32 servertype,
struct srv_info_struct **servers,
const char *domain)
{
bool local_list_only;
int i;
- lines = file_lines_load(lock_path(SERVER_LIST), NULL, 0);
+ lines = file_lines_load(cache_path(SERVER_LIST), NULL, 0, NULL);
if (!lines) {
- DEBUG(4,("Can't open %s - %s\n",lock_path(SERVER_LIST),strerror(errno)));
+ DEBUG(4,("Can't open %s - %s\n",cache_path(SERVER_LIST),strerror(errno)));
return 0;
}
alloced += 10;
*servers = SMB_REALLOC_ARRAY(*servers,struct srv_info_struct, alloced);
if (!*servers) {
- DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
- file_lines_free(lines);
+ DEBUG(0,("get_session_info: failed to enlarge servers info struct!\n"));
+ TALLOC_FREE(lines);
return 0;
}
memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
continue;
}
fstrcpy(s->comment, p);
+ string_truncate(s->comment, MAX_SERVER_STRING_LENGTH);
s->domain[0] = '\0';
if (!next_token_talloc(frame,&ptr,&p, NULL)) {
ok = False;
}
- if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
+ if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
(s->type & SV_TYPE_DOMAIN_ENUM)) {
DEBUG(4,("s: dom mismatch "));
ok = False;
}
-
+
if (!strequal(domain, s->domain) && !(servertype & SV_TYPE_DOMAIN_ENUM)) {
ok = False;
}
-
+
/* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
s->name, s->type, s->comment, s->domain));
}
}
-
- file_lines_free(lines);
+
+ TALLOC_FREE(lines);
return count;
}
Fill in a server info structure.
******************************************************************/
-static int fill_srv_info(struct srv_info_struct *service,
- int uLevel, char **buf, int *buflen,
+static int fill_srv_info(struct srv_info_struct *service,
+ int uLevel, char **buf, int *buflen,
char **stringbuf, int *stringspace, char *baseaddr)
{
int struct_len;
char* p2;
int l2;
int len;
-
+
switch (uLevel) {
case 0:
struct_len = 16;
default:
return -1;
}
-
+
if (!buf) {
len = 0;
switch (uLevel) {
*stringspace = len;
return struct_len + len;
}
-
+
len = struct_len;
p = *buf;
if (*buflen < struct_len) {
if (!baseaddr) {
baseaddr = p;
}
-
+
switch (uLevel) {
case 0:
push_ascii(p,service->name, MAX_NETBIOSNAME_LEN, STR_TERMINATE);
}
-static bool srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
+static int srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
{
- return(strcmp(s1->name,s2->name));
+ return StrCaseCmp(s1->name,s2->name);
}
/****************************************************************************
extracted from lists saved by nmbd on the local host.
****************************************************************************/
-static bool api_RNetServerEnum(connection_struct *conn, uint16 vuid,
+static bool api_RNetServerEnum2(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
- int mdrcnt, int mprcnt, char **rdata,
+ int mdrcnt, int mprcnt, char **rdata,
char **rparam, int *rdata_len, int *rparam_len)
{
char *str1 = get_safe_str_ptr(param, tpscnt, param, 2);
}
/* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
- any other bit (they may just set this bit on its own) they
- want all the locally seen servers. However this bit can be
- set on its own so set the requested servers to be
+ any other bit (they may just set this bit on its own) they
+ want all the locally seen servers. However this bit can be
+ set on its own so set the requested servers to be
ALL - DOMAIN_ENUM. */
if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM)) {
if (!prefix_ok(str1,"WrLehD")) {
return False;
}
- if (!check_server_info(uLevel,str2)) {
+ if (!check_session_info(uLevel,str2)) {
return False;
}
-
+
DEBUG(4, ("server request level: %s %8x ", str2, servertype));
DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
fstrcpy(domain, lp_workgroup());
}
+ DEBUG(4, ("domain [%s]\n", domain));
+
if (lp_browse_list()) {
- total = get_server_info(servertype,&servers,domain);
+ total = get_session_info(servertype,&servers,domain);
}
data_len = fixed_len = string_len = 0;
missed = 0;
- if (total > 0) {
- qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp);
- }
+ TYPESAFE_QSORT(servers, total, srv_comp);
{
char *lastname=NULL;
}
lastname = s->name;
data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
- DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
-
- if (data_len <= buf_len) {
+ DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n",
+ i, s->name, s->type, s->comment, s->domain));
+
+ if (data_len < buf_len) {
counted++;
fixed_len += f_len;
string_len += s_len;
if (!*rdata) {
return False;
}
-
+
p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
p = *rdata;
f_len = fixed_len;
}
lastname = s->name;
fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
- DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
+ DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n",
+ i, s->name, s->type, s->comment, s->domain));
count2--;
}
}
-
+
*rparam_len = 8;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
SAFE_FREE(servers);
- DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
+ DEBUG(3,("NetServerEnum2 domain = %s uLevel=%d counted=%d total=%d\n",
domain,uLevel,counted,counted+missed));
return True;
}
-/****************************************************************************
- command 0x34 - suspected of being a "Lookup Names" stub api
- ****************************************************************************/
+static int srv_name_match(const char *n1, const char *n2)
+{
+ /*
+ * [MS-RAP] footnote <88> for Section 3.2.5.15 says:
+ *
+ * In Windows, FirstNameToReturn need not be an exact match:
+ * the server will return a list of servers that exist on
+ * the network greater than or equal to the FirstNameToReturn.
+ */
+ int ret = StrCaseCmp(n1, n2);
+
+ if (ret <= 0) {
+ return 0;
+ }
+
+ return ret;
+}
-static bool api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid,
+static bool api_RNetServerEnum3(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
- int mdrcnt, int mprcnt, char **rdata,
+ int mdrcnt, int mprcnt, char **rdata,
char **rparam, int *rdata_len, int *rparam_len)
{
- char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
+ char *str1 = get_safe_str_ptr(param, tpscnt, param, 2);
char *str2 = skip_string(param,tpscnt,str1);
char *p = skip_string(param,tpscnt,str2);
- int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
- int buf_len = get_safe_SVAL(param,tpscnt,p,2,0);
- int counted=0;
- int missed=0;
+ int uLevel = get_safe_SVAL(param, tpscnt, p, 0, -1);
+ int buf_len = get_safe_SVAL(param,tpscnt, p, 2, 0);
+ uint32 servertype = get_safe_IVAL(param,tpscnt,p,4, 0);
+ char *p2;
+ int data_len, fixed_len, string_len;
+ int f_len = 0, s_len = 0;
+ struct srv_info_struct *servers=NULL;
+ int counted=0,first=0,total=0;
+ int i,missed;
+ fstring domain;
+ fstring first_name;
+ bool domain_request;
+ bool local_request;
if (!str1 || !str2 || !p) {
return False;
}
- DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
- str1, str2, p, uLevel, buf_len));
+ /* If someone sets all the bits they don't really mean to set
+ DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
+ known servers. */
- if (!prefix_ok(str1,"zWrLeh")) {
+ if (servertype == SV_TYPE_ALL) {
+ servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
+ }
+
+ /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
+ any other bit (they may just set this bit on its own) they
+ want all the locally seen servers. However this bit can be
+ set on its own so set the requested servers to be
+ ALL - DOMAIN_ENUM. */
+
+ if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM)) {
+ servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
+ }
+
+ domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
+ local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
+
+ p += 8;
+
+ if (strcmp(str1, "WrLehDzz") != 0) {
+ return false;
+ }
+ if (!check_session_info(uLevel,str2)) {
return False;
}
-
- *rdata_len = 0;
-
- *rparam_len = 8;
- *rparam = smb_realloc_limit(*rparam,*rparam_len);
- if (!*rparam) {
+
+ DEBUG(4, ("server request level: %s %8x ", str2, servertype));
+ DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
+ DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
+
+ if (skip_string(param,tpscnt,p) == NULL) {
+ return False;
+ }
+ pull_ascii_fstring(domain, p);
+ if (domain[0] == '\0') {
+ fstrcpy(domain, lp_workgroup());
+ }
+ p = skip_string(param,tpscnt,p);
+ if (skip_string(param,tpscnt,p) == NULL) {
return False;
}
+ pull_ascii_fstring(first_name, p);
- SSVAL(*rparam,0,0x08AC); /* informational warning message */
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,counted+missed);
+ DEBUG(4, ("domain: '%s' first_name: '%s'\n",
+ domain, first_name));
- return True;
-}
+ if (lp_browse_list()) {
+ total = get_session_info(servertype,&servers,domain);
+ }
-/****************************************************************************
- get info about a share
- ****************************************************************************/
+ data_len = fixed_len = string_len = 0;
+ missed = 0;
-static bool check_share_info(int uLevel, char* id)
-{
- switch( uLevel ) {
- case 0:
- if (strcmp(id,"B13") != 0) {
- return False;
+ TYPESAFE_QSORT(servers, total, srv_comp);
+
+ if (first_name[0] != '\0') {
+ struct srv_info_struct *first_server = NULL;
+
+ BINARY_ARRAY_SEARCH(servers, total, name, first_name,
+ srv_name_match, first_server);
+ if (first_server) {
+ first = PTR_DIFF(first_server, servers) / sizeof(*servers);
+ /*
+ * The binary search may not find the exact match
+ * so we need to search backward to find the first match
+ *
+ * This implements the strange matching windows
+ * implements. (see the comment in srv_name_match().
+ */
+ for (;first > 0;) {
+ int ret;
+ ret = StrCaseCmp(first_name,
+ servers[first-1].name);
+ if (ret > 0) {
+ break;
+ }
+ first--;
+ }
+ } else {
+ /* we should return no entries */
+ first = total;
+ }
+ }
+
+ {
+ char *lastname=NULL;
+
+ for (i=first;i<total;i++) {
+ struct srv_info_struct *s = &servers[i];
+
+ if (lastname && strequal(lastname,s->name)) {
+ continue;
+ }
+ lastname = s->name;
+ data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
+ DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n",
+ i, s->name, s->type, s->comment, s->domain));
+
+ if (data_len < buf_len) {
+ counted++;
+ fixed_len += f_len;
+ string_len += s_len;
+ } else {
+ missed++;
+ }
+ }
+ }
+
+ *rdata_len = fixed_len + string_len;
+ *rdata = smb_realloc_limit(*rdata,*rdata_len);
+ if (!*rdata) {
+ return False;
+ }
+
+ p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
+ p = *rdata;
+ f_len = fixed_len;
+ s_len = string_len;
+
+ {
+ char *lastname=NULL;
+ int count2 = counted;
+
+ for (i = first; i < total && count2;i++) {
+ struct srv_info_struct *s = &servers[i];
+
+ if (lastname && strequal(lastname,s->name)) {
+ continue;
+ }
+ lastname = s->name;
+ fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
+ DEBUG(4,("fill_srv_info[%d] %20s %8x %25s %15s\n",
+ i, s->name, s->type, s->comment, s->domain));
+ count2--;
+ }
+ }
+
+ *rparam_len = 8;
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
+ SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata));
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,counted);
+ SSVAL(*rparam,6,counted+missed);
+
+ DEBUG(3,("NetServerEnum3 domain = %s uLevel=%d first=%d[%s => %s] counted=%d total=%d\n",
+ domain,uLevel,first,first_name,
+ first < total ? servers[first].name : "",
+ counted,counted+missed));
+
+ SAFE_FREE(servers);
+
+ return True;
+}
+
+/****************************************************************************
+ command 0x34 - suspected of being a "Lookup Names" stub api
+ ****************************************************************************/
+
+static bool api_RNetGroupGetUsers(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
+ char *param, int tpscnt,
+ char *data, int tdscnt,
+ int mdrcnt, int mprcnt, char **rdata,
+ char **rparam, int *rdata_len, int *rparam_len)
+{
+ char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
+ char *str2 = skip_string(param,tpscnt,str1);
+ char *p = skip_string(param,tpscnt,str2);
+ int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
+ int buf_len = get_safe_SVAL(param,tpscnt,p,2,0);
+ int counted=0;
+ int missed=0;
+
+ if (!str1 || !str2 || !p) {
+ return False;
+ }
+
+ DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
+ str1, str2, p, uLevel, buf_len));
+
+ if (!prefix_ok(str1,"zWrLeh")) {
+ return False;
+ }
+
+ *rdata_len = 0;
+
+ *rparam_len = 8;
+ *rparam = smb_realloc_limit(*rparam,*rparam_len);
+ if (!*rparam) {
+ return False;
+ }
+
+ SSVAL(*rparam,0,0x08AC); /* informational warning message */
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,counted);
+ SSVAL(*rparam,6,counted+missed);
+
+ return True;
+}
+
+/****************************************************************************
+ get info about a share
+ ****************************************************************************/
+
+static bool check_share_info(int uLevel, char* id)
+{
+ switch( uLevel ) {
+ case 0:
+ if (strcmp(id,"B13") != 0) {
+ return False;
}
break;
case 1:
- if (strcmp(id,"B13BWz") != 0) {
+ /* Level-2 descriptor is allowed (and ignored) */
+ if (strcmp(id,"B13BWz") != 0 &&
+ strcmp(id,"B13BWzWWWzB9B") != 0) {
return False;
}
break;
char* p2;
int l2;
int len;
-
+
switch( uLevel ) {
case 0:
struct_len = 13;
default:
return -1;
}
-
-
+
if (!buf) {
len = 0;
}
return struct_len + len;
}
-
+
len = struct_len;
p = *buf;
if ((*buflen) < struct_len) {
if (!baseaddr) {
baseaddr = p;
}
-
+
push_ascii(p,lp_servicename(snum),13, STR_TERMINATE);
-
+
if (uLevel > 0) {
int type;
SIVAL(p,16,PTR_DIFF(p2,baseaddr));
len += CopyExpanded(conn,snum,&p2,lp_comment(snum),&l2);
}
-
+
if (uLevel > 1) {
SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE); /* permissions */
SSVALS(p,22,-1); /* max uses */
len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
memset(p+30,0,SHPWLEN+2); /* passwd (reserved), pad field */
}
-
+
if (uLevel > 2) {
memset(p+40,0,SHPWLEN+2);
SSVAL(p,50,0);
SSVAL(p,64,0);
SSVAL(p,66,0);
}
-
+
if (stringbuf) {
(*buf) = p + struct_len;
(*buflen) -= struct_len;
return len;
}
-static bool api_RNetShareGetInfo(connection_struct *conn,uint16 vuid,
+static bool api_RNetShareGetInfo(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
{
char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
char *str2 = skip_string(param,tpscnt,str1);
- char *netname = skip_string(param,tpscnt,str2);
+ char *netname_in = skip_string(param,tpscnt,str2);
+ char *netname = NULL;
char *p = skip_string(param,tpscnt,netname);
int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
int snum;
-
- if (!str1 || !str2 || !netname || !p) {
+
+ if (!str1 || !str2 || !netname_in || !p) {
return False;
}
- snum = find_service(netname);
- if (snum < 0) {
+ snum = find_service(talloc_tos(), netname_in, &netname);
+ if (snum < 0 || !netname) {
return False;
}
-
+
/* check it's a supported varient */
if (!prefix_ok(str1,"zWrLh")) {
return False;
if (!check_share_info(uLevel,str2)) {
return False;
}
-
+
*rdata = smb_realloc_limit(*rdata,mdrcnt);
if (!*rdata) {
return False;
if (*rdata_len < 0) {
return False;
}
-
+
*rparam_len = 6;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
SSVAL(*rparam,0,NERR_Success);
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len);
-
+
return True;
}
Share names longer than 12 bytes must be skipped.
****************************************************************************/
-static bool api_RNetShareEnum( connection_struct *conn, uint16 vuid,
+static bool api_RNetShareEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,
int i;
int data_len, fixed_len, string_len;
int f_len = 0, s_len = 0;
-
+
if (!str1 || !str2 || !p) {
return False;
}
if (!check_share_info(uLevel,str2)) {
return False;
}
-
+
/* Ensure all the usershares are loaded. */
become_root();
load_registry_shares();
if( lp_browseable( i ) && lp_snum_ok( i ) && (strlen(servicename_dos) < 13)) {
total++;
data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0);
- if (data_len <= buf_len) {
+ if (data_len < buf_len) {
counted++;
fixed_len += f_len;
string_len += s_len;
if (!*rdata) {
return False;
}
-
+
p2 = (*rdata) + fixed_len; /* auxiliary data (strings) will go here */
p = *rdata;
f_len = fixed_len;
}
}
}
-
+
*rparam_len = 8;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,counted);
SSVAL(*rparam,6,total);
-
+
DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
counted,total,uLevel,
buf_len,*rdata_len,mdrcnt));
Add a share
****************************************************************************/
-static bool api_RNetShareAdd(connection_struct *conn,uint16 vuid,
+static bool api_RNetShareAdd(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
fstring sharename;
fstring comment;
char *pathname = NULL;
- char *command, *cmdname;
unsigned int offset;
- int snum;
int res = ERRunsup;
size_t converted_size;
+ WERROR werr = WERR_OK;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ union srvsvc_NetShareInfo info;
+ struct srvsvc_NetShareInfo2 info2;
+ struct dcerpc_binding_handle *b;
+
if (!str1 || !str2 || !p) {
return False;
}
return False;
}
pull_ascii_fstring(sharename,data);
- snum = find_service(sharename);
- if (snum >= 0) { /* already exists */
- res = ERRfilexists;
- goto error_exit;
- }
if (mdrcnt < 28) {
return False;
offset = IVAL(data, 16);
if (offset >= mdrcnt) {
res = ERRinvalidparam;
- goto error_exit;
+ goto out;
}
/* Do we have a string ? */
if (offset >= mdrcnt) {
res = ERRinvalidparam;
- goto error_exit;
+ goto out;
}
/* Do we have a string ? */
return false;
}
- string_replace(sharename, '"', ' ');
- string_replace(pathname, '"', ' ');
- string_replace(comment, '"', ' ');
-
- cmdname = lp_add_share_cmd();
-
- if (!cmdname || *cmdname == '\0') {
- return False;
+ status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_RNetShareAdd: could not connect to srvsvc: %s\n",
+ nt_errstr(status)));
+ res = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
}
- if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_add_share_cmd(), get_dyn_CONFIGFILE(), sharename,
- pathname, comment) == -1) {
- return false;
- }
+ b = cli->binding_handle;
- DEBUG(10,("api_RNetShareAdd: Running [%s]\n", command ));
+ info2.name = sharename;
+ info2.type = STYPE_DISKTREE;
+ info2.comment = comment;
+ info2.permissions = 0;
+ info2.max_users = 0;
+ info2.current_users = 0;
+ info2.path = pathname;
+ info2.password = NULL;
- if ((res = smbrun(command, NULL)) != 0) {
- DEBUG(1,("api_RNetShareAdd: Running [%s] returned (%d)\n",
- command, res ));
- SAFE_FREE(command);
- res = ERRnoaccess;
- goto error_exit;
- } else {
- SAFE_FREE(command);
- message_send_all(smbd_messaging_context(),
- MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
+ info.info2 = &info2;
+
+ status = dcerpc_srvsvc_NetShareAdd(b, mem_ctx,
+ cli->srv_name_slash,
+ 2,
+ &info,
+ NULL,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ res = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ res = W_ERROR_V(werr);
+ goto out;
}
*rparam_len = 6;
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len);
*rdata_len = 0;
-
+
return True;
- error_exit:
+ out:
*rparam_len = 4;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
view list of groups available
****************************************************************************/
-static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
+static bool api_RNetGroupEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *str2 = skip_string(param,tpscnt,str1);
char *p = skip_string(param,tpscnt,str2);
- struct pdb_search *search;
- struct samr_displayentry *entries;
+ uint32_t num_groups;
+ uint32_t resume_handle;
+ struct rpc_pipe_client *samr_pipe;
+ struct policy_handle samr_handle, domain_handle;
+ NTSTATUS status, result;
+ struct dcerpc_binding_handle *b;
- int num_entries;
-
if (!str1 || !str2 || !p) {
return False;
}
return False;
}
- /* parameters
+ /* parameters
* W-> resume context (number of users to skip)
- * r -> return parameter pointer to receive buffer
+ * r -> return parameter pointer to receive buffer
* L -> length of receive buffer
* e -> return parameter number of entries
* h -> return parameter total number of users
return False;
}
- /* get list of domain groups SID_DOMAIN_GRP=2 */
- become_root();
- search = pdb_search_groups();
- unbecome_root();
+ status = rpc_pipe_open_internal(
+ talloc_tos(), &ndr_table_samr.syntax_id,
+ conn->session_info, &conn->sconn->client_id,
+ conn->sconn->msg_ctx, &samr_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
+ nt_errstr(status)));
+ return false;
+ }
- if (search == NULL) {
- DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
- return False;
+ b = samr_pipe->binding_handle;
+
+ status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+ SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+ nt_errstr(status)));
+ return false;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+ nt_errstr(result)));
+ return false;
+ }
+
+ status = dcerpc_samr_OpenDomain(b, talloc_tos(), &samr_handle,
+ SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
+ get_global_sam_sid(), &domain_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+ nt_errstr(status)));
+ dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
+ return false;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+ nt_errstr(result)));
+ dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
+ return false;
}
resume_context = get_safe_SVAL(param,tpscnt,p,0,-1);
DEBUG(10,("api_RNetGroupEnum:resume context: %d, client buffer size: "
"%d\n", resume_context, cli_buf_size));
- become_root();
- num_entries = pdb_search_entries(search, resume_context, 0xffffffff,
- &entries);
- unbecome_root();
-
*rdata_len = cli_buf_size;
*rdata = smb_realloc_limit(*rdata,*rdata_len);
if (!*rdata) {
p = *rdata;
- for(i=0; i<num_entries; i++) {
- fstring name;
- fstrcpy(name, entries[i].account_name);
- if( ((PTR_DIFF(p,*rdata)+21) <= *rdata_len) ) {
+ errflags = NERR_Success;
+ num_groups = 0;
+ resume_handle = 0;
+
+ while (true) {
+ struct samr_SamArray *sam_entries;
+ uint32_t num_entries;
+
+ status = dcerpc_samr_EnumDomainGroups(b, talloc_tos(),
+ &domain_handle,
+ &resume_handle,
+ &sam_entries, 1,
+ &num_entries,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("dcerpc_samr_EnumDomainGroups returned "
+ "%s\n", nt_errstr(status)));
+ break;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ status = result;
+ DEBUG(10, ("dcerpc_samr_EnumDomainGroups returned "
+ "%s\n", nt_errstr(result)));
+ break;
+ }
+
+ if (num_entries == 0) {
+ DEBUG(10, ("dcerpc_samr_EnumDomainGroups returned "
+ "no entries -- done\n"));
+ break;
+ }
+
+ for(i=0; i<num_entries; i++) {
+ const char *name;
+
+ name = sam_entries->entries[i].name.string;
+
+ if( ((PTR_DIFF(p,*rdata)+21) > *rdata_len) ) {
+ /* set overflow error */
+ DEBUG(3,("overflow on entry %d group %s\n", i,
+ name));
+ errflags=234;
+ break;
+ }
+
/* truncate the name at 21 chars. */
- memcpy(p, name, 21);
+ memset(p, 0, 21);
+ strlcpy(p, name, 21);
DEBUG(10,("adding entry %d group %s\n", i, p));
p += 21;
- p += 5; /* Both NT4 and W2k3SP1 do padding here.
- No idea why... */
- } else {
- /* set overflow error */
- DEBUG(3,("overflow on entry %d group %s\n", i, name));
- errflags=234;
+ p += 5; /* Both NT4 and W2k3SP1 do padding here. No
+ * idea why... */
+ num_groups += 1;
+ }
+
+ if (errflags != NERR_Success) {
break;
}
+
+ TALLOC_FREE(sam_entries);
}
- pdb_search_destroy(search);
+ dcerpc_samr_Close(b, talloc_tos(), &domain_handle, &result);
+ dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
*rdata_len = PTR_DIFF(p,*rdata);
}
SSVAL(*rparam, 0, errflags);
SSVAL(*rparam, 2, 0); /* converter word */
- SSVAL(*rparam, 4, i); /* is this right?? */
- SSVAL(*rparam, 6, resume_context+num_entries); /* is this right?? */
+ SSVAL(*rparam, 4, num_groups); /* is this right?? */
+ SSVAL(*rparam, 6, resume_context+num_groups); /* is this right?? */
return(True);
}
Get groups that a user is a member of.
******************************************************************/
-static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
+static bool api_NetUserGetGroups(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
const char *level_string;
int count=0;
- struct samu *sampw = NULL;
bool ret = False;
- DOM_SID *sids;
- gid_t *gids;
- size_t num_groups;
- size_t i;
- NTSTATUS result;
- DOM_SID user_sid;
- enum lsa_SidType type;
+ uint32_t i;
char *endp = NULL;
- TALLOC_CTX *mem_ctx;
+
+ struct rpc_pipe_client *samr_pipe;
+ struct policy_handle samr_handle, domain_handle, user_handle;
+ struct lsa_String name;
+ struct lsa_Strings names;
+ struct samr_Ids type, rid;
+ struct samr_RidWithAttributeArray *rids;
+ NTSTATUS status, result;
+ struct dcerpc_binding_handle *b;
if (!str1 || !str2 || !UserName || !p) {
return False;
p = *rdata;
endp = *rdata + *rdata_len;
- mem_ctx = talloc_new(NULL);
- if (mem_ctx == NULL) {
- DEBUG(0, ("talloc_new failed\n"));
- return False;
+ status = rpc_pipe_open_internal(
+ talloc_tos(), &ndr_table_samr.syntax_id,
+ conn->session_info, &conn->sconn->client_id,
+ conn->sconn->msg_ctx, &samr_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
+ nt_errstr(status)));
+ return false;
}
- if ( !(sampw = samu_new(mem_ctx)) ) {
- DEBUG(0, ("samu_new() failed!\n"));
- TALLOC_FREE(mem_ctx);
- return False;
+ b = samr_pipe->binding_handle;
+
+ status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+ SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+ nt_errstr(status)));
+ return false;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+ nt_errstr(result)));
+ return false;
}
- /* Lookup the user information; This should only be one of
- our accounts (not remote domains) */
+ status = dcerpc_samr_OpenDomain(b, talloc_tos(), &samr_handle,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+ get_global_sam_sid(), &domain_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+ nt_errstr(status)));
+ goto close_sam;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+ nt_errstr(result)));
+ goto close_sam;
+ }
- become_root(); /* ROOT BLOCK */
+ name.string = UserName;
- if (!lookup_name(mem_ctx, UserName, LOOKUP_NAME_ALL,
- NULL, NULL, &user_sid, &type)) {
- DEBUG(10, ("lookup_name(%s) failed\n", UserName));
- goto done;
+ status = dcerpc_samr_LookupNames(b, talloc_tos(),
+ &domain_handle, 1, &name,
+ &rid, &type,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+ nt_errstr(status)));
+ goto close_domain;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+ nt_errstr(result)));
+ goto close_domain;
}
- if (type != SID_NAME_USER) {
+ if (type.ids[0] != SID_NAME_USER) {
DEBUG(10, ("%s is a %s, not a user\n", UserName,
- sid_type_lookup(type)));
- goto done;
+ sid_type_lookup(type.ids[0])));
+ goto close_domain;
}
- if ( !pdb_getsampwsid(sampw, &user_sid) ) {
- DEBUG(10, ("pdb_getsampwsid(%s) failed for user %s\n",
- sid_string_dbg(&user_sid), UserName));
- goto done;
+ status = dcerpc_samr_OpenUser(b, talloc_tos(),
+ &domain_handle,
+ SAMR_USER_ACCESS_GET_GROUPS,
+ rid.ids[0], &user_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+ nt_errstr(status)));
+ goto close_domain;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+ nt_errstr(result)));
+ goto close_domain;
}
- gids = NULL;
- sids = NULL;
- num_groups = 0;
-
- result = pdb_enum_group_memberships(mem_ctx, sampw,
- &sids, &gids, &num_groups);
-
+ status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
+ &user_handle, &rids,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+ nt_errstr(status)));
+ goto close_user;
+ }
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
- UserName));
- goto done;
+ DEBUG(0, ("api_RNetUserEnum: samr_LookupNames failed: %s\n",
+ nt_errstr(result)));
+ goto close_user;
}
- for (i=0; i<num_groups; i++) {
- const char *grp_name;
+ for (i=0; i<rids->count; i++) {
- if ( lookup_sid(mem_ctx, &sids[i], NULL, &grp_name, NULL) ) {
- strlcpy(p, grp_name, PTR_DIFF(endp,p));
+ status = dcerpc_samr_LookupRids(b, talloc_tos(),
+ &domain_handle,
+ 1, &rids->rids[i].rid,
+ &names, &type,
+ &result);
+ if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result) && (names.count == 1)) {
+ strlcpy(p, names.names[0].string, PTR_DIFF(endp,p));
p += 21;
count++;
}
ret = True;
-done:
- unbecome_root(); /* END ROOT BLOCK */
-
- TALLOC_FREE(mem_ctx);
+ close_user:
+ dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
+ close_domain:
+ dcerpc_samr_Close(b, talloc_tos(), &domain_handle, &result);
+ close_sam:
+ dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
return ret;
}
Get all users.
******************************************************************/
-static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
+static bool api_RNetUserEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
int num_users=0;
int errflags=0;
int i, resume_context, cli_buf_size;
- struct pdb_search *search;
- struct samr_displayentry *users;
+ uint32_t resume_handle;
+
+ struct rpc_pipe_client *samr_pipe;
+ struct policy_handle samr_handle, domain_handle;
+ NTSTATUS status, result;
char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
char *str2 = skip_string(param,tpscnt,str1);
char *p = skip_string(param,tpscnt,str2);
char *endp = NULL;
+ struct dcerpc_binding_handle *b;
+
if (!str1 || !str2 || !p) {
return False;
}
p = *rdata;
endp = *rdata + *rdata_len;
- become_root();
- search = pdb_search_users(ACB_NORMAL);
- unbecome_root();
- if (search == NULL) {
- DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
- return False;
+ status = rpc_pipe_open_internal(
+ talloc_tos(), &ndr_table_samr.syntax_id,
+ conn->session_info, &conn->sconn->client_id,
+ conn->sconn->msg_ctx, &samr_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
+ nt_errstr(status)));
+ return false;
}
- become_root();
- num_users = pdb_search_entries(search, resume_context, 0xffffffff,
- &users);
- unbecome_root();
+ b = samr_pipe->binding_handle;
+
+ status = dcerpc_samr_Connect2(b, talloc_tos(), global_myname(),
+ SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+ nt_errstr(status)));
+ return false;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
+ nt_errstr(result)));
+ return false;
+ }
+
+ status = dcerpc_samr_OpenDomain(b, talloc_tos(), &samr_handle,
+ SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
+ get_global_sam_sid(), &domain_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+ nt_errstr(status)));
+ dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
+ return false;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("api_RNetUserEnum: samr_OpenDomain failed: %s\n",
+ nt_errstr(result)));
+ dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
+ return false;
+ }
errflags=NERR_Success;
- for (i=0; i<num_users; i++) {
- const char *name = users[i].account_name;
+ resume_handle = 0;
- if(((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21)) {
- strlcpy(p,name,PTR_DIFF(endp,p));
- DEBUG(10,("api_RNetUserEnum:adding entry %d username "
- "%s\n",count_sent,p));
- p += 21;
- count_sent++;
- } else {
- /* set overflow error */
- DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
- "username %s\n",count_sent,name));
- errflags=234;
+ while (true) {
+ struct samr_SamArray *sam_entries;
+ uint32_t num_entries;
+
+ status = dcerpc_samr_EnumDomainUsers(b, talloc_tos(),
+ &domain_handle,
+ &resume_handle,
+ 0, &sam_entries, 1,
+ &num_entries,
+ &result);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("dcerpc_samr_EnumDomainUsers returned "
+ "%s\n", nt_errstr(status)));
+ break;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10, ("dcerpc_samr_EnumDomainUsers returned "
+ "%s\n", nt_errstr(result)));
+ break;
+ }
+
+ if (num_entries == 0) {
+ DEBUG(10, ("dcerpc_samr_EnumDomainUsers returned "
+ "no entries -- done\n"));
+ break;
+ }
+
+ for (i=0; i<num_entries; i++) {
+ const char *name;
+
+ name = sam_entries->entries[i].name.string;
+
+ if(((PTR_DIFF(p,*rdata)+21)<=*rdata_len)
+ &&(strlen(name)<=21)) {
+ strlcpy(p,name,PTR_DIFF(endp,p));
+ DEBUG(10,("api_RNetUserEnum:adding entry %d "
+ "username %s\n",count_sent,p));
+ p += 21;
+ count_sent++;
+ } else {
+ /* set overflow error */
+ DEBUG(10,("api_RNetUserEnum:overflow on entry %d "
+ "username %s\n",count_sent,name));
+ errflags=234;
+ break;
+ }
+ }
+
+ if (errflags != NERR_Success) {
break;
}
+
+ TALLOC_FREE(sam_entries);
}
- pdb_search_destroy(search);
+ dcerpc_samr_Close(b, talloc_tos(), &domain_handle, &result);
+ dcerpc_samr_Close(b, talloc_tos(), &samr_handle, &result);
*rdata_len = PTR_DIFF(p,*rdata);
Get the time of day info.
****************************************************************************/
-static bool api_NetRemoteTOD(connection_struct *conn,uint16 vuid,
+static bool api_NetRemoteTOD(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
by NT in a "net time" operation,
it seems to ignore the one below */
- /* the client expects to get localtime, not GMT, in this bit
+ /* the client expects to get localtime, not GMT, in this bit
(I think, this needs testing) */
t = localtime(&unixdate);
if (!t) {
Set the user password.
*****************************************************************************/
-static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
+static bool api_SetUserPassword(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *p = NULL;
fstring user;
fstring pass1,pass2;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ NTSTATUS status, result;
+ struct rpc_pipe_client *cli = NULL;
+ struct policy_handle connect_handle, domain_handle, user_handle;
+ struct lsa_String domain_name;
+ struct dom_sid2 *domain_sid;
+ struct lsa_String names;
+ struct samr_Ids rids;
+ struct samr_Ids types;
+ struct samr_Password old_lm_hash;
+ struct samr_Password new_lm_hash;
+ int errcode = NERR_badpass;
+ uint32_t rid;
+ int encrypted;
+ int min_pwd_length;
+ struct dcerpc_binding_handle *b = NULL;
/* Skip 2 strings. */
p = skip_string(param,tpscnt,np);
memcpy(pass1,p,16);
memcpy(pass2,p+16,16);
+ encrypted = get_safe_SVAL(param,tpscnt,p+32,0,-1);
+ if (encrypted == -1) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
+
+ min_pwd_length = get_safe_SVAL(param,tpscnt,p+34,0,-1);
+ if (min_pwd_length == -1) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
+
*rparam_len = 4;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
*rdata_len = 0;
- SSVAL(*rparam,0,NERR_badpass);
- SSVAL(*rparam,2,0); /* converter word */
+ DEBUG(3,("Set password for <%s> (encrypted: %d, min_pwd_length: %d)\n",
+ user, encrypted, min_pwd_length));
+
+ ZERO_STRUCT(connect_handle);
+ ZERO_STRUCT(domain_handle);
+ ZERO_STRUCT(user_handle);
+
+ status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n",
+ nt_errstr(status)));
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
- DEBUG(3,("Set password for <%s>\n",user));
+ b = cli->binding_handle;
- /*
- * Attempt to verify the old password against smbpasswd entries
- * Win98 clients send old and new password in plaintext for this call.
- */
+ status = dcerpc_samr_Connect2(b, mem_ctx,
+ global_myname(),
+ SAMR_ACCESS_CONNECT_TO_SERVER |
+ SAMR_ACCESS_ENUM_DOMAINS |
+ SAMR_ACCESS_LOOKUP_DOMAIN,
+ &connect_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
- {
- auth_serversupplied_info *server_info = NULL;
- DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
+ init_lsa_String(&domain_name, get_global_sam_name());
- if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
+ status = dcerpc_samr_LookupDomain(b, mem_ctx,
+ &connect_handle,
+ &domain_name,
+ &domain_sid,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
- become_root();
- if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2, False, NULL))) {
- SSVAL(*rparam,0,NERR_Success);
- }
- unbecome_root();
+ status = dcerpc_samr_OpenDomain(b, mem_ctx,
+ &connect_handle,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+ domain_sid,
+ &domain_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
- TALLOC_FREE(server_info);
- }
- data_blob_clear_free(&password);
+ init_lsa_String(&names, user);
+
+ status = dcerpc_samr_LookupNames(b, mem_ctx,
+ &domain_handle,
+ 1,
+ &names,
+ &rids,
+ &types,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
}
- /*
- * If the plaintext change failed, attempt
- * the old encrypted method. NT will generate this
- * after trying the samr method. Note that this
- * method is done as a last resort as this
- * password change method loses the NT password hash
- * and cannot change the UNIX password as no plaintext
- * is received.
- */
+ if (rids.count != 1) {
+ errcode = W_ERROR_V(WERR_NO_SUCH_USER);
+ goto out;
+ }
+ if (rids.count != types.count) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
+ if (types.ids[0] != SID_NAME_USER) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
- if(SVAL(*rparam,0) != NERR_Success) {
- struct samu *hnd = NULL;
+ rid = rids.ids[0];
- if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) {
- become_root();
- if (change_lanman_password(hnd,(uchar *)pass2)) {
- SSVAL(*rparam,0,NERR_Success);
- }
- unbecome_root();
- TALLOC_FREE(hnd);
- }
+ status = dcerpc_samr_OpenUser(b, mem_ctx,
+ &domain_handle,
+ SAMR_USER_ACCESS_CHANGE_PASSWORD,
+ rid,
+ &user_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
+ if (encrypted == 0) {
+ E_deshash(pass1, old_lm_hash.hash);
+ E_deshash(pass2, new_lm_hash.hash);
+ } else {
+ ZERO_STRUCT(old_lm_hash);
+ ZERO_STRUCT(new_lm_hash);
+ memcpy(old_lm_hash.hash, pass1, MIN(strlen(pass1), 16));
+ memcpy(new_lm_hash.hash, pass1, MIN(strlen(pass2), 16));
+ }
+
+ status = dcerpc_samr_ChangePasswordUser(b, mem_ctx,
+ &user_handle,
+ true, /* lm_present */
+ &old_lm_hash,
+ &new_lm_hash,
+ false, /* nt_present */
+ NULL, /* old_nt_crypted */
+ NULL, /* new_nt_crypted */
+ false, /* cross1_present */
+ NULL, /* nt_cross */
+ false, /* cross2_present */
+ NULL, /* lm_cross */
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
+ errcode = NERR_Success;
+ out:
+
+ if (b && is_valid_policy_hnd(&user_handle)) {
+ dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
+ }
+ if (b && is_valid_policy_hnd(&domain_handle)) {
+ dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
+ }
+ if (b && is_valid_policy_hnd(&connect_handle)) {
+ dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
}
memset((char *)pass1,'\0',sizeof(fstring));
- memset((char *)pass2,'\0',sizeof(fstring));
-
+ memset((char *)pass2,'\0',sizeof(fstring));
+
+ SSVAL(*rparam,0,errcode);
+ SSVAL(*rparam,2,0); /* converter word */
return(True);
}
Set the user password (SamOEM version - gets plaintext).
****************************************************************************/
-static bool api_SamOEMChangePassword(connection_struct *conn,uint16 vuid,
+static bool api_SamOEMChangePassword(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
{
fstring user;
char *p = get_safe_str_ptr(param,tpscnt,param,2);
- *rparam_len = 2;
+
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ NTSTATUS status, result;
+ struct rpc_pipe_client *cli = NULL;
+ struct lsa_AsciiString server, account;
+ struct samr_CryptPassword password;
+ struct samr_Password hash;
+ int errcode = NERR_badpass;
+ int bufsize;
+ struct dcerpc_binding_handle *b;
+
+ *rparam_len = 4;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
return False;
DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
+ if (tdscnt != 532) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
- (void)map_username(user);
+ bufsize = get_safe_SVAL(param,tpscnt,p,0,-1);
+ if (bufsize != 532) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
+
+ memcpy(password.data, data, 516);
+ memcpy(hash.hash, data+516, 16);
- if (NT_STATUS_IS_OK(pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL, NULL))) {
- SSVAL(*rparam,0,NERR_Success);
+ status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_SamOEMChangePassword: could not connect to samr: %s\n",
+ nt_errstr(status)));
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
}
+ b = cli->binding_handle;
+
+ init_lsa_AsciiString(&server, global_myname());
+ init_lsa_AsciiString(&account, user);
+
+ status = dcerpc_samr_OemChangePasswordUser2(b, mem_ctx,
+ &server,
+ &account,
+ &password,
+ &hash,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
+ errcode = NERR_Success;
+ out:
+ SSVAL(*rparam,0,errcode);
+ SSVAL(*rparam,2,0); /* converter word */
+
return(True);
}
/****************************************************************************
delete a print job
- Form: <W> <>
+ Form: <W> <>
****************************************************************************/
-static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
+static bool api_RDosPrintJobDel(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *str2 = skip_string(param,tpscnt,str1);
char *p = skip_string(param,tpscnt,str2);
uint32 jobid;
- int snum;
fstring sharename;
int errcode;
WERROR werr = WERR_OK;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct policy_handle handle;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ enum spoolss_JobControl command;
+
if (!str1 || !str2 || !p) {
return False;
}
}
*rdata_len = 0;
- if (!print_job_exists(sharename, jobid)) {
- errcode = NERR_JobNotFound;
+ ZERO_STRUCT(handle);
+
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_RDosPrintJobDel: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
goto out;
}
+ b = cli->binding_handle;
+
+ ZERO_STRUCT(devmode_ctr);
- snum = lp_servicenumber( sharename);
- if (snum == -1) {
- errcode = NERR_DestNotFound;
+ status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
+ sharename,
+ "RAW",
+ devmode_ctr,
+ JOB_ACCESS_ADMINISTER,
+ &handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ errcode = W_ERROR_V(werr);
goto out;
}
- errcode = NERR_notsupported;
-
+ /* FIXME: formerly NERR_JobNotFound was returned if job did not exist
+ * and NERR_DestNotFound if share did not exist */
+
+ errcode = NERR_Success;
+
switch (function) {
- case 81: /* delete */
- if (print_job_delete(¤t_user, snum, jobid, &werr))
- errcode = NERR_Success;
+ case 81: /* delete */
+ command = SPOOLSS_JOB_CONTROL_DELETE;
break;
case 82: /* pause */
- if (print_job_pause(¤t_user, snum, jobid, &werr))
- errcode = NERR_Success;
+ command = SPOOLSS_JOB_CONTROL_PAUSE;
break;
case 83: /* resume */
- if (print_job_resume(¤t_user, snum, jobid, &werr))
- errcode = NERR_Success;
+ command = SPOOLSS_JOB_CONTROL_RESUME;
break;
+ default:
+ errcode = NERR_notsupported;
+ goto out;
}
- if (!W_ERROR_IS_OK(werr))
+ status = dcerpc_spoolss_SetJob(b, mem_ctx,
+ &handle,
+ jobid,
+ NULL, /* unique ptr ctr */
+ command,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
errcode = W_ERROR_V(werr);
-
+ goto out;
+ }
+
out:
- SSVAL(*rparam,0,errcode);
+ if (b && is_valid_policy_hnd(&handle)) {
+ dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
+ }
+
+ SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
return(True);
Purge a print queue - or pause or resume it.
****************************************************************************/
-static bool api_WPrintQueueCtrl(connection_struct *conn,uint16 vuid,
+static bool api_WPrintQueueCtrl(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *str2 = skip_string(param,tpscnt,str1);
char *QueueName = skip_string(param,tpscnt,str2);
int errcode = NERR_notsupported;
- int snum;
WERROR werr = WERR_OK;
+ NTSTATUS status;
+
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct policy_handle handle;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+ enum spoolss_PrinterControl command;
if (!str1 || !str2 || !QueueName) {
return False;
if (skip_string(param,tpscnt,QueueName) == NULL) {
return False;
}
- snum = print_queue_snum(QueueName);
- if (snum == -1) {
- errcode = NERR_JobNotFound;
+ ZERO_STRUCT(handle);
+
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_WPrintQueueCtrl: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ b = cli->binding_handle;
+
+ ZERO_STRUCT(devmode_ctr);
+
+ status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
+ QueueName,
+ NULL,
+ devmode_ctr,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ errcode = W_ERROR_V(werr);
goto out;
}
switch (function) {
case 74: /* Pause queue */
- if (print_queue_pause(¤t_user, snum, &werr)) errcode = NERR_Success;
+ command = SPOOLSS_PRINTER_CONTROL_PAUSE;
break;
case 75: /* Resume queue */
- if (print_queue_resume(¤t_user, snum, &werr)) errcode = NERR_Success;
+ command = SPOOLSS_PRINTER_CONTROL_RESUME;
break;
case 103: /* Purge */
- if (print_queue_purge(¤t_user, snum, &werr)) errcode = NERR_Success;
+ command = SPOOLSS_PRINTER_CONTROL_PURGE;
break;
+ default:
+ werr = WERR_NOT_SUPPORTED;
+ break;
+ }
+
+ if (!W_ERROR_IS_OK(werr)) {
+ errcode = W_ERROR_V(werr);
+ goto out;
}
- if (!W_ERROR_IS_OK(werr)) errcode = W_ERROR_V(werr);
+ ZERO_STRUCT(info_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+
+ status = dcerpc_spoolss_SetPrinter(b, mem_ctx,
+ &handle,
+ &info_ctr,
+ &devmode_ctr,
+ &secdesc_ctr,
+ command,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ errcode = W_ERROR_V(werr);
out:
+
+ if (b && is_valid_policy_hnd(&handle)) {
+ dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
+ }
+
SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
set the property of a print job (undocumented?)
? function = 0xb -> set name of print job
? function = 0x6 -> move print job up/down
- Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
- or <WWsTP> <WB21BB16B10zWWzDDz>
+ Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
+ or <WWsTP> <WB21BB16B10zWWzDDz>
****************************************************************************/
static int check_printjob_info(struct pack_desc* desc,
return True;
}
-static bool api_PrintJobInfo(connection_struct *conn, uint16 vuid,
+static bool api_PrintJobInfo(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
fstring sharename;
int uLevel = get_safe_SVAL(param,tpscnt,p,2,-1);
int function = get_safe_SVAL(param,tpscnt,p,4,-1);
- int place, errcode;
+ int errcode;
+
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ WERROR werr;
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct policy_handle handle;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct spoolss_JobInfoContainer ctr;
+ union spoolss_JobInfo info;
+ struct spoolss_SetJobInfo1 info1;
if (!str1 || !str2 || !p) {
return False;
return False;
}
- if (!share_defined(sharename)) {
- DEBUG(0,("api_PrintJobInfo: sharen [%s] not defined\n",
- sharename));
- return False;
+ *rdata_len = 0;
+
+ /* check it's a supported varient */
+ if ((strcmp(str1,"WWsTP")) ||
+ (!check_printjob_info(&desc,uLevel,str2)))
+ return(False);
+
+ errcode = NERR_notsupported;
+
+ switch (function) {
+ case 0xb:
+ /* change print job name, data gives the name */
+ break;
+ default:
+ goto out;
}
-
- *rdata_len = 0;
-
- /* check it's a supported varient */
- if ((strcmp(str1,"WWsTP")) ||
- (!check_printjob_info(&desc,uLevel,str2)))
- return(False);
- if (!print_job_exists(sharename, jobid)) {
- errcode=NERR_JobNotFound;
+ ZERO_STRUCT(handle);
+
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_PrintJobInfo: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
goto out;
}
+ b = cli->binding_handle;
- errcode = NERR_notsupported;
+ ZERO_STRUCT(devmode_ctr);
- switch (function) {
- case 0x6:
- /* change job place in the queue,
- data gives the new place */
- place = SVAL(data,0);
- if (print_job_set_place(sharename, jobid, place)) {
- errcode=NERR_Success;
- }
- break;
+ status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
+ sharename,
+ "RAW",
+ devmode_ctr,
+ PRINTER_ACCESS_USE,
+ &handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ errcode = W_ERROR_V(werr);
+ goto out;
+ }
- case 0xb:
- /* change print job name, data gives the name */
- if (print_job_set_name(sharename, jobid, data)) {
- errcode=NERR_Success;
- }
- break;
+ werr = rpccli_spoolss_getjob(cli, mem_ctx,
+ &handle,
+ jobid,
+ 1, /* level */
+ 0, /* offered */
+ &info);
+ if (!W_ERROR_IS_OK(werr)) {
+ errcode = W_ERROR_V(werr);
+ goto out;
+ }
- default:
- return False;
+ ZERO_STRUCT(ctr);
+
+ info1.job_id = info.info1.job_id;
+ info1.printer_name = info.info1.printer_name;
+ info1.user_name = info.info1.user_name;
+ info1.document_name = data;
+ info1.data_type = info.info1.data_type;
+ info1.text_status = info.info1.text_status;
+ info1.status = info.info1.status;
+ info1.priority = info.info1.priority;
+ info1.position = info.info1.position;
+ info1.total_pages = info.info1.total_pages;
+ info1.pages_printed = info.info1.pages_printed;
+ info1.submitted = info.info1.submitted;
+
+ ctr.level = 1;
+ ctr.info.info1 = &info1;
+
+ status = dcerpc_spoolss_SetJob(b, mem_ctx,
+ &handle,
+ jobid,
+ &ctr,
+ 0,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ errcode = W_ERROR_V(werr);
+ goto out;
}
+ errcode = NERR_Success;
out:
+
+ if (b && is_valid_policy_hnd(&handle)) {
+ dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
+ }
+
SSVALS(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
-
+
return(True);
}
Get info about the server.
****************************************************************************/
-static bool api_RNetServerGetInfo(connection_struct *conn,uint16 vuid,
+static bool api_RNetServerGetInfo(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *p2;
int struct_len;
+ NTSTATUS status;
+ WERROR werr;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ struct rpc_pipe_client *cli = NULL;
+ union srvsvc_NetSrvInfo info;
+ int errcode;
+ struct dcerpc_binding_handle *b;
+
if (!str1 || !str2 || !p) {
return False;
}
p = *rdata;
p2 = p + struct_len;
+
+ status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_RNetServerGetInfo: could not connect to srvsvc: %s\n",
+ nt_errstr(status)));
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+
+ b = cli->binding_handle;
+
+ status = dcerpc_srvsvc_NetSrvGetInfo(b, mem_ctx,
+ NULL,
+ 101,
+ &info,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ if (info.info101 == NULL) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
+
if (uLevel != 20) {
- srvstr_push(NULL, 0, p,global_myname(),16,
+ srvstr_push(NULL, 0, p, info.info101->server_name, 16,
STR_ASCII|STR_UPPER|STR_TERMINATE);
}
p += 16;
if (uLevel > 0) {
- struct srv_info_struct *servers=NULL;
- int i,count;
- char *comment = NULL;
- TALLOC_CTX *ctx = talloc_tos();
- uint32 servertype= lp_default_server_announce();
-
- comment = talloc_strdup(ctx,lp_serverstring());
- if (!comment) {
- return false;
- }
-
- if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
- for (i=0;i<count;i++) {
- if (strequal(servers[i].name,global_myname())) {
- servertype = servers[i].type;
- TALLOC_FREE(comment);
- comment = talloc_strdup(ctx,
- servers[i].comment);
- if (comment) {
- return false;
- }
- }
- }
- }
-
- SAFE_FREE(servers);
-
- SCVAL(p,0,lp_major_announce_version());
- SCVAL(p,1,lp_minor_announce_version());
- SIVAL(p,2,servertype);
+ SCVAL(p,0,info.info101->version_major);
+ SCVAL(p,1,info.info101->version_minor);
+ SIVAL(p,2,info.info101->server_type);
if (mdrcnt == struct_len) {
SIVAL(p,6,0);
} else {
SIVAL(p,6,PTR_DIFF(p2,*rdata));
- comment = talloc_sub_advanced(ctx,
- lp_servicename(SNUM(conn)),
- conn->server_info->unix_name,
- conn->connectpath,
- conn->server_info->gid,
- get_current_username(),
- current_user_info.domain,
- comment);
- if (comment) {
- return false;
- }
if (mdrcnt - struct_len <= 0) {
return false;
}
push_ascii(p2,
- comment,
+ info.info101->comment,
MIN(mdrcnt - struct_len,
MAX_SERVER_STRING_LENGTH),
STR_TERMINATE);
return False; /* not yet implemented */
}
+ errcode = NERR_Success;
+
+ out:
+
*rdata_len = PTR_DIFF(p2,*rdata);
*rparam_len = 6;
if (!*rparam) {
return False;
}
- SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len);
Get info about the server.
****************************************************************************/
-static bool api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid,
+static bool api_NetWkstaGetInfo(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
p += 4;
SIVAL(p,0,PTR_DIFF(p2,*rdata));
- strlcpy(p2,current_user_info.smb_name,PTR_DIFF(endp,p2));
+ strlcpy(p2,conn->session_info->sanitized_username,PTR_DIFF(endp,p2));
p2 = skip_string(*rdata,*rdata_len,p2);
if (!p2) {
return False;
get info about a user
struct user_info_11 {
- char usri11_name[21]; 0-20
- char usri11_pad; 21
- char *usri11_comment; 22-25
+ char usri11_name[21]; 0-20
+ char usri11_pad; 21
+ char *usri11_comment; 22-25
char *usri11_usr_comment; 26-29
unsigned short usri11_priv; 30-31
unsigned long usri11_auth_flags; 32-35
****************************************************************************/
-#define usri11_name 0
+#define usri11_name 0
#define usri11_pad 21
#define usri11_comment 22
#define usri11_usr_comment 26
#define usri11_code_page 84
#define usri11_end 86
-#define USER_PRIV_GUEST 0
-#define USER_PRIV_USER 1
-#define USER_PRIV_ADMIN 2
-
-#define AF_OP_PRINT 0
-#define AF_OP_COMM 1
-#define AF_OP_SERVER 2
-#define AF_OP_ACCOUNTS 3
-
-
-static bool api_RNetUserGetInfo(connection_struct *conn, uint16 vuid,
+static bool api_RNetUserGetInfo(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *endp;
const char *level_string;
- /* get NIS home of a previously validated user - simeon */
- /* With share level security vuid will always be zero.
- Don't depend on vuser being non-null !!. JRA */
- user_struct *vuser = get_valid_user_struct(vuid);
- if(vuser != NULL) {
- DEBUG(3,(" Username of UID %d is %s\n",
- (int)vuser->server_info->uid,
- vuser->server_info->unix_name));
- }
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ NTSTATUS status, result;
+ struct rpc_pipe_client *cli = NULL;
+ struct policy_handle connect_handle, domain_handle, user_handle;
+ struct lsa_String domain_name;
+ struct dom_sid2 *domain_sid;
+ struct lsa_String names;
+ struct samr_Ids rids;
+ struct samr_Ids types;
+ int errcode = W_ERROR_V(WERR_USER_NOT_FOUND);
+ uint32_t rid;
+ union samr_UserInfo *info;
+ struct dcerpc_binding_handle *b = NULL;
if (!str1 || !str2 || !UserName || !p) {
return False;
return False;
}
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
p = *rdata;
endp = *rdata + *rdata_len;
p2 = get_safe_ptr(*rdata,*rdata_len,p,usri11_end);
return False;
}
+ ZERO_STRUCT(connect_handle);
+ ZERO_STRUCT(domain_handle);
+ ZERO_STRUCT(user_handle);
+
+ status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_RNetUserGetInfo: could not connect to samr: %s\n",
+ nt_errstr(status)));
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+
+ b = cli->binding_handle;
+
+ status = dcerpc_samr_Connect2(b, mem_ctx,
+ global_myname(),
+ SAMR_ACCESS_CONNECT_TO_SERVER |
+ SAMR_ACCESS_ENUM_DOMAINS |
+ SAMR_ACCESS_LOOKUP_DOMAIN,
+ &connect_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
+ init_lsa_String(&domain_name, get_global_sam_name());
+
+ status = dcerpc_samr_LookupDomain(b, mem_ctx,
+ &connect_handle,
+ &domain_name,
+ &domain_sid,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
+ status = dcerpc_samr_OpenDomain(b, mem_ctx,
+ &connect_handle,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
+ domain_sid,
+ &domain_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
+ init_lsa_String(&names, UserName);
+
+ status = dcerpc_samr_LookupNames(b, mem_ctx,
+ &domain_handle,
+ 1,
+ &names,
+ &rids,
+ &types,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
+ if (rids.count != 1) {
+ errcode = W_ERROR_V(WERR_NO_SUCH_USER);
+ goto out;
+ }
+ if (rids.count != types.count) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
+ if (types.ids[0] != SID_NAME_USER) {
+ errcode = W_ERROR_V(WERR_INVALID_PARAM);
+ goto out;
+ }
+
+ rid = rids.ids[0];
+
+ status = dcerpc_samr_OpenUser(b, mem_ctx,
+ &domain_handle,
+ SAMR_USER_ACCESS_GET_LOCALE |
+ SAMR_USER_ACCESS_GET_LOGONINFO |
+ SAMR_USER_ACCESS_GET_ATTRIBUTES |
+ SAMR_USER_ACCESS_GET_GROUPS |
+ SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP |
+ SEC_STD_READ_CONTROL,
+ rid,
+ &user_handle,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
+ status = dcerpc_samr_QueryUserInfo2(b, mem_ctx,
+ &user_handle,
+ UserAllInformation,
+ &info,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!NT_STATUS_IS_OK(result)) {
+ errcode = W_ERROR_V(ntstatus_to_werror(result));
+ goto out;
+ }
+
memset(p,0,21);
fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */
/* EEK! the cifsrap.txt doesn't have this in!!!! */
SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
- strlcpy(p2,((vuser != NULL)
- ? pdb_get_fullname(vuser->server_info->sam_account)
- : UserName),PTR_DIFF(endp,p2));
+ strlcpy(p2,info->info21.full_name.string,PTR_DIFF(endp,p2));
p2 = skip_string(*rdata,*rdata_len,p2);
if (!p2) {
return False;
}
if (uLevel == 11) {
- const char *homedir = "";
- if (vuser != NULL) {
- homedir = pdb_get_homedir(
- vuser->server_info->sam_account);
- }
+ const char *homedir = info->info21.home_directory.string;
/* modelled after NTAS 3.51 reply */
- SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ SSVAL(p,usri11_priv,
+ (get_current_uid(conn) == sec_initial_uid())?
+ USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
SIVALS(p,usri11_password_age,-1); /* password age */
SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
memset(p+22,' ',16); /* password */
SIVALS(p,38,-1); /* password age */
SSVAL(p,42,
- conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ (get_current_uid(conn) == sec_initial_uid())?
+ USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- strlcpy(p2, vuser ? pdb_get_homedir(
- vuser->server_info->sam_account) : "",
+ strlcpy(p2, info->info21.home_directory.string,
PTR_DIFF(endp,p2));
p2 = skip_string(*rdata,*rdata_len,p2);
if (!p2) {
*p2++ = 0;
SSVAL(p,52,0); /* flags */
SIVAL(p,54,PTR_DIFF(p2,*rdata)); /* script_path */
- strlcpy(p2, vuser ? pdb_get_logon_script(
- vuser->server_info->sam_account) : "",
+ strlcpy(p2, info->info21.logon_script.string,
PTR_DIFF(endp,p2));
p2 = skip_string(*rdata,*rdata_len,p2);
if (!p2) {
return False;
}
if (uLevel == 2) {
- SIVAL(p,60,0); /* auth_flags */
- SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
- strlcpy(p2,((vuser != NULL)
- ? pdb_get_fullname(vuser->server_info->sam_account)
- : UserName),PTR_DIFF(endp,p2));
+ SIVAL(p,58,0); /* auth_flags */
+ SIVAL(p,62,PTR_DIFF(p2,*rdata)); /* full_name */
+ strlcpy(p2,info->info21.full_name.string,PTR_DIFF(endp,p2));
p2 = skip_string(*rdata,*rdata_len,p2);
if (!p2) {
return False;
}
- SIVAL(p,68,0); /* urs_comment */
- SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
+ SIVAL(p,66,0); /* urs_comment */
+ SIVAL(p,70,PTR_DIFF(p2,*rdata)); /* parms */
strlcpy(p2,"",PTR_DIFF(endp,p2));
p2 = skip_string(*rdata,*rdata_len,p2);
if (!p2) {
return False;
}
- SIVAL(p,76,0); /* workstations */
- SIVAL(p,80,0); /* last_logon */
- SIVAL(p,84,0); /* last_logoff */
- SIVALS(p,88,-1); /* acct_expires */
- SIVALS(p,92,-1); /* max_storage */
- SSVAL(p,96,168); /* units_per_week */
- SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
+ SIVAL(p,74,0); /* workstations */
+ SIVAL(p,78,0); /* last_logon */
+ SIVAL(p,82,0); /* last_logoff */
+ SIVALS(p,86,-1); /* acct_expires */
+ SIVALS(p,90,-1); /* max_storage */
+ SSVAL(p,94,168); /* units_per_week */
+ SIVAL(p,96,PTR_DIFF(p2,*rdata)); /* logon_hours */
memset(p2,-1,21);
p2 += 21;
- SSVALS(p,102,-1); /* bad_pw_count */
- SSVALS(p,104,-1); /* num_logons */
- SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
+ SSVALS(p,100,-1); /* bad_pw_count */
+ SSVALS(p,102,-1); /* num_logons */
+ SIVAL(p,104,PTR_DIFF(p2,*rdata)); /* logon_server */
{
TALLOC_CTX *ctx = talloc_tos();
int space_rem = *rdata_len - (p2 - *rdata);
if (!p2) {
return False;
}
- SSVAL(p,110,49); /* country_code */
- SSVAL(p,112,860); /* code page */
+ SSVAL(p,108,49); /* country_code */
+ SSVAL(p,110,860); /* code page */
}
}
+ errcode = NERR_Success;
+
+ out:
*rdata_len = PTR_DIFF(p2,*rdata);
+ if (b && is_valid_policy_hnd(&user_handle)) {
+ dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
+ }
+ if (b && is_valid_policy_hnd(&domain_handle)) {
+ dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
+ }
+ if (b && is_valid_policy_hnd(&connect_handle)) {
+ dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
+ }
+
+ SSVAL(*rparam,0,errcode);
+ SSVAL(*rparam,2,0); /* converter word */
SSVAL(*rparam,4,*rdata_len); /* is this right?? */
return(True);
}
-static bool api_WWkstaUserLogon(connection_struct *conn,uint16 vuid,
+static bool api_WWkstaUserLogon(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char* name;
/* With share level security vuid will always be zero.
Don't depend on vuser being non-null !!. JRA */
- user_struct *vuser = get_valid_user_struct(vuid);
+ user_struct *vuser = get_valid_user_struct(sconn, vuid);
if (!str1 || !str2 || !p) {
return False;
if(vuser != NULL) {
DEBUG(3,(" Username of UID %d is %s\n",
- (int)vuser->server_info->uid,
- vuser->server_info->unix_name));
+ (int)vuser->session_info->utok.uid,
+ vuser->session_info->unix_name));
}
uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
desc.buflen = mdrcnt;
desc.subformat = NULL;
desc.format = str2;
-
+
if (init_package(&desc,1,0)) {
PACKI(&desc,"W",0); /* code */
PACKS(&desc,"B21",name); /* eff. name */
PACKS(&desc,"B",""); /* pad */
- PACKI(&desc,"W", conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ PACKI(&desc,"W",
+ (get_current_uid(conn) == sec_initial_uid())?
+ USER_PRIV_ADMIN:USER_PRIV_USER);
PACKI(&desc,"D",0); /* auth flags XXX */
PACKI(&desc,"W",0); /* num logons */
PACKI(&desc,"W",0); /* bad pw count */
}
PACKS(&desc,"z",lp_workgroup());/* domain */
- PACKS(&desc,"z", vuser ? pdb_get_logon_script(
- vuser->server_info->sam_account) : ""); /* script path */
+ PACKS(&desc,"z", vuser ?
+ vuser->session_info->info3->base.logon_script.string
+ : ""); /* script path */
PACKI(&desc,"D",0x00000000); /* reserved */
}
api_WAccessGetUserPerms
****************************************************************************/
-static bool api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid,
+static bool api_WAccessGetUserPerms(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
api_WPrintJobEnumerate
****************************************************************************/
-static bool api_WPrintJobGetInfo(connection_struct *conn, uint16 vuid,
+static bool api_WPrintJobGetInfo(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *str2 = skip_string(param,tpscnt,str1);
char *p = skip_string(param,tpscnt,str2);
int uLevel;
- int count;
- int i;
- int snum;
fstring sharename;
uint32 jobid;
struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
char *tmpdata=NULL;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ WERROR werr;
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct policy_handle handle;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ union spoolss_JobInfo info;
+
if (!str1 || !str2 || !p) {
return False;
}
return False;
}
- snum = lp_servicenumber( sharename);
- if (snum < 0 || !VALID_SNUM(snum)) {
- return(False);
+ ZERO_STRUCT(handle);
+
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_WPrintJobGetInfo: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
}
+ b = cli->binding_handle;
- count = print_queue_status(snum,&queue,&status);
- for (i = 0; i < count; i++) {
- if (queue[i].job == jobid) {
- break;
- }
+ ZERO_STRUCT(devmode_ctr);
+
+ status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
+ sharename,
+ "RAW",
+ devmode_ctr,
+ PRINTER_ACCESS_USE,
+ &handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ werr = rpccli_spoolss_getjob(cli, mem_ctx,
+ &handle,
+ jobid,
+ 2, /* level */
+ 0, /* offered */
+ &info);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
}
if (mdrcnt > 0) {
}
if (init_package(&desc,1,0)) {
- if (i < count) {
- fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
- *rdata_len = desc.usedlen;
- } else {
- desc.errcode = NERR_JobNotFound;
- *rdata_len = 0;
- }
+ fill_spoolss_printjob_info(uLevel, &desc, &info.info2, info.info2.position);
+ *rdata_len = desc.usedlen;
+ } else {
+ desc.errcode = NERR_JobNotFound;
+ *rdata_len = 0;
+ }
+ out:
+ if (b && is_valid_policy_hnd(&handle)) {
+ dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
}
*rparam_len = 6;
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,desc.neededlen);
- SAFE_FREE(queue);
SAFE_FREE(tmpdata);
DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
return True;
}
-static bool api_WPrintJobEnumerate(connection_struct *conn, uint16 vuid,
+static bool api_WPrintJobEnumerate(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *p = skip_string(param,tpscnt,str2);
char *name = p;
int uLevel;
- int count;
int i, succnt=0;
- int snum;
struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
+
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ WERROR werr;
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct policy_handle handle;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ uint32_t count = 0;
+ union spoolss_JobInfo *info;
if (!str1 || !str2 || !p) {
return False;
}
memset((char *)&desc,'\0',sizeof(desc));
- memset((char *)&status,'\0',sizeof(status));
p = skip_string(param,tpscnt,p);
if (!p) {
if (strcmp(str1,"zWrLeh") != 0) {
return False;
}
-
+
if (uLevel > 2) {
return False; /* defined only for uLevel 0,1,2 */
}
-
- if (!check_printjob_info(&desc,uLevel,str2)) {
+
+ if (!check_printjob_info(&desc,uLevel,str2)) {
return False;
}
- snum = find_service(name);
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
- return False;
+ ZERO_STRUCT(handle);
+
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_WPrintJobEnumerate: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ b = cli->binding_handle;
+
+ ZERO_STRUCT(devmode_ctr);
+
+ status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
+ name,
+ NULL,
+ devmode_ctr,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ werr = rpccli_spoolss_enumjobs(cli, mem_ctx,
+ &handle,
+ 0, /* firstjob */
+ 0xff, /* numjobs */
+ 2, /* level */
+ 0, /* offered */
+ &count,
+ &info);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
}
- count = print_queue_status(snum,&queue,&status);
if (mdrcnt > 0) {
*rdata = smb_realloc_limit(*rdata,mdrcnt);
if (!*rdata) {
if (init_package(&desc,count,0)) {
succnt = 0;
for (i = 0; i < count; i++) {
- fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
+ fill_spoolss_printjob_info(uLevel, &desc, &info[i].info2, i);
if (desc.errcode == NERR_Success) {
succnt = i+1;
}
}
}
+ out:
+ if (b && is_valid_policy_hnd(&handle)) {
+ dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
+ }
*rdata_len = desc.usedlen;
SSVAL(*rparam,4,succnt);
SSVAL(*rparam,6,count);
- SAFE_FREE(queue);
-
DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
return True;
return False;
}
if (id == NULL || strcmp(desc->format,id) != 0) {
- DEBUG(0,("check_printdest_info: invalid string %s\n",
+ DEBUG(0,("check_printdest_info: invalid string %s\n",
id ? id : "<NULL>" ));
return False;
}
return True;
}
-static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
+static void fill_printdest_info(struct spoolss_PrinterInfo2 *info2, int uLevel,
struct pack_desc* desc)
{
char buf[100];
- strncpy(buf,SERVICE(snum),sizeof(buf)-1);
+ strncpy(buf, info2->printername, sizeof(buf)-1);
buf[sizeof(buf)-1] = 0;
strupper_m(buf);
}
}
-static bool api_WPrintDestGetInfo(connection_struct *conn, uint16 vuid,
+static bool api_WPrintDestGetInfo(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char* PrinterName = p;
int uLevel;
struct pack_desc desc;
- int snum;
char *tmpdata=NULL;
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ WERROR werr;
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct policy_handle handle;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ union spoolss_PrinterInfo info;
+
if (!str1 || !str2 || !p) {
return False;
}
return False;
}
- snum = find_service(PrinterName);
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
+ ZERO_STRUCT(handle);
+
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_WPrintDestGetInfo: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ b = cli->binding_handle;
+
+ ZERO_STRUCT(devmode_ctr);
+
+ status = dcerpc_spoolss_OpenPrinter(b, mem_ctx,
+ PrinterName,
+ NULL,
+ devmode_ctr,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
*rdata_len = 0;
desc.errcode = NERR_DestNotFound;
desc.neededlen = 0;
- } else {
- if (mdrcnt > 0) {
- *rdata = smb_realloc_limit(*rdata,mdrcnt);
- if (!*rdata) {
- return False;
- }
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- } else {
- /*
- * Don't return data but need to get correct length
- * init_package will return wrong size if buflen=0
- */
- desc.buflen = getlen(desc.format);
- desc.base = tmpdata = (char *)SMB_MALLOC( desc.buflen );
- }
- if (init_package(&desc,1,0)) {
- fill_printdest_info(conn,snum,uLevel,&desc);
+ goto out;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ *rdata_len = 0;
+ desc.errcode = NERR_DestNotFound;
+ desc.neededlen = 0;
+ goto out;
+ }
+
+ werr = rpccli_spoolss_getprinter(cli, mem_ctx,
+ &handle,
+ 2,
+ 0,
+ &info);
+ if (!W_ERROR_IS_OK(werr)) {
+ *rdata_len = 0;
+ desc.errcode = NERR_DestNotFound;
+ desc.neededlen = 0;
+ goto out;
+ }
+
+ if (mdrcnt > 0) {
+ *rdata = smb_realloc_limit(*rdata,mdrcnt);
+ if (!*rdata) {
+ return False;
}
- *rdata_len = desc.usedlen;
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ } else {
+ /*
+ * Don't return data but need to get correct length
+ * init_package will return wrong size if buflen=0
+ */
+ desc.buflen = getlen(desc.format);
+ desc.base = tmpdata = (char *)SMB_MALLOC( desc.buflen );
+ }
+ if (init_package(&desc,1,0)) {
+ fill_printdest_info(&info.info2, uLevel,&desc);
}
+ out:
+ if (b && is_valid_policy_hnd(&handle)) {
+ dcerpc_spoolss_ClosePrinter(b, mem_ctx, &handle, &werr);
+ }
+
+ *rdata_len = desc.usedlen;
+
*rparam_len = 6;
*rparam = smb_realloc_limit(*rparam,*rparam_len);
if (!*rparam) {
return True;
}
-static bool api_WPrintDestEnum(connection_struct *conn, uint16 vuid,
+static bool api_WPrintDestEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
int queuecnt;
int i, n, succnt=0;
struct pack_desc desc;
- int services = lp_numservices();
+
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ WERROR werr;
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ union spoolss_PrinterInfo *info;
+ uint32_t count;
if (!str1 || !str2 || !p) {
return False;
}
queuecnt = 0;
- for (i = 0; i < services; i++) {
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- queuecnt++;
- }
+
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_spoolss.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("api_WPrintDestEnum: could not connect to spoolss: %s\n",
+ nt_errstr(status)));
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+
+ werr = rpccli_spoolss_enumprinters(cli, mem_ctx,
+ PRINTER_ENUM_LOCAL,
+ cli->srv_name_slash,
+ 2,
+ 0,
+ &count,
+ &info);
+ if (!W_ERROR_IS_OK(werr)) {
+ desc.errcode = W_ERROR_V(werr);
+ *rdata_len = 0;
+ desc.errcode = NERR_DestNotFound;
+ desc.neededlen = 0;
+ goto out;
}
+ queuecnt = count;
+
if (mdrcnt > 0) {
*rdata = smb_realloc_limit(*rdata,mdrcnt);
if (!*rdata) {
desc.base = *rdata;
desc.buflen = mdrcnt;
- if (init_package(&desc,queuecnt,0)) {
+ if (init_package(&desc,queuecnt,0)) {
succnt = 0;
n = 0;
- for (i = 0; i < services; i++) {
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printdest_info(conn,i,uLevel,&desc);
- n++;
- if (desc.errcode == NERR_Success) {
- succnt = n;
- }
+ for (i = 0; i < count; i++) {
+ fill_printdest_info(&info[i].info2, uLevel,&desc);
+ n++;
+ if (desc.errcode == NERR_Success) {
+ succnt = n;
}
}
}
-
+ out:
*rdata_len = desc.usedlen;
*rparam_len = 8;
return True;
}
-static bool api_WPrintDriverEnum(connection_struct *conn, uint16 vuid,
+static bool api_WPrintDriverEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
return True;
}
-static bool api_WPrintQProcEnum(connection_struct *conn, uint16 vuid,
+static bool api_WPrintQProcEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
return True;
}
-static bool api_WPrintPortEnum(connection_struct *conn, uint16 vuid,
+static bool api_WPrintPortEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
List open sessions
****************************************************************************/
-static bool api_RNetSessionEnum(connection_struct *conn, uint16 vuid,
+static bool api_RNetSessionEnum(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt,int mprcnt,
char *p = skip_string(param,tpscnt,str2);
int uLevel;
struct pack_desc desc;
- struct sessionid *session_list;
- int i, num_sessions;
+ int i;
+
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ WERROR werr;
+ NTSTATUS status;
+ struct rpc_pipe_client *cli = NULL;
+ struct dcerpc_binding_handle *b = NULL;
+ struct srvsvc_NetSessInfoCtr info_ctr;
+ uint32_t totalentries, resume_handle = 0;
+ uint32_t count = 0;
if (!str1 || !str2 || !p) {
return False;
}
- memset((char *)&desc,'\0',sizeof(desc));
+ ZERO_STRUCT(desc);
uLevel = get_safe_SVAL(param,tpscnt,p,0,-1);
return False;
}
- num_sessions = list_sessions(talloc_tos(), &session_list);
+ status = rpc_pipe_open_interface(conn,
+ &ndr_table_srvsvc.syntax_id,
+ conn->session_info,
+ &conn->sconn->client_id,
+ conn->sconn->msg_ctx,
+ &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("RNetSessionEnum: could not connect to srvsvc: %s\n",
+ nt_errstr(status)));
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+ b = cli->binding_handle;
+
+ info_ctr.level = 1;
+ info_ctr.ctr.ctr1 = talloc_zero(talloc_tos(), struct srvsvc_NetSessCtr1);
+ if (info_ctr.ctr.ctr1 == NULL) {
+ desc.errcode = W_ERROR_V(WERR_NOMEM);
+ goto out;
+ }
+
+ status = dcerpc_srvsvc_NetSessEnum(b, mem_ctx,
+ cli->srv_name_slash,
+ NULL, /* client */
+ NULL, /* user */
+ &info_ctr,
+ (uint32_t)-1, /* max_buffer */
+ &totalentries,
+ &resume_handle,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("RNetSessionEnum: dcerpc_srvsvc_NetSessEnum failed: %s\n",
+ nt_errstr(status)));
+ desc.errcode = W_ERROR_V(ntstatus_to_werror(status));
+ goto out;
+ }
+
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,("RNetSessionEnum: dcerpc_srvsvc_NetSessEnum failed: %s\n",
+ win_errstr(werr)));
+ desc.errcode = W_ERROR_V(werr);
+ goto out;
+ }
+
+ count = info_ctr.ctr.ctr1->count;
+ out:
if (mdrcnt > 0) {
*rdata = smb_realloc_limit(*rdata,mdrcnt);
if (!*rdata) {
return False;
}
}
- memset((char *)&desc,'\0',sizeof(desc));
+
desc.base = *rdata;
desc.buflen = mdrcnt;
desc.format = str2;
- if (!init_package(&desc,num_sessions,0)) {
+ if (!init_package(&desc, count,0)) {
return False;
}
- for(i=0; i<num_sessions; i++) {
- PACKS(&desc, "z", session_list[i].remote_machine);
- PACKS(&desc, "z", session_list[i].username);
+ for(i=0; i < count; i++) {
+ PACKS(&desc, "z", info_ctr.ctr.ctr1->array[i].client);
+ PACKS(&desc, "z", info_ctr.ctr.ctr1->array[i].user);
PACKI(&desc, "W", 1); /* num conns */
- PACKI(&desc, "W", 0); /* num opens */
+ PACKI(&desc, "W", info_ctr.ctr.ctr1->array[i].num_open);
PACKI(&desc, "W", 1); /* num users */
PACKI(&desc, "D", 0); /* session time */
PACKI(&desc, "D", 0); /* idle time */
}
SSVALS(*rparam,0,desc.errcode);
SSVAL(*rparam,2,0); /* converter */
- SSVAL(*rparam,4,num_sessions); /* count */
+ SSVAL(*rparam,4, count); /* count */
DEBUG(4,("RNetSessionEnum: errorcode %d\n",desc.errcode));
The buffer was too small.
****************************************************************************/
-static bool api_TooSmall(connection_struct *conn,uint16 vuid, char *param, char *data,
+static bool api_TooSmall(struct smbd_server_connection *sconn,
+ connection_struct *conn,uint16 vuid, char *param, char *data,
int mdrcnt, int mprcnt,
char **rdata, char **rparam,
int *rdata_len, int *rparam_len)
The request is not supported.
****************************************************************************/
-static bool api_Unsupported(connection_struct *conn, uint16 vuid,
+static bool api_Unsupported(struct smbd_server_connection *sconn,
+ connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
int mdrcnt, int mprcnt,
static const struct {
const char *name;
int id;
- bool (*fn)(connection_struct *, uint16,
+ bool (*fn)(struct smbd_server_connection *sconn,
+ connection_struct *, uint16,
char *, int,
char *, int,
int,int,char **,char **,int *,int *);
{"WPrintDestGetInfo", RAP_WPrintDestGetInfo, api_WPrintDestGetInfo},
{"NetRemoteTOD", RAP_NetRemoteTOD, api_NetRemoteTOD},
{"WPrintQueuePurge", RAP_WPrintQPurge, api_WPrintQueueCtrl},
- {"NetServerEnum", RAP_NetServerEnum2, api_RNetServerEnum}, /* anon OK */
+ {"NetServerEnum2", RAP_NetServerEnum2, api_RNetServerEnum2}, /* anon OK */
+ {"NetServerEnum3", RAP_NetServerEnum3, api_RNetServerEnum3}, /* anon OK */
{"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms},
{"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword},
{"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon},
{NULL, -1, api_Unsupported}
/* The following RAP calls are not implemented by Samba:
- RAP_WFileEnum2 - anon not OK
+ RAP_WFileEnum2 - anon not OK
*/
};
/* Check whether this api call can be done anonymously */
if (api_commands[i].auth_user && lp_restrict_anonymous()) {
- user_struct *user = get_valid_user_struct(vuid);
+ user_struct *user = get_valid_user_struct(req->sconn, vuid);
- if (!user || user->server_info->guest) {
+ if (!user || user->session_info->guest) {
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
return;
}
return;
}
- reply = api_commands[i].fn(conn,
+ reply = api_commands[i].fn(req->sconn, conn,
vuid,
params,tpscnt, /* params + length */
data,tdscnt, /* data + length */
if (rdata_len > mdrcnt || rparam_len > mprcnt) {
- reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
+ reply = api_TooSmall(req->sconn,conn,vuid,params,data,
+ mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
}
/* if we get False back then it's actually unsupported */
if (!reply) {
- reply = api_Unsupported(conn,vuid,params,tpscnt,data,tdscnt,mdrcnt,mprcnt,
+ reply = api_Unsupported(req->sconn,conn,vuid,params,tpscnt,
+ data,
+ tdscnt,mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
}