mirror of
https://github.com/samba-team/samba.git
synced 2025-01-13 13:18:06 +03:00
merge from APP_HEAD of winbindd's domain local group fix
(This used to be commit 09c6f6329d
)
This commit is contained in:
parent
641dd258ad
commit
bfa93735ab
source3
nsswitch
rpc_client
rpc_server
utils
@ -123,12 +123,18 @@ struct winbindd_methods {
|
||||
uint32 *num_entries,
|
||||
WINBIND_USERINFO **info);
|
||||
|
||||
/* get a list of groups */
|
||||
/* get a list of domain groups */
|
||||
NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32 *num_entries,
|
||||
struct acct_info **info);
|
||||
|
||||
/* get a list of domain local groups */
|
||||
NTSTATUS (*enum_local_groups)(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32 *num_entries,
|
||||
struct acct_info **info);
|
||||
|
||||
/* convert one user or group name to a sid */
|
||||
NTSTATUS (*name_to_sid)(struct winbindd_domain *domain,
|
||||
const char *name,
|
||||
|
@ -559,7 +559,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
|
||||
|
||||
if (!cache->tdb) goto do_query;
|
||||
|
||||
centry = wcache_fetch(cache, domain, "GL/%s", domain->name);
|
||||
centry = wcache_fetch(cache, domain, "GL/%s/domain", domain->name);
|
||||
if (!centry) goto do_query;
|
||||
|
||||
*num_entries = centry_uint32(centry);
|
||||
@ -599,13 +599,83 @@ do_query:
|
||||
centry_put_string(centry, (*info)[i].acct_desc);
|
||||
centry_put_uint32(centry, (*info)[i].rid);
|
||||
}
|
||||
centry_end(centry, "GL/%s", domain->name);
|
||||
centry_end(centry, "GL/%s/domain", domain->name);
|
||||
centry_free(centry);
|
||||
|
||||
skip_save:
|
||||
return status;
|
||||
}
|
||||
|
||||
/* list all domain groups */
|
||||
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32 *num_entries,
|
||||
struct acct_info **info)
|
||||
{
|
||||
struct winbind_cache *cache = get_cache(domain);
|
||||
struct cache_entry *centry = NULL;
|
||||
NTSTATUS status;
|
||||
int i;
|
||||
|
||||
if (!cache->tdb) goto do_query;
|
||||
|
||||
centry = wcache_fetch(cache, domain, "GL/%s/local", domain->name);
|
||||
if (!centry) goto do_query;
|
||||
|
||||
*num_entries = centry_uint32(centry);
|
||||
|
||||
if (*num_entries == 0) goto do_cached;
|
||||
|
||||
(*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
|
||||
if (! (*info)) smb_panic("enum_dom_groups out of memory");
|
||||
for (i=0; i<(*num_entries); i++) {
|
||||
fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
|
||||
fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
|
||||
(*info)[i].rid = centry_uint32(centry);
|
||||
}
|
||||
|
||||
do_cached:
|
||||
|
||||
/* If we are returning cached data and the domain controller
|
||||
is down then we don't know whether the data is up to date
|
||||
or not. Return NT_STATUS_MORE_PROCESSING_REQUIRED to
|
||||
indicate this. */
|
||||
|
||||
if (wcache_server_down(domain)) {
|
||||
DEBUG(10, ("query_user_list: returning cached user list and server was down\n"));
|
||||
status = NT_STATUS_MORE_PROCESSING_REQUIRED;
|
||||
} else
|
||||
status = centry->status;
|
||||
|
||||
centry_free(centry);
|
||||
return status;
|
||||
|
||||
do_query:
|
||||
*num_entries = 0;
|
||||
*info = NULL;
|
||||
|
||||
if (wcache_server_down(domain)) {
|
||||
return NT_STATUS_SERVER_DISABLED;
|
||||
}
|
||||
|
||||
status = cache->backend->enum_local_groups(domain, mem_ctx, num_entries, info);
|
||||
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, True);
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry) goto skip_save;
|
||||
centry_put_uint32(centry, *num_entries);
|
||||
for (i=0; i<(*num_entries); i++) {
|
||||
centry_put_string(centry, (*info)[i].acct_name);
|
||||
centry_put_string(centry, (*info)[i].acct_desc);
|
||||
centry_put_uint32(centry, (*info)[i].rid);
|
||||
}
|
||||
centry_end(centry, "GL/%s/local", domain->name);
|
||||
centry_free(centry);
|
||||
|
||||
skip_save:
|
||||
return status;
|
||||
}
|
||||
|
||||
/* convert a single name to a sid in a domain */
|
||||
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
@ -906,6 +976,7 @@ struct winbindd_methods cache_methods = {
|
||||
True,
|
||||
query_user_list,
|
||||
enum_dom_groups,
|
||||
enum_local_groups,
|
||||
name_to_sid,
|
||||
sid_to_name,
|
||||
query_user,
|
||||
|
@ -462,6 +462,15 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
|
||||
|
||||
if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
|
||||
result = NT_STATUS_PIPE_NOT_AVAILABLE;
|
||||
/*
|
||||
* only cache a failure if we are not trying to open the
|
||||
* **win2k** specific lsarpc UUID. This could be an NT PDC
|
||||
* and therefore a failure is normal. This should probably
|
||||
* be abstracted to a check for 2k specific pipes and wondering
|
||||
* if the PDC is an NT4 box. but since there is only one 2k
|
||||
* specific UUID right now, i'm not going to bother. --jerry
|
||||
*/
|
||||
if ( !is_win2k_pipe(pipe_index) )
|
||||
add_failed_connection_entry(new_conn, result);
|
||||
cli_shutdown(new_conn->cli);
|
||||
return result;
|
||||
@ -563,7 +572,7 @@ BOOL cm_check_for_native_mode_win2k( const char *domain )
|
||||
|
||||
if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) )
|
||||
{
|
||||
DEBUG(3, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
|
||||
DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n",
|
||||
domain, nt_errstr(result)));
|
||||
return False;
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
|
||||
{
|
||||
NTSTATUS status;
|
||||
uint32 num_entries;
|
||||
struct acct_info *name_list = NULL;
|
||||
struct acct_info *name_list = NULL, *tmp_name_list = NULL;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL result = False;
|
||||
struct acct_info *sam_grp_entries = NULL;
|
||||
@ -436,10 +436,9 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = domain->methods->enum_dom_groups(domain,
|
||||
mem_ctx,
|
||||
&num_entries,
|
||||
&sam_grp_entries);
|
||||
/* always get the domain global groups */
|
||||
|
||||
status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(3, ("get_sam_group_entries: could not enumerate domain groups! Error: %s", nt_errstr(status)));
|
||||
@ -450,12 +449,54 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
|
||||
/* Copy entries into return buffer */
|
||||
|
||||
if (num_entries) {
|
||||
name_list = malloc(sizeof(struct acct_info) * num_entries);
|
||||
memcpy(name_list, sam_grp_entries,
|
||||
num_entries * sizeof(struct acct_info));
|
||||
if ( !(name_list = malloc(sizeof(struct acct_info) * num_entries)) ) {
|
||||
DEBUG(0,("get_sam_group_entries: Failed to malloc memory for %d domain groups!\n",
|
||||
num_entries));
|
||||
result = False;
|
||||
goto done;
|
||||
}
|
||||
memcpy( name_list, sam_grp_entries, num_entries * sizeof(struct acct_info) );
|
||||
}
|
||||
|
||||
ent->num_sam_entries = num_entries;
|
||||
|
||||
/* get the domain local groups if we are a member of
|
||||
a native win2k domain */
|
||||
|
||||
if ( domain->native_mode )
|
||||
{
|
||||
DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n"));
|
||||
|
||||
status = domain->methods->enum_local_groups(domain, mem_ctx, &num_entries, &sam_grp_entries);
|
||||
|
||||
if ( !NT_STATUS_IS_OK(status) ) {
|
||||
DEBUG(3,("get_sam_group_entries: Failed to enumerate domain local groups!\n"));
|
||||
num_entries = 0;
|
||||
}
|
||||
else
|
||||
DEBUG(4,("get_sam_group_entries: Returned %d local groups\n", num_entries));
|
||||
|
||||
/* Copy entries into return buffer */
|
||||
|
||||
if ( num_entries ) {
|
||||
if ( !(tmp_name_list = Realloc( name_list, sizeof(struct acct_info) * (ent->num_sam_entries+num_entries))) )
|
||||
{
|
||||
DEBUG(0,("get_sam_group_entries: Failed to realloc more memory for %d local groups!\n",
|
||||
num_entries));
|
||||
result = False;
|
||||
SAFE_FREE( name_list );
|
||||
goto done;
|
||||
}
|
||||
|
||||
name_list = tmp_name_list;
|
||||
|
||||
memcpy( &name_list[ent->num_sam_entries], sam_grp_entries,
|
||||
num_entries * sizeof(struct acct_info) );
|
||||
}
|
||||
|
||||
ent->num_sam_entries += num_entries;
|
||||
}
|
||||
|
||||
|
||||
/* Fill in remaining fields */
|
||||
|
||||
|
@ -183,6 +183,65 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
|
||||
return status;
|
||||
}
|
||||
|
||||
/* List all domain groups */
|
||||
|
||||
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
uint32 *num_entries,
|
||||
struct acct_info **info)
|
||||
{
|
||||
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
|
||||
CLI_POLICY_HND *hnd;
|
||||
POLICY_HND dom_pol;
|
||||
NTSTATUS result;
|
||||
|
||||
*num_entries = 0;
|
||||
*info = NULL;
|
||||
|
||||
if ( !(hnd = cm_get_sam_handle(domain->name)) )
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
if ( !NT_STATUS_IS_OK(result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
|
||||
des_access, &domain->sid, &dom_pol)) )
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
do {
|
||||
struct acct_info *info2 = NULL;
|
||||
uint32 count = 0, start = *num_entries;
|
||||
TALLOC_CTX *mem_ctx2;
|
||||
|
||||
mem_ctx2 = talloc_init_named("enum_dom_local_groups[rpc]");
|
||||
|
||||
result = cli_samr_enum_als_groups( hnd->cli, mem_ctx2, &dom_pol,
|
||||
&start, 0xFFFF, &info2, &count);
|
||||
|
||||
if ( !NT_STATUS_IS_OK(result)
|
||||
&& !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
|
||||
{
|
||||
talloc_destroy(mem_ctx2);
|
||||
break;
|
||||
}
|
||||
|
||||
(*info) = talloc_realloc(mem_ctx, *info,
|
||||
sizeof(**info) * ((*num_entries) + count));
|
||||
if (! *info) {
|
||||
talloc_destroy(mem_ctx2);
|
||||
cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
|
||||
(*num_entries) += count;
|
||||
talloc_destroy(mem_ctx2);
|
||||
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
|
||||
|
||||
cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* convert a single name to a sid in a domain */
|
||||
static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
const char *name,
|
||||
@ -635,6 +694,7 @@ struct winbindd_methods msrpc_methods = {
|
||||
False,
|
||||
query_user_list,
|
||||
enum_dom_groups,
|
||||
enum_local_groups,
|
||||
name_to_sid,
|
||||
sid_to_name,
|
||||
query_user,
|
||||
|
@ -128,7 +128,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
|
||||
|
||||
if ( strequal( lp_workgroup(), domain_name) ) {
|
||||
domain->native_mode = cm_check_for_native_mode_win2k( domain_name );
|
||||
DEBUG(5,("add_trusted_domain: %s is a %s mode domain\n", domain_name,
|
||||
DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain_name,
|
||||
domain->native_mode ? "native" : "mixed" ));
|
||||
}
|
||||
|
||||
|
@ -983,6 +983,22 @@ char* get_pipe_name_from_index( const int pipe_index )
|
||||
return pipe_names[pipe_index].client_pipe;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Check to see if this pipe index points to one of
|
||||
the pipes only supported by Win2k
|
||||
****************************************************************************/
|
||||
|
||||
BOOL is_win2k_pipe( const int pipe_idx )
|
||||
{
|
||||
switch ( pipe_idx )
|
||||
{
|
||||
case PI_LSARPC_DS:
|
||||
return True;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
check the rpc bind acknowledge response
|
||||
****************************************************************************/
|
||||
|
@ -5603,23 +5603,17 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
|
||||
char *cmd = lp_addprinter_cmd();
|
||||
char **qlines;
|
||||
pstring command;
|
||||
pstring driverlocation;
|
||||
int numlines;
|
||||
int ret;
|
||||
int fd;
|
||||
fstring remote_machine = "%m";
|
||||
|
||||
/* build driver path... only 9X architecture is needed for legacy reasons */
|
||||
slprintf(driverlocation, sizeof(driverlocation)-1, "\\\\%s\\print$\\WIN40\\0",
|
||||
get_called_name());
|
||||
/* change \ to \\ for the shell */
|
||||
all_string_sub(driverlocation,"\\","\\\\",sizeof(pstring));
|
||||
standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
|
||||
|
||||
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
|
||||
cmd, printer->info_2->printername, printer->info_2->sharename,
|
||||
printer->info_2->portname, printer->info_2->drivername,
|
||||
printer->info_2->location, driverlocation, remote_machine);
|
||||
printer->info_2->location, printer->info_2->comment, remote_machine);
|
||||
|
||||
DEBUG(10,("Running [%s]\n", command));
|
||||
ret = smbrun(command, &fd);
|
||||
|
@ -175,6 +175,11 @@ static int profile_dump(void)
|
||||
d_printf("write_count: %u\n", profile_p->syscall_write_count);
|
||||
d_printf("write_time: %u\n", profile_p->syscall_write_time);
|
||||
d_printf("write_bytes: %u\n", profile_p->syscall_write_bytes);
|
||||
#ifdef HAVE_SENDFILE
|
||||
d_printf("sendfile_count: %u\n", profile_p->syscall_sendfile_count);
|
||||
d_printf("sendfile_time: %u\n", profile_p->syscall_sendfile_time);
|
||||
d_printf("sendfile_bytes: %u\n", profile_p->syscall_sendfile_bytes);
|
||||
#endif
|
||||
d_printf("lseek_count: %u\n", profile_p->syscall_lseek_count);
|
||||
d_printf("lseek_time: %u\n", profile_p->syscall_lseek_time);
|
||||
d_printf("rename_count: %u\n", profile_p->syscall_rename_count);
|
||||
|
Loading…
Reference in New Issue
Block a user