diff options
author | Gerald Carter <jerry@samba.org> | 2004-10-25 19:25:54 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2004-10-25 19:25:54 +0000 |
commit | 317ab676bf28d3922dc0fba02e908a766035872f (patch) | |
tree | d9ea00a371f92740e58b95991b4b56723454304d /source/rpc_server | |
parent | 943c0aaaeb5a24a9501a164e9a765384e8e8a2ff (diff) | |
download | samba-317ab676bf28d3922dc0fba02e908a766035872f.tar.gz samba-317ab676bf28d3922dc0fba02e908a766035872f.tar.xz samba-317ab676bf28d3922dc0fba02e908a766035872f.zip |
r3220: merging current 3.0 code to release branch
Diffstat (limited to 'source/rpc_server')
-rw-r--r-- | source/rpc_server/srv_netlog_nt.c | 4 | ||||
-rw-r--r-- | source/rpc_server/srv_spoolss_nt.c | 326 | ||||
-rw-r--r-- | source/rpc_server/srv_util.c | 323 |
3 files changed, 243 insertions, 410 deletions
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c index 3e0762fa43b..a3157435f37 100644 --- a/source/rpc_server/srv_netlog_nt.c +++ b/source/rpc_server/srv_netlog_nt.c @@ -486,8 +486,8 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * cred_hash3( pwd, q_u->pwd, p->dc.sess_key, 0); DEBUG(100,("Server password set : new given value was :\n")); - for(i = 0; i < 16; i++) - DEBUG(100,("%02X ", q_u->pwd[i])); + for(i = 0; i < sizeof(pwd); i++) + DEBUG(100,("%02X ", pwd[i])); DEBUG(100,("\n")); old_pw = pdb_get_nt_passwd(sampass); diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index e7b1fdb1d09..fad5555cea1 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -201,7 +201,7 @@ static void free_printer_entry(void *ptr) snum = -1; srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd); } else if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) { - snum = print_queue_snum(Printer->dev.handlename); + snum = print_queue_snum(Printer->sharename); if (snum != -1) srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd); @@ -277,17 +277,19 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd ****************************************************************************/ WERROR find_printer_in_print_hnd_cache( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 **info2, - const char *printername ) + const char *servername, const char *printername ) { Printer_entry *p; - DEBUG(10,("find_printer_in_print_hnd_cache: printer [%s]\n", printername)); + DEBUG(10,("find_printer_in_print_hnd_cache: printer [\\\\%s\\%s]\n", + servername, printername)); for ( p=printers_list; p; p=p->next ) { if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER && p->printer_info - && StrCaseCmp(p->dev.handlename, printername) == 0 ) + && strequal( p->sharename, printername ) + && strequal( p->servername, servername ) ) { DEBUG(10,("Found printer\n")); *info2 = dup_printer_2( ctx, p->printer_info->info_2 ); @@ -313,7 +315,7 @@ void invalidate_printer_hnd_cache( char *printername ) { if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER && p->printer_info - && StrCaseCmp(p->dev.handlename, printername)==0) + && StrCaseCmp(p->sharename, printername)==0) { DEBUG(10,("invalidating printer_info cache for handl:\n")); free_a_printer( &p->printer_info, 2 ); @@ -378,8 +380,8 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) } #endif - if (del_a_printer(Printer->dev.handlename) != 0) { - DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename)); + if (del_a_printer( Printer->sharename ) != 0) { + DEBUG(3,("Error deleting printer %s\n", Printer->sharename)); return WERR_BADFID; } @@ -389,9 +391,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) pstring command; int ret; - /* Printer->dev.handlename equals portname equals sharename */ - slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd, - Printer->dev.handlename); + pstr_sprintf(command, "%s \"%s\"", cmd, Printer->sharename); DEBUG(10,("Running [%s]\n", command)); ret = smbrun(command, NULL); @@ -406,7 +406,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) /* go ahead and re-read the services immediately */ reload_services( False ); - if ( lp_servicenumber( Printer->dev.handlename ) < 0 ) + if ( lp_servicenumber( Printer->sharename ) < 0 ) return WERR_ACCESS_DENIED; } @@ -427,14 +427,14 @@ static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number) } switch (Printer->printer_type) { - case PRINTER_HANDLE_IS_PRINTER: - DEBUG(4,("short name:%s\n", Printer->dev.handlename)); - *number = print_queue_snum(Printer->dev.handlename); - return (*number != -1); - case PRINTER_HANDLE_IS_PRINTSERVER: - return False; - default: - return False; + case PRINTER_HANDLE_IS_PRINTER: + DEBUG(4,("short name:%s\n", Printer->sharename)); + *number = print_queue_snum(Printer->sharename); + return (*number != -1); + case PRINTER_HANDLE_IS_PRINTSERVER: + return False; + default: + return False; } } @@ -475,6 +475,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) int snum; int n_services=lp_numservices(); char *aprinter, *printername; + const char *servername; fstring sname; BOOL found=False; NT_PRINTER_INFO_LEVEL *printer; @@ -482,28 +483,37 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename))); - if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) { - ZERO_STRUCT(Printer->dev.printerservername); - strncpy(Printer->dev.printerservername, handlename, strlen(handlename)); - return True; - } - - if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER) - return False; - - if (*handlename=='\\') { - aprinter=strchr_m(handlename+2, '\\'); - aprinter++; + aprinter = handlename; + if ( *handlename == '\\' ) { + servername = handlename + 2; + if ( (aprinter = strchr_m( handlename+2, '\\' )) != NULL ) { + *aprinter = '\0'; + aprinter++; + } } else { - aprinter=handlename; + servername = ""; } + + /* save the servername to fill in replies on this handle */ + + if ( !is_myname_or_ipaddr( servername ) ) + return False; - DEBUGADD(5, ("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter))); + fstrcpy( Printer->servername, servername ); + + if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) + return True; - /* have to search on sharename and PRINTER_INFO2->printername */ + if ( Printer->printer_type != PRINTER_HANDLE_IS_PRINTER ) + return False; - for (snum=0; snum<n_services; snum++) { + DEBUGADD(5, ("searching for [%s]\n", aprinter )); + + /* Search all sharenames first as this is easier than pulling + the printer_info_2 off of disk */ + + for (snum=0; !found && snum<n_services; snum++) { if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) ) continue; @@ -516,10 +526,25 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) if ( strequal(sname, aprinter) ) { found = True; - break; + } + } + + + /* do another loop to look for printernames */ + + for (snum=0; !found && snum<n_services; snum++) { + + /* no point in checking if this is not a printer or + we aren't allowing printername != sharename */ + + if ( !(lp_snum_ok(snum) + && lp_print_ok(snum) + && !lp_force_printername(snum)) ) + { + continue; } - /* ------ printername ------ */ + fstrcpy(sname, lp_servicename(snum)); printer = NULL; result = get_a_printer( NULL, &printer, 2, sname ); @@ -538,29 +563,24 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) } printername++; - + if ( strequal(printername, aprinter) ) { found = True; } DEBUGADD(10, ("printername: %s\n", printername)); - free_a_printer( &printer, 2); - - if ( found ) - break; + free_a_printer( &printer, 2); } - - if (!found) { + if ( !found ) { DEBUGADD(4,("Printer not found\n")); return False; } DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname)); - ZERO_STRUCT(Printer->dev.handlename); - fstrcpy(Printer->dev.handlename, sname); + fstrcpy(Printer->sharename, sname); return True; } @@ -696,10 +716,8 @@ static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type, } } - DEBUG(10, ("%s is not monitoring 0x%02x/0x%02x\n", - (p->printer_type == PRINTER_HANDLE_IS_PRINTER) ? - p->dev.handlename : p->dev.printerservername, - notify_type, notify_field)); + DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n", + p->servername, p->sharename, notify_type, notify_field)); return False; } @@ -995,13 +1013,13 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) if ( !p->notify.client_connected ) continue; - DEBUG(10,("Client connected! [%s]\n", p->dev.handlename)); + DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename)); /* For this printer? Print servers always receive notifications. */ if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) && - ( !strequal(msg_group->printername, p->dev.handlename) ) ) + ( !strequal(msg_group->printername, p->sharename) ) ) continue; DEBUG(10,("Our printer\n")); @@ -1027,7 +1045,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n", - msg->type, msg->field, p->dev.handlename)); + msg->type, msg->field, p->sharename)); /* * if the is a printer notification handle and not a job notification @@ -1323,7 +1341,7 @@ void update_monitored_printq_cache( void ) if ( (printer->printer_type == PRINTER_HANDLE_IS_PRINTER) && printer->notify.client_connected ) { - snum = print_queue_snum(printer->dev.handlename); + snum = print_queue_snum(printer->sharename); print_queue_status( snum, NULL, NULL ); } @@ -1619,9 +1637,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, return WERR_INVALID_PRINTER_NAME; Printer=find_printer_index_by_hnd(p, handle); - if (!Printer) { - DEBUG(0,(" _spoolss_open_printer_ex: logic error. \ -Can't find printer handle we created for printer %s\n", name )); + if ( !Printer ) { + DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer " + "handle we created for printer %s\n", name )); close_printer_handle(p,handle); return WERR_INVALID_PRINTER_NAME; } @@ -1765,10 +1783,11 @@ Can't find printer handle we created for printer %s\n", name )); if ( (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER) && q_u->printer_default.devmode_cont.devmode_ptr ) { - convert_devicemode( Printer->dev.handlename, q_u->printer_default.devmode_cont.devmode, + convert_devicemode( Printer->sharename, q_u->printer_default.devmode_cont.devmode, &Printer->nt_devmode ); } +#if 0 /* JERRY -- I'm doubtful this is really effective */ /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN optimization in Windows 2000 clients --jerry */ @@ -1778,6 +1797,7 @@ Can't find printer handle we created for printer %s\n", name )); DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n")); sys_usleep( 500000 ); } +#endif return WERR_OK; } @@ -1983,6 +2003,7 @@ static int get_version_id (char * arch) {"Windows NT Alpha_AXP", "W32ALPHA", 2 }, {"Windows NT PowerPC", "W32PPC", 2 }, {"Windows IA64", "IA64", 3 }, + {"Windows x64", "x64", 3 }, {NULL, "", -1 } }; @@ -2747,12 +2768,10 @@ void spoolss_notify_server_name(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp_name, temp; + pstring temp; uint32 len; - slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name()); - - len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push(temp, printer->info_2->servername, sizeof(temp)-2, STR_TERMINATE); data->notify_data.data.length = len; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); @@ -3486,6 +3505,7 @@ static const struct s_notify_info_data_table notify_info_data_table[] = { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages }, { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed }, { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size }, +{ PRINT_TABLE_END, 0x0, NULL, 0x0, NULL }, }; /******************************************************************* @@ -3551,7 +3571,7 @@ static int search_notify(uint16 type, uint16 field, int *value) { int i; - for (i = 0; i < sizeof(notify_info_data_table); i++) { + for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) { if (notify_info_data_table[i].type == type && notify_info_data_table[i].field == field && notify_info_data_table[i].fn != NULL) { @@ -3979,7 +3999,7 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p init_unistr(&printer->printername, chaine); - slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_called_name()); + slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_server_name(print_hnd)); init_unistr(&printer->servername, chaine); printer->cjobs = count; @@ -4444,6 +4464,7 @@ static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, ui return WERR_INVALID_NAME; } +#if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */ /******************************************************************** enum_all_printers_info_1_remote. *********************************************************************/ @@ -4458,9 +4479,10 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, /* JFM: currently it's more a place holder than anything else. * In the spooler world there is a notion of server registration. - * the print servers are registring (sp ?) on the PDC (in the same domain) + * the print servers are registered on the PDC (in the same domain) * - * We should have a TDB here. The registration is done thru an undocumented RPC call. + * We should have a TDB here. The registration is done thru an + * undocumented RPC call. */ if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL) @@ -4468,8 +4490,8 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, *returned=1; - slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", get_called_name()); - slprintf(desc, sizeof(desc)-1,"%s", get_called_name()); + slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name); + slprintf(desc, sizeof(desc)-1,"%s", name); slprintf(comment, sizeof(comment)-1, "Logged on Domain"); init_unistr(&printer->description, desc); @@ -4499,6 +4521,8 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, return WERR_OK; } +#endif + /******************************************************************** enum_all_printers_info_1_network. *********************************************************************/ @@ -4605,8 +4629,10 @@ static WERROR enumprinters_level1( uint32 flags, fstring name, if (flags & PRINTER_ENUM_NAME) return enum_all_printers_info_1_name(name, buffer, offered, needed, returned); +#if 0 /* JERRY - disabled for now */ if (flags & PRINTER_ENUM_REMOTE) return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned); +#endif if (flags & PRINTER_ENUM_NETWORK) return enum_all_printers_info_1_network(name, buffer, offered, needed, returned); @@ -5543,6 +5569,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_ uint32 *needed = &r_u->needed; uint32 *servermajorversion = &r_u->servermajorversion; uint32 *serverminorversion = &r_u->serverminorversion; + Printer_entry *printer; fstring servername; fstring architecture; @@ -5554,11 +5581,16 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_ DEBUG(4,("_spoolss_getprinterdriver2\n")); + if ( !(printer = find_printer_index_by_hnd( p, handle )) ) { + DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n")); + return WERR_INVALID_PRINTER_NAME; + } + *needed = 0; *servermajorversion = 0; *serverminorversion = 0; - fstrcpy(servername, get_called_name()); + fstrcpy(servername, get_server_name( printer )); unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1); if (!get_printer_snum(p, handle, &snum)) @@ -5840,11 +5872,9 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level, } /* NT seems to like setting the security descriptor even though - nothing may have actually changed. This causes annoying - dialog boxes when the user doesn't have permission to change - the security descriptor. */ + nothing may have actually changed. */ - nt_printing_getsec(p->mem_ctx, Printer->dev.handlename, &old_secdesc_ctr); + nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr); if (DEBUGLEVEL >= 10) { SEC_ACL *the_acl; @@ -5903,7 +5933,7 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level, goto done; } - result = nt_printing_setsec(Printer->dev.handlename, new_secdesc_ctr); + result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr); done: @@ -5911,9 +5941,12 @@ static WERROR 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 + Canonicalize printer info from a client + + ATTN: It does not matter what we set the servername to hear + since we do the necessary work in get_a_printer() to set it to + the correct value based on what the client sent in the + _spoolss_open_printer_ex(). ********************************************************************/ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) @@ -5921,25 +5954,35 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) fstring printername; const char *p; - 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)); + 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)-1, "\\\\%s", get_called_name()); + slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname()); fstrcpy(info->sharename, lp_servicename(snum)); - /* make sure printername is in \\server\printername format */ + /* check to see if we allow printername != sharename */ + + if ( lp_force_printername(snum) ) { + slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", + global_myname(), info->sharename ); + } else { + + /* make sure printername is in \\server\printername format */ - fstrcpy( printername, info->printername ); - p = printername; - if ( printername[0] == '\\' && printername[1] == '\\' ) { - if ( (p = strchr_m( &printername[2], '\\' )) != NULL ) - p++; + fstrcpy( printername, info->printername ); + p = printername; + if ( printername[0] == '\\' && printername[1] == '\\' ) { + if ( (p = strchr_m( &printername[2], '\\' )) != NULL ) + p++; + } + + slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", + global_myname(), p ); } - - slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", - get_called_name(), p ); - + info->attributes |= PRINTER_ATTRIBUTE_SAMBA; info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA; @@ -6322,18 +6365,16 @@ WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u ****************************************************************************/ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue, - int position, int snum) + int position, int snum, + NT_PRINTER_INFO_LEVEL *ntprinter) { - pstring temp_name; - struct tm *t; t=gmtime(&queue->time); - slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name()); job_info->jobid=queue->job; init_unistr(&job_info->printername, lp_servicename(snum)); - init_unistr(&job_info->machinename, temp_name); + init_unistr(&job_info->machinename, ntprinter->info_2->servername); init_unistr(&job_info->username, queue->fs_user); init_unistr(&job_info->document, queue->fs_file); init_unistr(&job_info->datatype, "RAW"); @@ -6355,17 +6396,15 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *ntprinter, DEVICEMODE *devmode) { - pstring temp_name; struct tm *t; t=gmtime(&queue->time); - slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name()); job_info->jobid=queue->job; init_unistr(&job_info->printername, ntprinter->info_2->printername); - init_unistr(&job_info->machinename, temp_name); + init_unistr(&job_info->machinename, ntprinter->info_2->servername); init_unistr(&job_info->username, queue->fs_user); init_unistr(&job_info->document, queue->fs_file); init_unistr(&job_info->notifyname, queue->fs_user); @@ -6398,6 +6437,7 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, ****************************************************************************/ static WERROR enumjobs_level1(print_queue_struct *queue, int snum, + NT_PRINTER_INFO_LEVEL *ntprinter, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { @@ -6412,7 +6452,7 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum, } for (i=0; i<*returned; i++) - fill_job_info_1(&info[i], &queue[i], i, snum); + fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter ); SAFE_FREE(queue); @@ -6445,10 +6485,10 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum, ****************************************************************************/ static WERROR enumjobs_level2(print_queue_struct *queue, int snum, + NT_PRINTER_INFO_LEVEL *ntprinter, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; JOB_INFO_2 *info = NULL; int i; WERROR result; @@ -6460,12 +6500,6 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum, result = WERR_NOMEM; goto done; } - - result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); - if (!W_ERROR_IS_OK(result)) { - *returned = 0; - goto done; - } /* this should not be a failure condition if the devmode is NULL */ @@ -6523,7 +6557,7 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; WERROR wret; - + NT_PRINTER_INFO_LEVEL *ntprinter = NULL; int snum; print_status_struct prt_status; print_queue_struct *queue=NULL; @@ -6537,9 +6571,15 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO *needed=0; *returned=0; + /* lookup the printer snum and tdb entry */ + if (!get_printer_snum(p, handle, &snum)) return WERR_BADFID; + wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); + if ( !W_ERROR_IS_OK(wret) ) + return wret; + *returned = print_queue_status(snum, &queue, &prt_status); DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message)); @@ -6550,16 +6590,19 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO switch (level) { case 1: - wret = enumjobs_level1(queue, snum, buffer, offered, needed, returned); + wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned); return wret; case 2: - wret = enumjobs_level2(queue, snum, buffer, offered, needed, returned); + wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned); return wret; default: SAFE_FREE(queue); *returned=0; - return WERR_UNKNOWN_LEVEL; + wret = WERR_UNKNOWN_LEVEL; } + + free_a_printer( &ntprinter, 2 ); + return wret; } /**************************************************************************** @@ -6587,7 +6630,7 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u return WERR_BADFID; } - if (!print_job_exists(snum, jobid)) { + if (!print_job_exists(lp_const_servicename(snum), jobid)) { return WERR_INVALID_PRINTER_NAME; } @@ -6866,7 +6909,6 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u) { - UNISTR2 *environment = &q_u->environment; uint32 level = q_u->level; NEW_BUFFER *buffer = NULL; uint32 offered = q_u->offered; @@ -6882,11 +6924,14 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS buffer = r_u->buffer; DEBUG(4,("_spoolss_enumprinterdrivers\n")); - fstrcpy(servername, get_called_name()); *needed=0; *returned=0; - unistr2_to_ascii(architecture, environment, sizeof(architecture)-1); + unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)-1); + unistr2_to_ascii(servername, &q_u->name, sizeof(servername)-1); + + if ( !is_myname_or_ipaddr( servername ) ) + return WERR_UNKNOWN_PRINTER_DRIVER; switch (level) { case 1: @@ -7387,7 +7432,10 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_ } } - slprintf(name, sizeof(name)-1, "\\\\%s\\%s", get_called_name(), + /* use our primary netbios name since get_a_printer() will convert + it to what the client expects on a case by case basis */ + + slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(), printer->info_2->sharename); @@ -7659,18 +7707,32 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen { pstring path; pstring long_archi; + fstring servername; + char *pservername; const char *short_archi; DRIVER_DIRECTORY_1 *info=NULL; + unistr2_to_ascii(servername, name, sizeof(servername)-1); unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); + /* check for beginning double '\'s and that the server + long enough */ + + pservername = servername; + if ( *pservername == '\\' && strlen(servername)>2 ) { + pservername += 2; + } + + if ( !is_myname_or_ipaddr( pservername ) ) + return WERR_INVALID_PARAM; + if (!(short_archi = get_short_archi(long_archi))) return WERR_INVALID_ENVIRONMENT; if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL) return WERR_NOMEM; - slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi); + slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", pservername, short_archi); DEBUG(4,("printer driver directory: [%s]\n", path)); @@ -8496,7 +8558,10 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_ /**************************************************************************** ****************************************************************************/ -static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, + NT_PRINTER_INFO_LEVEL *ntprinter, + uint32 jobid, NEW_BUFFER *buffer, uint32 offered, + uint32 *needed) { int i=0; BOOL found=False; @@ -8519,7 +8584,7 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, ui return WERR_INVALID_PARAM; } - fill_job_info_1(info_1, &((*queue)[i-1]), i, snum); + fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter ); *needed += spoolss_size_job_info_1(info_1); @@ -8541,12 +8606,14 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, ui /**************************************************************************** ****************************************************************************/ -static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, + NT_PRINTER_INFO_LEVEL *ntprinter, + uint32 jobid, NEW_BUFFER *buffer, uint32 offered, + uint32 *needed) { int i = 0; BOOL found = False; JOB_INFO_2 *info_2; - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; WERROR ret; DEVICEMODE *devmode = NULL; NT_DEVICEMODE *nt_devmode = NULL; @@ -8574,17 +8641,13 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, ui goto done; } - ret = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum)); - if (!W_ERROR_IS_OK(ret)) - goto done; - /* * if the print job does not have a DEVMODE associated with it, * just use the one for the printer. A NULL devicemode is not * a failure condition */ - if ( !(nt_devmode=print_job_devmode( snum, jobid )) ) + if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) ) devmode = construct_dev_mode(snum); else { if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) != NULL) { @@ -8616,7 +8679,6 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, ui free_job_info_2(info_2); /* Also frees devmode */ SAFE_FREE(info_2); - free_a_printer(&ntprinter, 2); return ret; } @@ -8633,7 +8695,7 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; WERROR wstatus = WERR_OK; - + NT_PRINTER_INFO_LEVEL *ntprinter = NULL; int snum; int count; print_queue_struct *queue = NULL; @@ -8650,6 +8712,10 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ if (!get_printer_snum(p, handle, &snum)) return WERR_BADFID; + wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); + if ( !W_ERROR_IS_OK(wstatus) ) + return wstatus; + count = print_queue_status(snum, &queue, &prt_status); DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n", @@ -8657,11 +8723,11 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ switch ( level ) { case 1: - wstatus = getjob_level_1(&queue, count, snum, jobid, + wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid, buffer, offered, needed); break; case 2: - wstatus = getjob_level_2(&queue, count, snum, jobid, + wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid, buffer, offered, needed); break; default: @@ -8670,6 +8736,8 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_ } SAFE_FREE(queue); + free_a_printer( &ntprinter, 2 ); + return wstatus; } diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c index 5bb8db4e062..ce8e02fae79 100644 --- a/source/rpc_server/srv_util.c +++ b/source/rpc_server/srv_util.c @@ -3,7 +3,8 @@ * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1998 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - * Copyright (C) Paul Ashton 1997-1998. + * Copyright (C) Paul Ashton 1997-1998, + * Copyright (C) Andrew Bartlett 2004. * * 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 @@ -46,7 +47,7 @@ * and groups. */ -rid_name builtin_alias_rids[] = +static const rid_name builtin_alias_rids[] = { { BUILTIN_ALIAS_RID_ADMINS , "Administrators" }, { BUILTIN_ALIAS_RID_USERS , "Users" }, @@ -62,7 +63,7 @@ rid_name builtin_alias_rids[] = }; /* array lookup of well-known Domain RID users. */ -rid_name domain_user_rids[] = +static const rid_name domain_user_rids[] = { { DOMAIN_USER_RID_ADMIN , "Administrator" }, { DOMAIN_USER_RID_GUEST , "Guest" }, @@ -70,7 +71,7 @@ rid_name domain_user_rids[] = }; /* array lookup of well-known Domain RID groups. */ -rid_name domain_group_rids[] = +static const rid_name domain_group_rids[] = { { DOMAIN_GROUP_RID_ADMINS , "Domain Admins" }, { DOMAIN_GROUP_RID_USERS , "Domain Users" }, @@ -98,17 +99,6 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui BOOL ret; BOOL winbind_groups_exist; - /* - * this code is far from perfect. - * first it enumerates the full /etc/group and that can be slow. - * second, it works only with users' SIDs - * whereas the day we support nested groups, it will have to - * support both users's SIDs and domain groups' SIDs - * - * having our own ldap backend would be so much faster ! - * we're far from that, but hope one day ;-) JFM. - */ - *prids=NULL; *numgroups=0; @@ -136,11 +126,8 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui return NT_STATUS_UNSUCCESSFUL; } - become_root(); - /* on some systems this must run as root */ - num_groups = getgroups_user(user_name, &groups); - unbecome_root(); - if (num_groups == -1) { + ret = getgroups_user(user_name, &groups, &num_groups); + if (!ret) { /* this should never happen */ DEBUG(2,("get_alias_user_groups: getgroups_user failed\n")); pdb_free_sam(&sam_pass); @@ -272,115 +259,57 @@ done: ********************************************************************/ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SAM_ACCOUNT *sam_pass) { - GROUP_MAP *map=NULL; - int i, num, num_entries, cur_gid=0; - struct group *grp; - DOM_GID *gids; - fstring user_name; - uint32 grid; - uint32 tmp_rid; - BOOL ret; - - *numgroups= 0; - - fstrcpy(user_name, pdb_get_username(sam_pass)); - grid=pdb_get_group_rid(sam_pass); - - DEBUG(10,("get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name)); - - /* we must wrap this is become/unbecome root for ldap backends */ - - become_root(); - /* first get the list of the domain groups */ - ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED); - - unbecome_root(); - /* end wrapper for group enumeration */ + const char *username = pdb_get_username(sam_pass); + int n_unix_groups; + int i,j; + gid_t *unix_groups; + *numgroups = 0; + *pgids = NULL; - if ( !ret ) + if (!getgroups_user(username, &unix_groups, &n_unix_groups)) { return False; - - DEBUG(10,("get_domain_user_groups: there are %d mapped groups\n", num_entries)); - - - /* - * alloc memory. In the worse case, we alloc memory for nothing. - * but I prefer to alloc for nothing - * than reallocing everytime. - */ - gids = (DOM_GID *)talloc(ctx, sizeof(DOM_GID) * num_entries); + } - /* for each group, check if the user is a member of. Only include groups - from this domain */ + /* now setup the space for storing the SIDS */ - for(i=0; i<num_entries; i++) { + if (n_unix_groups > 0) { - if ( !sid_check_is_in_our_domain(&map[i].sid) ) { - DEBUG(10,("get_domain_user_groups: skipping check of %s since it is not in our domain\n", - map[i].nt_name)); - continue; - } - - if ((grp=getgrgid(map[i].gid)) == NULL) { - /* very weird !!! */ - DEBUG(5,("get_domain_user_groups: gid %d doesn't exist anymore !\n", (int)map[i].gid)); - continue; - } - - for(num=0; grp->gr_mem[num]!=NULL; num++) { - if(strcmp(grp->gr_mem[num], user_name)==0) { - /* we found the user, add the group to the list */ - sid_peek_rid(&map[i].sid, &(gids[cur_gid].g_rid)); - gids[cur_gid].attr=7; - DEBUG(10,("get_domain_user_groups: user found in group %s\n", map[i].nt_name)); - cur_gid++; - break; - } + *pgids = talloc(ctx, sizeof(DOM_GID) * n_unix_groups); + + if (!*pgids) { + DEBUG(0, ("get_user_group: malloc() failed for DOM_GID list!\n")); + SAFE_FREE(unix_groups); + return False; } } - /* we have checked the groups */ - /* we must now check the gid of the user or the primary group rid, that's the same */ - for (i=0; i<cur_gid && grid!=gids[i].g_rid; i++) - ; - - /* the user's gid is already there */ - if (i!=cur_gid) { - /* - * the primary group of the user but be the first one in the list - * don't ask ! JFM. - */ - gids[i].g_rid=gids[0].g_rid; - gids[0].g_rid=grid; - goto done; - } - - for(i=0; i<num_entries; i++) { - sid_peek_rid(&map[i].sid, &tmp_rid); - if (tmp_rid==grid) { - /* - * the primary group of the user but be the first one in the list - * don't ask ! JFM. - */ - gids[cur_gid].g_rid=gids[0].g_rid; - gids[0].g_rid=tmp_rid; - gids[cur_gid].attr=7; - DEBUG(10,("get_domain_user_groups: primary gid of user found in group %s\n", map[i].nt_name)); - cur_gid++; - goto done; /* leave the loop early */ + become_root(); + j = 0; + for (i = 0; i < n_unix_groups; i++) { + GROUP_MAP map; + uint32 rid; + + if (!pdb_getgrgid(&map, unix_groups[i])) { + DEBUG(3, ("get_user_groups: failed to convert gid %ld to a domain group!\n", + (long int)unix_groups[i+1])); + if (i == 0) { + DEBUG(1,("get_domain_user_groups: primary gid of user [%s] is not a Domain group !\n", username)); + DEBUGADD(1,("get_domain_user_groups: You should fix it, NT doesn't like that\n")); + } + } else if ((map.sid_name_use == SID_NAME_DOM_GRP) + && sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)) { + (*pgids)[j].attr=7; + (*pgids)[j].g_rid=rid; + j++; } } + unbecome_root(); - DEBUG(0,("get_domain_user_groups: primary gid of user [%s] is not a Domain group !\n", user_name)); - DEBUGADD(0,("get_domain_user_groups: You should fix it, NT doesn't like that\n")); - + *numgroups = j; - done: - *pgids=gids; - *numgroups=cur_gid; - SAFE_FREE(map); + SAFE_FREE(unix_groups); return True; } @@ -414,167 +343,3 @@ NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid, return NT_STATUS_OK; } -/******************************************************************* - Look up a local (domain) rid and return a name and type. - ********************************************************************/ -NTSTATUS local_lookup_group_name(uint32 rid, char *group_name, uint32 *type) -{ - int i = 0; - (*type) = SID_NAME_DOM_GRP; - - DEBUG(5,("lookup_group_name: rid: %d", rid)); - - while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0) - { - i++; - } - - if (domain_group_rids[i].rid != 0) - { - fstrcpy(group_name, domain_group_rids[i].name); - DEBUG(5,(" = %s\n", group_name)); - return NT_STATUS_OK; - } - - DEBUG(5,(" none mapped\n")); - return NT_STATUS_NONE_MAPPED; -} - -/******************************************************************* - Look up a local alias rid and return a name and type. - ********************************************************************/ -NTSTATUS local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type) -{ - int i = 0; - (*type) = SID_NAME_WKN_GRP; - - DEBUG(5,("lookup_alias_name: rid: %d", rid)); - - while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0) - { - i++; - } - - if (builtin_alias_rids[i].rid != 0) - { - fstrcpy(alias_name, builtin_alias_rids[i].name); - DEBUG(5,(" = %s\n", alias_name)); - return NT_STATUS_OK; - } - - DEBUG(5,(" none mapped\n")); - return NT_STATUS_NONE_MAPPED; -} - - -#if 0 /*Nobody uses this function just now*/ -/******************************************************************* - Look up a local user rid and return a name and type. - ********************************************************************/ -NTSTATUS local_lookup_user_name(uint32 rid, char *user_name, uint32 *type) -{ - SAM_ACCOUNT *sampwd=NULL; - int i = 0; - BOOL ret; - - (*type) = SID_NAME_USER; - - DEBUG(5,("lookup_user_name: rid: %d", rid)); - - /* look up the well-known domain user rids first */ - while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0) - { - i++; - } - - if (domain_user_rids[i].rid != 0) { - fstrcpy(user_name, domain_user_rids[i].name); - DEBUG(5,(" = %s\n", user_name)); - return NT_STATUS_OK; - } - - pdb_init_sam(&sampwd); - - /* ok, it's a user. find the user account */ - become_root(); - ret = pdb_getsampwrid(sampwd, rid); - unbecome_root(); - - if (ret == True) { - fstrcpy(user_name, pdb_get_username(sampwd) ); - DEBUG(5,(" = %s\n", user_name)); - pdb_free_sam(&sampwd); - return NT_STATUS_OK; - } - - DEBUG(5,(" none mapped\n")); - pdb_free_sam(&sampwd); - return NT_STATUS_NONE_MAPPED; -} - -#endif - -/******************************************************************* - Look up a local (domain) group name and return a rid - ********************************************************************/ -NTSTATUS local_lookup_group_rid(char *group_name, uint32 *rid) -{ - const char *grp_name; - int i = -1; /* start do loop at -1 */ - - do /* find, if it exists, a group rid for the group name*/ - { - i++; - (*rid) = domain_group_rids[i].rid; - grp_name = domain_group_rids[i].name; - - } while (grp_name != NULL && !strequal(grp_name, group_name)); - - return (grp_name != NULL) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED; -} - -/******************************************************************* - Look up a local (BUILTIN) alias name and return a rid - ********************************************************************/ -NTSTATUS local_lookup_alias_rid(const char *alias_name, uint32 *rid) -{ - const char *als_name; - int i = -1; /* start do loop at -1 */ - - do /* find, if it exists, a alias rid for the alias name*/ - { - i++; - (*rid) = builtin_alias_rids[i].rid; - als_name = builtin_alias_rids[i].name; - - } while (als_name != NULL && !strequal(als_name, alias_name)); - - return (als_name != NULL) ? NT_STATUS_OK : NT_STATUS_NONE_MAPPED; -} - -/******************************************************************* - Look up a local user name and return a rid - ********************************************************************/ -NTSTATUS local_lookup_user_rid(char *user_name, uint32 *rid) -{ - SAM_ACCOUNT *sampass=NULL; - BOOL ret; - - (*rid) = 0; - - pdb_init_sam(&sampass); - - /* find the user account */ - become_root(); - ret = pdb_getsampwnam(sampass, user_name); - unbecome_root(); - - if (ret == True) { - (*rid) = pdb_get_user_rid(sampass); - pdb_free_sam(&sampass); - return NT_STATUS_OK; - } - - pdb_free_sam(&sampass); - return NT_STATUS_NONE_MAPPED; -} |