diff options
-rw-r--r-- | source/include/proto.h | 17 | ||||
-rw-r--r-- | source/lib/interface.c | 4 | ||||
-rw-r--r-- | source/printing/nt_printing.c | 32 | ||||
-rw-r--r-- | source/printing/printing.c | 66 | ||||
-rw-r--r-- | source/rpc_parse/parse_misc.c | 2 | ||||
-rw-r--r-- | source/rpc_parse/parse_spoolss.c | 14 | ||||
-rw-r--r-- | source/rpc_server/srv_spoolss_nt.c | 261 | ||||
-rw-r--r-- | source/smbd/lanman.c | 6 | ||||
-rw-r--r-- | source/smbwrapper/smbw.c | 57 | ||||
-rw-r--r-- | source/smbwrapper/smbw.h | 10 | ||||
-rw-r--r-- | source/tdb/tdbutil.c | 2 | ||||
-rw-r--r-- | source/utils/nmblookup.c | 10 |
12 files changed, 272 insertions, 209 deletions
diff --git a/source/include/proto.h b/source/include/proto.h index 2c20a4ad8a6..08995690e19 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -1790,9 +1790,9 @@ int print_job_fd(int jobid); char *print_job_fname(int jobid); BOOL print_job_set_place(int jobid, int place); BOOL print_job_set_name(int jobid, char *name); -BOOL print_job_delete(struct current_user *user, int jobid); -BOOL print_job_pause(struct current_user *user, int jobid); -BOOL print_job_resume(struct current_user *user, int jobid); +BOOL print_job_delete(struct current_user *user, int jobid, int *errcode); +BOOL print_job_pause(struct current_user *user, int jobid, int *errcode); +BOOL print_job_resume(struct current_user *user, int jobid, int *errcode); int print_job_write(int jobid, const char *buf, int size); int print_job_start(struct current_user *user, int snum, char *jobname); BOOL print_job_end(int jobid); @@ -3233,12 +3233,8 @@ uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid); -uint32 _spoolss_setjob( POLICY_HND *handle, - uint32 jobid, - uint32 level, - pipes_struct *p, - JOB_INFO *ctr, - uint32 command); +uint32 _spoolss_setjob(POLICY_HND *handle, uint32 jobid, uint32 level, + pipes_struct *p, JOB_INFO *ctr, uint32 command); uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); @@ -3951,6 +3947,9 @@ void clean_fname(char *name); char *smbw_parse_path(const char *fname, char *server, char *share, char *path); int smbw_path(const char *path); int smbw_errno(struct cli_state *c); +void get_envvar_auth_data(char *server, char *share, char **workgroup, + char **username, char **password); +void smbw_set_auth_data_fn(smbw_get_auth_data_fn fn); struct smbw_server *smbw_server(char *server, char *share); struct smbw_file *smbw_file(int fd); int smbw_open(const char *fname, int flags, mode_t mode); diff --git a/source/lib/interface.c b/source/lib/interface.c index e5352517567..31ec846fdca 100644 --- a/source/lib/interface.c +++ b/source/lib/interface.c @@ -234,8 +234,8 @@ BOOL interfaces_changed(void) n = get_interfaces(ifaces, MAX_INTERFACES); - if (n != total_probed || - memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n)) { + if ((n > 0 )&& (n != total_probed || + memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) { return True; } diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c index c70a6891d47..18652d8c928 100644 --- a/source/printing/nt_printing.c +++ b/source/printing/nt_printing.c @@ -640,7 +640,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, connection_struct *conn; pstring inbuf; pstring outbuf; - struct smb_passwd *smb_pass; + struct passwd *pass; int ecode; int outsize = 0; int i; @@ -662,9 +662,9 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, get_short_archi(architecture, driver->environment); become_root(); - smb_pass = getsmbpwuid(user->uid); - if(smb_pass == NULL) { - DEBUG(0,("move_driver_to_download_area: Unable to get smbpasswd entry for uid %u\n", + pass = getpwuid(user->uid); + if(pass == NULL) { + DEBUG(0,("move_driver_to_download_area: Unable to get passwd entry for uid %u\n", (unsigned int)user->uid )); unbecome_root(); return False; @@ -672,7 +672,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, unbecome_root(); /* connect to the print$ share under the same account as the user connected to the rpc pipe */ - fstrcpy(user_name, smb_pass->smb_name ); + fstrcpy(user_name, pass->pw_name ); DEBUG(10,("move_driver_to_download_area: uid %d -> user %s\n", (int)user->uid, user_name)); /* Null password is ok - we are already an authenticated user... */ @@ -1431,9 +1431,8 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename) ZERO_STRUCTP(nt_devmode); - snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, default_devicename); - fstrcpy(nt_devmode->devicename, adevice); - + safe_strcpy(adevice, default_devicename, sizeof(adevice)); + fstrcpy(nt_devmode->devicename, adevice); fstrcpy(nt_devmode->formname, "Letter"); @@ -1663,8 +1662,10 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin snum = lp_servicenumber(sharename); - fstrcpy(info.servername, global_myname); - fstrcpy(info.printername, sharename); + slprintf(info.servername, sizeof(info.servername), "\\\\%s", global_myname); + slprintf(info.printername, sizeof(info.printername), "\\\\%s\\%s", + global_myname, sharename); + fstrcpy(info.sharename, sharename); fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME); fstrcpy(info.drivername, lp_printerdriver(snum)); pstrcpy(info.comment, ""); @@ -1713,6 +1714,7 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen NT_PRINTER_INFO_LEVEL_2 info; int len = 0; TDB_DATA kbuf, dbuf; + fstring printername; ZERO_STRUCT(info); @@ -1752,6 +1754,12 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen /* Samba has to have shared raw drivers. */ info.attributes |= (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_RAW_ONLY); + /* Restore the stripped strings. */ + slprintf(info.servername, sizeof(info.servername), "\\\\%s", global_myname); + slprintf(printername, sizeof(printername), "\\\\%s\\%s", global_myname, + info.printername); + fstrcpy(info.printername, printername); + len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len); len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len); @@ -1760,8 +1768,8 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen safe_free(dbuf.dptr); *info_ptr=memdup(&info, sizeof(info)); - DEBUG(9,("Unpacked printer [%s] running driver [%s]\n", - sharename, info.drivername)); + DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n", + sharename, info.printername, info.drivername)); return 0; diff --git a/source/printing/printing.c b/source/printing/printing.c index 6a3d5b443b5..77e32d5bf0c 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -197,21 +197,18 @@ list a unix job in the print database static void print_unix_job(int snum, print_queue_struct *q) { int jobid = q->job + UNIX_JOB_START; - struct printjob pj; + struct printjob pj, *old_pj; - /* Don't re-insert a unix job if it already exists as it mucks - up the timestamp. */ + /* Preserve the timestamp on an existing unix print job */ - if (tdb_exists(tdb, print_key(jobid))) { - return; - } + old_pj = print_job_find(jobid); ZERO_STRUCT(pj); pj.pid = (pid_t)-1; pj.sysjob = q->job; pj.fd = -1; - pj.starttime = q->time; + pj.starttime = old_pj ? old_pj->starttime : q->time; pj.status = q->status; pj.size = q->size; pj.spooled = True; @@ -523,9 +520,10 @@ static BOOL is_owner(struct current_user *user, int jobid) /**************************************************************************** delete a print job ****************************************************************************/ -BOOL print_job_delete(struct current_user *user, int jobid) +BOOL print_job_delete(struct current_user *user, int jobid, int *errcode) { int snum = print_job_snum(jobid); + char *printer_name; BOOL owner; owner = is_owner(user, jobid); @@ -536,6 +534,7 @@ BOOL print_job_delete(struct current_user *user, int jobid) if (!owner && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("delete denied by security descriptor\n")); + *errcode = ERROR_ACCESS_DENIED; return False; } @@ -546,6 +545,13 @@ BOOL print_job_delete(struct current_user *user, int jobid) print_queue_update(snum); + /* Send a printer notify message */ + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + return !print_job_exists(jobid); } @@ -553,14 +559,14 @@ BOOL print_job_delete(struct current_user *user, int jobid) /**************************************************************************** pause a job ****************************************************************************/ -BOOL print_job_pause(struct current_user *user, int jobid) +BOOL print_job_pause(struct current_user *user, int jobid, int *errcode) { struct printjob *pjob = print_job_find(jobid); int snum, ret = -1; + char *printer_name; fstring jobstr; BOOL owner; - if (!pjob || !user) return False; if (!pjob->spooled || pjob->sysjob == -1) return False; @@ -571,6 +577,7 @@ BOOL print_job_pause(struct current_user *user, int jobid) if (!owner && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); + *errcode = ERROR_ACCESS_DENIED; return False; } @@ -581,19 +588,33 @@ BOOL print_job_pause(struct current_user *user, int jobid) "%j", jobstr, NULL); + if (ret != 0) { + *errcode = ERROR_INVALID_PARAMETER; + return False; + } + /* force update the database */ print_cache_flush(snum); + /* Send a printer notify message */ + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + /* how do we tell if this succeeded? */ - return ret == 0; + + return True; } /**************************************************************************** resume a job ****************************************************************************/ -BOOL print_job_resume(struct current_user *user, int jobid) +BOOL print_job_resume(struct current_user *user, int jobid, int *errcode) { struct printjob *pjob = print_job_find(jobid); + char *printer_name; int snum, ret; fstring jobstr; BOOL owner; @@ -608,6 +629,7 @@ BOOL print_job_resume(struct current_user *user, int jobid) if (!is_owner(user, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); + *errcode = ERROR_ACCESS_DENIED; return False; } @@ -617,11 +639,22 @@ BOOL print_job_resume(struct current_user *user, int jobid) "%j", jobstr, NULL); + if (ret != 0) { + *errcode = ERROR_INVALID_PARAMETER; + return False; + } + /* force update the database */ print_cache_flush(snum); - /* how do we tell if this succeeded? */ - return ret == 0; + /* Send a printer notify message */ + + printer_name = PRINTERNAME(snum); + + message_send_all(MSG_PRINTER_NOTIFY, printer_name, + strlen(printer_name) + 1); + + return True; } /**************************************************************************** @@ -970,6 +1003,8 @@ int print_queue_status(int snum, /* make sure the database is up to date */ if (print_cache_expired(snum)) print_queue_update(snum); + + *queue = NULL; /* * Count the number of entries. @@ -978,6 +1013,9 @@ int print_queue_status(int snum, tsc.snum = snum; tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc); + if (tsc.count == 0) + return 0; + /* Allocate the queue size. */ if (( tstruct.queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c index 93f47bbc7a2..859a8007719 100644 --- a/source/rpc_parse/parse_misc.c +++ b/source/rpc_parse/parse_misc.c @@ -494,6 +494,8 @@ void init_unistr(UNISTR *str, const char *buf) if (str->buffer == NULL) smb_panic("init_unistr: malloc fail\n"); + memset(str->buffer, '\0', len); + /* store the string (null-terminated copy) */ dos_struni2((char *)str->buffer, buf, len); } diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index eaacb52f5bb..c4196b03341 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -4340,6 +4340,13 @@ BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_ if(!prs_uint32("version", ps, depth, &il->version)) return False; +#if 0 + /* + * Older build versions of W2K seem to need this. JRA. + */ + if(!prs_uint32("dummy4", ps, depth, &il->dummy4)) + return False; +#endif if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr)) return False; if(!prs_uint32("environment_ptr", ps, depth, &il->environment_ptr)) @@ -4385,30 +4392,37 @@ BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_ return False; if(!prs_align(ps)) return False; + if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth)) return False; if(!prs_align(ps)) return False; + if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth)) return False; if(!prs_align(ps)) return False; + if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth)) return False; if(!prs_align(ps)) return False; + if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth)) return False; if(!prs_align(ps)) return False; + if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth)) return False; if(!prs_align(ps)) return False; + if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth)) return False; if(!prs_align(ps)) return False; + if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth)) return False; if(!prs_align(ps)) diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index 93638291655..42f9d29d9c1 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -1103,12 +1103,19 @@ static void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, p static void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) { + /* the notify name should not contain the \\server\ part */ + char *p = strrchr(printer->info_2->printername, '\\'); + if (!p) { + p = printer->info_2->printername; + } else { + p++; + } /* data->notify_data.data.length=strlen(lp_servicename(snum)); dos_PutUniCode(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string), True); */ data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string, - printer->info_2->printername, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16)); + p, sizeof(data->notify_data.data.string), True) - sizeof(uint16))/sizeof(uint16)); } /******************************************************************* @@ -1339,18 +1346,19 @@ static void spoolss_notify_job_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, prin static void spoolss_notify_job_status_string(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) { char *p = "unknown"; + switch (queue->status) { case LPQ_QUEUED: - p = "QUEUED"; + p = "Queued"; break; case LPQ_PAUSED: - p = "PAUSED"; + p = ""; /* NT provides the paused string */ break; case LPQ_SPOOLING: - p = "SPOOLING"; + p = "Spooling"; break; case LPQ_PRINTING: - p = "PRINTING"; + p = "Printing"; break; } data->notify_data.data.length=(uint32)((dos_PutUniCode((char *)data->notify_data.data.string, @@ -1580,6 +1588,10 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPO current_data=&info->data[info->count]; construct_info_data(current_data, type, field, id); + + DEBUG(10,("construct_notify_printer_info: calling %s\n", + notify_info_data_table[j].name )); + notify_info_data_table[j].fn(snum, current_data, queue, printer); info->count++; @@ -1819,9 +1831,9 @@ uint32 _spoolss_rfnpcnex( POLICY_HND *handle, uint32 change, /******************************************************************** * construct_printer_info_0 - * fill a printer_info_1 struct + * fill a printer_info_0 struct ********************************************************************/ -static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring servername) +static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum) { pstring chaine; int count; @@ -1870,12 +1882,11 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring */ global_counter=session_counter->counter; - /* the description and the name are of the form \\server\share */ - slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter->info_2->printername); + pstrcpy(chaine,ntprinter->info_2->printername); init_unistr(&printer->printername, chaine); - slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername); + slprintf(chaine,sizeof(chaine)-1,"\\\\%s", global_myname); init_unistr(&printer->servername, chaine); printer->cjobs = count; @@ -1931,7 +1942,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum, fstring * construct_printer_info_1 * fill a printer_info_1 struct ********************************************************************/ -static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum) +static BOOL construct_printer_info_1(uint32 flags, PRINTER_INFO_1 *printer, int snum) { pstring chaine; pstring chaine2; @@ -1944,16 +1955,16 @@ static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_ if (*ntprinter->info_2->comment == '\0') { init_unistr(&printer->comment, lp_comment(snum)); - snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername, + snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",global_myname, ntprinter->info_2->printername, ntprinter->info_2->drivername, lp_comment(snum)); } else { init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */ - snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter->info_2->printername, + snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",global_myname, ntprinter->info_2->printername, ntprinter->info_2->drivername, ntprinter->info_2->comment); } - snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter->info_2->printername); + snprintf(chaine2,sizeof(chaine)-1,"%s", ntprinter->info_2->printername); init_unistr(&printer->description, chaine); init_unistr(&printer->name, chaine2); @@ -1982,7 +1993,7 @@ static void free_dev_mode(DEVICEMODE *dev) Create a DEVMODE struct. Returns malloced memory. ****************************************************************************/ -static DEVICEMODE *construct_dev_mode(int snum, char *servername) +static DEVICEMODE *construct_dev_mode(int snum) { char adevice[32]; char aform[32]; @@ -2012,7 +2023,7 @@ static DEVICEMODE *construct_dev_mode(int snum, char *servername) DEBUGADD(8,("loading DEVICEMODE\n")); - snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, printer->info_2->printername); + safe_strcpy(adevice, printer->info_2->printername, sizeof(adevice)); init_unistr(&devmode->devicename, adevice); snprintf(aform, sizeof(aform), ntdevmode->formname); @@ -2068,11 +2079,8 @@ static DEVICEMODE *construct_dev_mode(int snum, char *servername) * fill a printer_info_2 struct ********************************************************************/ -static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer, int snum) +static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum) { - pstring chaine; - pstring chaine2; - pstring sl; int count; NT_PRINTER_INFO_LEVEL *ntprinter = NULL; @@ -2086,21 +2094,8 @@ static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer memset(&status, 0, sizeof(status)); count = print_queue_status(snum, &queue, &status); - snprintf(chaine, sizeof(chaine)-1, "%s", servername); - - if (strlen(servername)!=0) - fstrcpy(sl, "\\"); - else - fstrcpy(sl, '\0'); - - if (!strchr(ntprinter->info_2->printername, '\\')) { - snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter->info_2->printername); - } else { - pstrcpy(chaine2, ntprinter->info_2->printername); - } - - init_unistr(&printer->servername, chaine); /* servername*/ - init_unistr(&printer->printername, chaine2); /* printername*/ + init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/ + init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/ init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */ init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */ init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */ @@ -2126,7 +2121,7 @@ static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer printer->cjobs = count; /* jobs */ printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */ - if((printer->devmode = construct_dev_mode(snum, servername)) == NULL) { + if((printer->devmode = construct_dev_mode(snum)) == NULL) { DEBUG(8, ("Returning NULL Devicemode!\n")); } @@ -2150,8 +2145,7 @@ static BOOL construct_printer_info_2(fstring servername, PRINTER_INFO_2 *printer * construct_printer_info_3 * fill a printer_info_3 struct ********************************************************************/ -static BOOL construct_printer_info_3(fstring servername, - PRINTER_INFO_3 **pp_printer, int snum) +static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; PRINTER_INFO_3 *printer = NULL; @@ -2204,7 +2198,7 @@ static BOOL construct_printer_info_3(fstring servername, /******************************************************************** Spoolss_enumprinters. ********************************************************************/ -static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static BOOL enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; int i; @@ -2218,7 +2212,7 @@ static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *b if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - if (construct_printer_info_1(server, flags, ¤t_prt, snum)) { + if (construct_printer_info_1(flags, ¤t_prt, snum)) { if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) { *returned=0; return ERROR_NOT_ENOUGH_MEMORY; @@ -2255,20 +2249,11 @@ static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *b /******************************************************************** enum_all_printers_info_1_local. *********************************************************************/ -static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static BOOL enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - fstring temp; DEBUG(4,("enum_all_printers_info_1_local\n")); - fstrcpy(temp, "\\\\"); - fstrcat(temp, global_myname); - - if (!strcmp(name, temp)) { - fstrcat(temp, "\\"); - return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned); - } - else - return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned); + return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned); } /******************************************************************** @@ -2282,9 +2267,8 @@ static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint fstrcpy(temp, "\\\\"); fstrcat(temp, global_myname); - if (!strcmp(name, temp)) { - fstrcat(temp, "\\"); - return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned); + if (strequal(name, temp)) { + return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned); } else return ERROR_INVALID_NAME; @@ -2347,15 +2331,11 @@ static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, ui /******************************************************************** enum_all_printers_info_1_network. *********************************************************************/ -static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static BOOL enum_all_printers_info_1_network(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - fstring temp; DEBUG(4,("enum_all_printers_info_1_network\n")); - fstrcpy(temp, "\\\\"); - fstrcat(temp, global_myname); - fstrcat(temp, "\\"); - return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned); + return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned); } /******************************************************************** @@ -2363,7 +2343,7 @@ static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, u * * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; int i; @@ -2375,7 +2355,7 @@ static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uin if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - if (construct_printer_info_2(servername, ¤t_prt, snum)) { + if (construct_printer_info_2(¤t_prt, snum)) { if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) return ERROR_NOT_ENOUGH_MEMORY; DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned)); @@ -2427,7 +2407,7 @@ static uint32 enumprinters_level1( uint32 flags, fstring name, /* Not all the flags are equals */ if (flags & PRINTER_ENUM_LOCAL) - return enum_all_printers_info_1_local(name, buffer, offered, needed, returned); + return enum_all_printers_info_1_local(buffer, offered, needed, returned); if (flags & PRINTER_ENUM_NAME) return enum_all_printers_info_1_name(name, buffer, offered, needed, returned); @@ -2436,7 +2416,7 @@ static uint32 enumprinters_level1( uint32 flags, fstring name, return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned); if (flags & PRINTER_ENUM_NETWORK) - return enum_all_printers_info_1_network(name, buffer, offered, needed, returned); + return enum_all_printers_info_1_network(buffer, offered, needed, returned); return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */ } @@ -2454,15 +2434,15 @@ static uint32 enumprinters_level2( uint32 flags, fstring servername, fstrcat(temp, global_myname); if (flags & PRINTER_ENUM_LOCAL) { - if (!strcmp(servername, temp)) - return enum_all_printers_info_2(temp, buffer, offered, needed, returned); + if (strequal(servername, temp)) + return enum_all_printers_info_2(buffer, offered, needed, returned); else - return enum_all_printers_info_2("", buffer, offered, needed, returned); + return enum_all_printers_info_2(buffer, offered, needed, returned); } if (flags & PRINTER_ENUM_NAME) { - if (!strcmp(servername, temp)) - return enum_all_printers_info_2(temp, buffer, offered, needed, returned); + if (strequal(servername, temp)) + return enum_all_printers_info_2(buffer, offered, needed, returned); else return ERROR_INVALID_NAME; } @@ -2532,14 +2512,14 @@ uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 le /**************************************************************************** ****************************************************************************/ -static uint32 getprinter_level_0(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static uint32 getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_0 *printer=NULL; if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL) return ERROR_NOT_ENOUGH_MEMORY; - construct_printer_info_0(printer, snum, servername); + construct_printer_info_0(printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_0(printer); @@ -2564,14 +2544,14 @@ static uint32 getprinter_level_0(fstring servername, int snum, NEW_BUFFER *buffe /**************************************************************************** ****************************************************************************/ -static uint32 getprinter_level_1(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static uint32 getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_1 *printer=NULL; if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL) return ERROR_NOT_ENOUGH_MEMORY; - construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum); + construct_printer_info_1(PRINTER_ENUM_ICON8, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_1(printer); @@ -2596,17 +2576,14 @@ static uint32 getprinter_level_1(fstring servername, int snum, NEW_BUFFER *buffe /**************************************************************************** ****************************************************************************/ -static uint32 getprinter_level_2(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static uint32 getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_2 *printer=NULL; - fstring temp; if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL) return ERROR_NOT_ENOUGH_MEMORY; - fstrcpy(temp, "\\\\"); - fstrcat(temp, servername); - construct_printer_info_2(temp, printer, snum); + construct_printer_info_2(printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_2(printer); @@ -2634,14 +2611,12 @@ static uint32 getprinter_level_2(fstring servername, int snum, NEW_BUFFER *buffe /**************************************************************************** ****************************************************************************/ -static uint32 getprinter_level_3(fstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static uint32 getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_3 *printer=NULL; fstring temp; - fstrcpy(temp, "\\\\"); - fstrcat(temp, servername); - if (!construct_printer_info_3(temp, &printer, snum)) + if (!construct_printer_info_3(&printer, snum)) return ERROR_NOT_ENOUGH_MEMORY; /* check the required size. */ @@ -2671,24 +2646,21 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { int snum; - fstring servername; *needed=0; - pstrcpy(servername, global_myname); - if (!get_printer_snum(handle, &snum)) return ERROR_INVALID_HANDLE; switch (level) { case 0: - return getprinter_level_0(servername, snum, buffer, offered, needed); + return getprinter_level_0(snum, buffer, offered, needed); case 1: - return getprinter_level_1(servername,snum, buffer, offered, needed); + return getprinter_level_1(snum, buffer, offered, needed); case 2: - return getprinter_level_2(servername,snum, buffer, offered, needed); + return getprinter_level_2(snum, buffer, offered, needed); case 3: - return getprinter_level_3(servername,snum, buffer, offered, needed); + return getprinter_level_3(snum, buffer, offered, needed); default: return ERROR_INVALID_LEVEL; } @@ -2956,8 +2928,23 @@ static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fst status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status)); if (status != 0) { - free_a_printer(&printer,2); - return ERROR_UNKNOWN_PRINTER_DRIVER; + /* + * Is this a W2k client ? + */ + + if (version < 3) { + free_a_printer(&printer,2); + return ERROR_UNKNOWN_PRINTER_DRIVER; + } + + /* Yes - try again with a WinNT driver. */ + version = 2; + status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); + DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status)); + if (status != 0) { + free_a_printer(&printer,2); + return ERROR_UNKNOWN_PRINTER_DRIVER; + } } fill_printer_driver_info_6(info, driver, servername); @@ -3324,8 +3311,7 @@ static uint32 control_printer(POLICY_HND *handle, uint32 command, pipes_struct *p) { struct current_user user; - int snum; - int errcode = ERROR_INVALID_FUNCTION; + int snum, errcode = ERROR_INVALID_FUNCTION; Printer_entry *Printer = find_printer_index_by_hnd(handle); get_current_user(&user, p); @@ -3355,6 +3341,8 @@ static uint32 control_printer(POLICY_HND *handle, uint32 command, errcode = 0; } break; + default: + return ERROR_INVALID_LEVEL; } return errcode; @@ -3431,50 +3419,25 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level, /******************************************************************** Do Samba sanity checks on a printer info struct. + this has changed purpose: it now "canonicalises" printer + info from a client rather than just checking it is correct ********************************************************************/ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) { - /* - * Ensure that this printer is shared under the correct name - * as this is what Samba insists upon. - */ - - if (!(info->attributes & (PRINTER_ATTRIBUTE_SHARED|PRINTER_ATTRIBUTE_NETWORK))) { - DEBUG(10,("check_printer_ok: SHARED/NETWORK check failed (%x).\n", - (unsigned int)info->attributes )); - return False; - } - - if (!(info->attributes & PRINTER_ATTRIBUTE_RAW_ONLY)) { - /* NT forgets to set the raw attribute but sends the correct type. */ - if (strequal(info->datatype, "RAW")) - info->attributes |= PRINTER_ATTRIBUTE_RAW_ONLY; - else { - DEBUG(10,("check_printer_ok: RAW check failed (%x).\n", (unsigned int)info->attributes )); - return False; - } - } - - /* - * Sometimes the NT client doesn't set the sharename, but - * includes the sharename in the printername. This could - * cause SETPRINTER to fail which causes problems with the - * client getting confused between local/remote printers... - */ - - if (*info->sharename == '\0') { - char *p = strrchr(info->printername, '\\'); - if (p) - fstrcpy(info->sharename, p+1); - } - - if (!strequal(info->sharename, lp_servicename(snum))) { - DEBUG(10,("check_printer_ok: NAME check failed (%s) (%s).\n", - info->sharename, lp_servicename(snum))); - return False; - } + DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n", + info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location)); + /* we force some elements to "correct" values */ + slprintf(info->servername, sizeof(info->servername), "\\\\%s", global_myname); + slprintf(info->printername, sizeof(info->printername), "\\\\%s\\%s", + global_myname, lp_servicename(snum)); + fstrcpy(info->sharename, lp_servicename(snum)); + info->attributes = PRINTER_ATTRIBUTE_SHARED \ + | PRINTER_ATTRIBUTE_LOCAL \ + | PRINTER_ATTRIBUTE_RAW_ONLY \ + | PRINTER_ATTRIBUTE_QUEUED ; + return True; } @@ -3764,7 +3727,7 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level, */ convert_printer_info(info, printer, level); - + if (info->info_2->devmode_ptr != 0) { /* we have a valid devmode convert it and link it*/ @@ -3830,6 +3793,7 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level, done: free_a_printer(&printer, 2); + free_a_printer(&old_printer, 2); srv_spoolss_sendnotify(handle); @@ -3979,7 +3943,7 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, job_info->timeelapsed=0; job_info->pagesprinted=0; - if((job_info->devmode = construct_dev_mode(snum, global_myname)) == NULL) { + if((job_info->devmode = construct_dev_mode(snum)) == NULL) { free_a_printer(&ntprinter, 2); return False; } @@ -4131,17 +4095,12 @@ uint32 _spoolss_schedulejob( POLICY_HND *handle, uint32 jobid) /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_setjob( POLICY_HND *handle, - uint32 jobid, - uint32 level, - pipes_struct *p, - JOB_INFO *ctr, - uint32 command) - +uint32 _spoolss_setjob(POLICY_HND *handle, uint32 jobid, uint32 level, + pipes_struct *p, JOB_INFO *ctr, uint32 command) { struct current_user user; - int snum; print_status_struct prt_status; + int snum, errcode = ERROR_INVALID_FUNCTION; memset(&prt_status, 0, sizeof(prt_status)); @@ -4158,28 +4117,26 @@ uint32 _spoolss_setjob( POLICY_HND *handle, switch (command) { case JOB_CONTROL_CANCEL: case JOB_CONTROL_DELETE: - if (print_job_delete(&user, jobid)) { - srv_spoolss_sendnotify(handle); - return 0x0; + if (print_job_delete(&user, jobid, &errcode)) { + errcode = 0; } break; case JOB_CONTROL_PAUSE: - if (print_job_pause(&user, jobid)) { - srv_spoolss_sendnotify(handle); - return 0x0; + if (print_job_pause(&user, jobid, &errcode)) { + errcode = 0; } break; + case JOB_CONTROL_RESTART: case JOB_CONTROL_RESUME: - if (print_job_resume(&user, jobid)) { - srv_spoolss_sendnotify(handle); - return 0x0; + if (print_job_resume(&user, jobid, &errcode)) { + errcode = 0; } break; default: return ERROR_INVALID_LEVEL; } - return ERROR_INVALID_HANDLE; + return errcode; } /**************************************************************************** diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c index 3b509604686..944a187ccc9 100644 --- a/source/smbd/lanman.c +++ b/source/smbd/lanman.c @@ -1892,15 +1892,15 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param switch (function) { case 81: /* delete */ - if (print_job_delete(¤t_user, jobid)) + if (print_job_delete(¤t_user, jobid, &errcode)) errcode = NERR_Success; break; case 82: /* pause */ - if (print_job_pause(¤t_user, jobid)) + if (print_job_pause(¤t_user, jobid, &errcode)) errcode = NERR_Success; break; case 83: /* resume */ - if (print_job_resume(¤t_user, jobid)) + if (print_job_resume(¤t_user, jobid, &errcode)) errcode = NERR_Success; break; } diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c index 5532e687cee..362f7b4964a 100644 --- a/source/smbwrapper/smbw.c +++ b/source/smbwrapper/smbw.c @@ -390,6 +390,34 @@ int smbw_errno(struct cli_state *c) return ret; } +/* Return a username and password given a server and share name */ + +void get_envvar_auth_data(char *server, char *share, char **workgroup, + char **username, char **password) +{ + /* Fall back to shared memory/environment variables */ + + *username = smbw_getshared("USER"); + if (!*username) *username = getenv("USER"); + if (!*username) *username = "guest"; + + *workgroup = smbw_getshared("WORKGROUP"); + if (!*workgroup) *workgroup = lp_workgroup(); + + *password = smbw_getshared("PASSWORD"); + if (!*password) *password = ""; +} + +static smbw_get_auth_data_fn get_auth_data_fn = get_envvar_auth_data; + +/***************************************************** +set the get auth data function +******************************************************/ +void smbw_set_auth_data_fn(smbw_get_auth_data_fn fn) +{ + get_auth_data_fn = fn; +} + /***************************************************** return a connection to a server (existing or new) *******************************************************/ @@ -410,20 +438,13 @@ struct smbw_server *smbw_server(char *server, char *share) ip = ipzero; ZERO_STRUCT(c); - username = smbw_getshared("USER"); - if (!username) username = getenv("USER"); - if (!username) username = "guest"; - - workgroup = smbw_getshared("WORKGROUP"); - if (!workgroup) workgroup = lp_workgroup(); - - password = smbw_getshared("PASSWORD"); - if (!password) password = ""; - /* try to use an existing connection */ for (srv=smbw_srvs;srv;srv=srv->next) { if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0) return srv; + strcmp(share,srv->share_name)==0 && + strcmp(workgroup,srv->workgroup)==0 && + strcmp(username, srv->username) == 0) + return srv; } if (server[0] == 0) { @@ -434,6 +455,8 @@ struct smbw_server *smbw_server(char *server, char *share) make_nmb_name(&calling, global_myname, 0x0); make_nmb_name(&called , server, 0x20); + get_auth_data_fn(server, share, &workgroup, &username, &password); + DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server)); if ((p=strchr(server_n,'#')) && strcmp(p+1,"1D")==0) { @@ -539,6 +562,18 @@ struct smbw_server *smbw_server(char *server, char *share) goto failed; } + srv->workgroup = strdup(workgroup); + if (!srv->workgroup) { + errno = ENOMEM; + goto failed; + } + + srv->username = strdup(username); + if (!srv->username) { + errno = ENOMEM; + goto failed; + } + /* some programs play with file descriptors fairly intimately. We try to get out of the way by duping to a high fd number */ if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) { diff --git a/source/smbwrapper/smbw.h b/source/smbwrapper/smbw.h index 7241f8b3c55..d059b20c788 100644 --- a/source/smbwrapper/smbw.h +++ b/source/smbwrapper/smbw.h @@ -19,6 +19,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef _SMBW_H +#define _SMBW_H + #define SMBW_PREFIX "/smb/" #define SMBW_DUMMY "/dev/null" @@ -33,6 +36,8 @@ struct smbw_server { struct cli_state cli; char *server_name; char *share_name; + char *workgroup; + char *username; dev_t dev; BOOL no_pathinfo2; }; @@ -60,3 +65,8 @@ struct smbw_dir { char *path; }; +typedef void (*smbw_get_auth_data_fn)(char *server, char *share, + char **workgroup, char **username, + char **password); + +#endif /* _SMBW_H */ diff --git a/source/tdb/tdbutil.c b/source/tdb/tdbutil.c index ac7a5e2e909..92b8f9cbfb1 100644 --- a/source/tdb/tdbutil.c +++ b/source/tdb/tdbutil.c @@ -140,7 +140,7 @@ size_t tdb_pack(char *buf, int bufsize, char *fmt, ...) switch ((c = *fmt++)) { case 'w': len = 2; - w = va_arg(ap, uint16); + w = (uint16)va_arg(ap, int); if (bufsize >= len) { SSVAL(buf, 0, w); } diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c index 15188f6768f..2cdd85fae85 100644 --- a/source/utils/nmblookup.c +++ b/source/utils/nmblookup.c @@ -34,7 +34,7 @@ static struct in_addr bcast_addr; static BOOL recursion_desired = False; static BOOL translate_addresses = False; static int ServerFD= -1; -static int RootPort = 0; +static int RootPort = False; static BOOL find_status=False; /**************************************************************************** @@ -43,14 +43,14 @@ static BOOL find_status=False; static BOOL open_sockets(void) { ServerFD = open_socket_in( SOCK_DGRAM, - (RootPort ? 137 :0), - 3, + (RootPort ? 137 : 0), + (RootPort ? 0 : 3), interpret_addr(lp_socket_address()), True ); if (ServerFD == -1) return(False); - set_socket_options(ServerFD,"SO_BROADCAST"); + set_socket_options( ServerFD, "SO_BROADCAST" ); DEBUG(3, ("Socket opened.\n")); return True; @@ -200,7 +200,7 @@ int main(int argc,char *argv[]) pstrcpy(servicesf, optarg); break; case 'r': - RootPort = -1; + RootPort = True; break; case 'h': usage(); |