diff -ur ../../samba-2.2.8/source/lib/access.c ./lib/access.c --- ../../samba-2.2.8/source/lib/access.c Sat Mar 15 08:34:47 2003 +++ source/lib/access.c Fri Apr 4 16:02:42 2003 @@ -33,7 +33,7 @@ if (strlen(slash + 1) > 2) { mask = interpret_addr(slash + 1); } else { - mask = (uint32)((ALLONES << atoi(slash + 1)) ^ ALLONES); + mask = (uint32)((ALLONES >> atoi(slash + 1)) ^ ALLONES); } if (net == INADDR_NONE || mask == INADDR_NONE) { diff -ur ../../samba-2.2.8/source/lib/util_sid.c ./lib/util_sid.c --- ../../samba-2.2.8/source/lib/util_sid.c Sat Mar 15 08:34:47 2003 +++ source/lib/util_sid.c Sun Apr 6 16:58:34 2003 @@ -472,7 +472,7 @@ Return the last rid from the end of a sid *****************************************************************/ -BOOL sid_peek_rid(DOM_SID *sid, uint32 *rid) +BOOL sid_peek_rid(const DOM_SID *sid, uint32 *rid) { if (sid->num_auths > 0) { *rid = sid->sub_auths[sid->num_auths - 1]; @@ -482,6 +482,25 @@ } /***************************************************************** + Return the last rid from the end of a sid + and check the sid against the exp_dom_sid +*****************************************************************/ + +BOOL sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *rid) +{ + if (!exp_dom_sid || !sid || !rid) + return False; + + + if (sid_compare_domain(exp_dom_sid, sid)!=0){ + *rid=(-1); + return False; + } + + return sid_peek_rid(sid, rid); +} + +/***************************************************************** Copies a sid *****************************************************************/ diff -ur ../../samba-2.2.8/source/libsmb/libsmbclient.c ./libsmb/libsmbclient.c --- ../../samba-2.2.8/source/libsmb/libsmbclient.c Sat Mar 1 02:56:19 2003 +++ source/libsmb/libsmbclient.c Mon Apr 7 14:23:44 2003 @@ -2423,7 +2423,7 @@ /* Try to open the file for reading ... */ - if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { + if ((int)(fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); return -1; /* smbc_open sets errno */ @@ -2432,7 +2432,7 @@ /* Now, try to open the printer file for writing */ - if ((fid2 = smbc_open_print_job(printq)) < 0) { + if ((int)(fid2 = smbc_open_print_job(printq)) < 0) { saverr = errno; /* Save errno */ smbc_close(fid1); diff -ur ../../samba-2.2.8/source/locking/brlock.c ./locking/brlock.c --- ../../samba-2.2.8/source/locking/brlock.c Sat Mar 1 02:56:19 2003 +++ source/locking/brlock.c Mon Apr 7 14:23:44 2003 @@ -414,7 +414,9 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - BOOL remove_pending_locks_only) + BOOL remove_pending_locks_only, + void (*pre_unlock_fn)(void *), + void *pre_unlock_data) { TDB_DATA kbuf, dbuf; int count, i, j; @@ -450,6 +452,10 @@ lock->fnum == fnum && lock->start == start && lock->size == size) { + + if (pre_unlock_fn) + (*pre_unlock_fn)(pre_unlock_data); + /* found it - delete it */ if (count == 1) { tdb_delete(tdb, kbuf); @@ -483,6 +489,11 @@ continue; if (lock->lock_type != PENDING_LOCK) { + + /* Do any POSIX unlocks needed. */ + if (pre_unlock_fn) + (*pre_unlock_fn)(pre_unlock_data); + /* Send unlock messages to any pending waiters that overlap. */ for (j=0; jdev, fsp->inode, fsp->fnum, lock_pid, sys_getpid(), conn->cnum, - offset, count, False); + offset, count, False, + NULL, NULL); } } } @@ -177,6 +178,25 @@ return ret; } +/* Struct passed to brl_unlock. */ +struct posix_unlock_data_struct { + files_struct *fsp; + SMB_BIG_UINT offset; + SMB_BIG_UINT count; +}; + +/**************************************************************************** + Function passed to brl_unlock to allow POSIX unlock to be done first. +****************************************************************************/ + +static void posix_unlock(void *pre_data) +{ + struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data; + + if (lp_posix_locking(SNUM(pdata->fsp->conn))) + release_posix_lock(pdata->fsp, pdata->offset, pdata->count); +} + /**************************************************************************** Utility function called by unlocking requests. ****************************************************************************/ @@ -185,6 +205,7 @@ SMB_BIG_UINT count,SMB_BIG_UINT offset) { BOOL ok = False; + struct posix_unlock_data_struct posix_data; if (!lp_locking(SNUM(conn))) return NT_STATUS_OK; @@ -202,19 +223,18 @@ * match then don't bother looking to remove POSIX locks. */ + posix_data.fsp = fsp; + posix_data.offset = offset; + posix_data.count = count; + ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum, - lock_pid, sys_getpid(), conn->cnum, offset, count, False); + lock_pid, sys_getpid(), conn->cnum, offset, count, + False, posix_unlock, (void *)&posix_data); if (!ok) { DEBUG(10,("do_unlock: returning ERRlock.\n" )); return NT_STATUS_RANGE_NOT_LOCKED; } - - if (!lp_posix_locking(SNUM(conn))) - return NT_STATUS_OK; - - (void)release_posix_lock(fsp, offset, count); - return NT_STATUS_OK; } diff -ur ../../samba-2.2.8/source/nmbd/nmbd.c ./nmbd/nmbd.c --- ../../samba-2.2.8/source/nmbd/nmbd.c Sat Mar 15 08:34:48 2003 +++ source/nmbd/nmbd.c Fri Apr 4 16:02:43 2003 @@ -793,7 +793,7 @@ reopen_logs(); DEBUG( 0, ( "Netbios nameserver version %s started.\n", VERSION ) ); - DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2002\n" ) ); + DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2003\n" ) ); if ( !reload_nmbd_services(False) ) return(-1); diff -ur ../../samba-2.2.8/source/nsswitch/winbindd.h ./nsswitch/winbindd.h --- ../../samba-2.2.8/source/nsswitch/winbindd.h Sat Mar 1 02:56:20 2003 +++ source/nsswitch/winbindd.h Sun Apr 6 15:57:38 2003 @@ -82,6 +82,25 @@ uint32 group_rid; /* primary group */ } WINBIND_USERINFO; +#define ALIAS_CACHE_TIME 3600 + +struct alias_cache { + TALLOC_CTX *mem_ctx; + + uint32 sequence_number; + time_t last_cache_time; + + struct acct_info *dom_aliases; + uint32 num_dom_aliases; + + struct alias_cache_info { + uint32 num_members; + DOM_SID **alias_sid_mem; + char **alias_names; + uint32 *alias_types; + } *per_alias; +}; + /* Structures to hold per domain information */ struct winbindd_domain { @@ -106,6 +125,8 @@ /* Linked list info */ struct winbindd_domain *prev, *next; + + struct alias_cache *alias_cache; }; /* per-domain methods. This is how LDAP vs RPC is selected @@ -126,6 +147,12 @@ 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, Only in ./nsswitch: winbindd.h.orig Only in ./nsswitch: winbindd.o diff -ur ../../samba-2.2.8/source/nsswitch/winbindd_cache.c ./nsswitch/winbindd_cache.c --- ../../samba-2.2.8/source/nsswitch/winbindd_cache.c Wed Dec 11 01:58:15 2002 +++ source/nsswitch/winbindd_cache.c Sun Apr 6 16:30:45 2003 @@ -633,6 +633,78 @@ } +/* 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; + unsigned 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, const char *name, @@ -929,6 +1001,7 @@ True, query_user_list, enum_dom_groups, + enum_local_groups, name_to_sid, sid_to_name, query_user, Only in ./nsswitch: winbindd_cache.o Only in ./nsswitch: winbindd_cm.o diff -ur ../../samba-2.2.8/source/nsswitch/winbindd_group.c ./nsswitch/winbindd_group.c --- ../../samba-2.2.8/source/nsswitch/winbindd_group.c Wed Dec 11 01:58:15 2002 +++ source/nsswitch/winbindd_group.c Sun Apr 6 16:33:31 2003 @@ -71,12 +71,6 @@ *num_gr_mem = 0; - if (group_name_type != SID_NAME_DOM_GRP) { - DEBUG(1, ("rid %d in domain %s isn't a " "domain group\n", - group_rid, domain->name)); - goto done; - } - /* Lookup group members */ status = domain->methods->lookup_groupmem(domain, mem_ctx, group_rid, &num_names, &rid_mem, &names, &name_types); @@ -84,7 +78,7 @@ DEBUG(1, ("could not lookup membership for group rid %d in domain %s\n", group_rid, domain->name)); - goto done; + num_names = 0; } DEBUG(10, ("looked up %d names\n", num_names)); @@ -396,7 +390,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; @@ -438,6 +432,42 @@ ent->num_sam_entries = num_entries; + + if ( domain->methods->enum_local_groups ) + { + nt_status = domain->methods->enum_local_groups(domain, mem_ctx, &num_entries, &sam_grp_entries); + + if ( !NT_STATUS_IS_OK(nt_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; + } + + if (status && !NT_STATUS_IS_OK(nt_status)) + *status = nt_status; + /* Fill in remaining fields */ ent->sam_entries = name_list; diff -ur ../../samba-2.2.8/source/nsswitch/winbindd_proto.h ./nsswitch/winbindd_proto.h --- ../../samba-2.2.8/source/nsswitch/winbindd_proto.h Wed Dec 11 01:58:15 2002 +++ source/nsswitch/winbindd_proto.h Sun Apr 6 16:48:38 2003 @@ -74,6 +74,7 @@ /* The following definitions come from nsswitch/winbindd_rpc.c */ +int get_ldap_seq(const char *server, uint32 *seq); /* The following definitions come from nsswitch/winbindd_sid.c */ @@ -112,6 +113,9 @@ BOOL check_domain_env(char *domain_env, char *domain); BOOL parse_domain_user(const char *domuser, fstring domain, fstring user); void fill_domain_username(fstring name, const char *domain, const char *user); +DOM_SID *rid_to_talloced_sid(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 rid) ; /* The following definitions come from nsswitch/winbindd_wins.c */ diff -ur ../../samba-2.2.8/source/nsswitch/winbindd_rpc.c ./nsswitch/winbindd_rpc.c --- ../../samba-2.2.8/source/nsswitch/winbindd_rpc.c Sat Mar 1 02:56:20 2003 +++ source/nsswitch/winbindd_rpc.c Sun Apr 6 17:47:05 2003 @@ -41,6 +41,13 @@ return s; } +static NTSTATUS lookup_aliasmem(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 group_rid, uint32 *num_names, + DOM_SID ***sid_mem, char ***names, + uint32 **name_types); + + /* Query display info for a domain. This returns enough information plus a bit extra to give an overview of domain users for the User Manager application. */ @@ -211,6 +218,76 @@ return result; } + +/* List all local 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; + int retry; + + *num_entries = 0; + *info = NULL; + + retry = 0; + do { + /* Get sam handle */ + + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + return result; + + /* Get domain handle */ + + result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, + des_access, &domain->sid, &dom_pol); + } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && + hnd && hnd->cli && hnd->cli->fd == -1); + + if ( !NT_STATUS_IS_OK(result)) + return result; + + do { + struct acct_info *info2 = NULL; + uint32 count = 0, start = *num_entries; + TALLOC_CTX *mem_ctx2; + + mem_ctx2 = talloc_init(); + + 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, @@ -370,33 +447,198 @@ return result; } + +/* initialise the alias cache for this domain */ +static NTSTATUS init_alias_cache(struct winbindd_domain *domain) +{ + CLI_POLICY_HND *hnd; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + POLICY_HND dom_pol; + uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; + uint32 idx = 0; + unsigned int retry; + BOOL got_dom_pol = False; + int i; + TALLOC_CTX *mem_ctx; + + if (domain->alias_cache) { + if (domain->alias_cache->sequence_number == domain->sequence_number) { + return NT_STATUS_OK; + } + /* fill the alias cache at most every 5 minutes */ + if (domain->alias_cache->last_cache_time + ALIAS_CACHE_TIME > time(NULL)) { + return NT_STATUS_OK; + } + talloc_destroy(domain->alias_cache->mem_ctx); + domain->alias_cache = NULL; + } + + mem_ctx = talloc_init(); + + do { + /* Get sam handle */ + + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) { + talloc_destroy(mem_ctx); + goto done; + } + + /* Get domain handle */ + + result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, + des_access, &domain->sid, &dom_pol); + } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && + hnd && hnd->cli && hnd->cli->fd == -1); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + domain->alias_cache = (struct alias_cache *)talloc(mem_ctx, sizeof(struct alias_cache)); + domain->alias_cache->mem_ctx = mem_ctx; + domain->alias_cache->last_cache_time = time(NULL); + domain->alias_cache->sequence_number = domain->sequence_number; + + + got_dom_pol = True; + + domain->alias_cache->last_cache_time = time(NULL); + + result = cli_samr_enum_als_groups(hnd->cli, mem_ctx, + &dom_pol, &idx, + 0xffff, + &domain->alias_cache->dom_aliases, + &domain->alias_cache->num_dom_aliases); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + domain->alias_cache->per_alias = + (struct alias_cache_info *)talloc(mem_ctx, + domain->alias_cache->num_dom_aliases * + sizeof(struct alias_cache_info)); + if (!domain->alias_cache->per_alias) { + goto done; + } + + + for (i=0;ialias_cache->num_dom_aliases;i++) { + NTSTATUS status; + int j, k; + + status = lookup_aliasmem(domain, mem_ctx, + domain->alias_cache->dom_aliases[i].rid, + &domain->alias_cache->per_alias[i].num_members, + &domain->alias_cache->per_alias[i].alias_sid_mem, + &domain->alias_cache->per_alias[i].alias_names, + &domain->alias_cache->per_alias[i].alias_types); + if (!NT_STATUS_IS_OK(status)) { + continue; + } + } + + done: + /* Clean up policy handles */ + if (got_dom_pol) + cli_samr_close(hnd->cli, mem_ctx, &dom_pol); + + if (!NT_STATUS_IS_OK(result)) { + talloc_destroy(domain->alias_cache->mem_ctx); + domain->alias_cache = NULL; + } + + return result; +} + + +/* add any local groups that the user should be a member of */ +static NTSTATUS add_local_groups(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 n_groups, DOM_GID *user_groups, + uint32 *groups_out, uint32 **gids_out) +{ + int i; + + init_alias_cache(domain); + if (!domain->alias_cache) { + return NT_STATUS_UNSUCCESSFUL; + } + + for (i=0;ialias_cache->num_dom_aliases;i++) { + int j, k; + DOM_SID *alias_sid; + + alias_sid = rid_to_talloced_sid(domain, mem_ctx, domain->alias_cache->dom_aliases[i].rid); + + for (j=0;jalias_cache->per_alias[i].num_members;j++) { + uint32 alias_rid; + if (domain->alias_cache->per_alias[i].alias_types[j] != SID_NAME_DOM_GRP) { + continue; + } + if (!sid_peek_check_rid(&domain->sid, + domain->alias_cache->per_alias[i].alias_sid_mem[j], + &alias_rid)) { + continue; + } + for (k=0;kname, &hnd))) goto done; /* Get domain handle */ + result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, - des_access, &domain->sid, &dom_pol); + des_access, &domain->sid, &dom_pol); } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1); @@ -405,6 +647,7 @@ got_dom_pol = True; + /* Get user handle */ result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol, des_access, user_rid, &user_pol); @@ -416,16 +659,40 @@ /* Query user rids */ result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol, - num_groups, &user_groups); + &n_groups, &user_groups); - if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0) + if (!NT_STATUS_IS_OK(result)) goto done; + n_aliases = 0; + + sid_copy(&user_sid, &domain->sid); + sid_append_rid(&user_sid, user_rid); + init_dom_sid2(&sid2, &user_sid); + + result = cli_samr_query_useraliases(hnd->cli, mem_ctx, &dom_pol, 1, &sid2, + &n_aliases, &alias_rids); + + /* ignore errors from this */ + + (*num_groups) = n_groups + n_aliases; + (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups)); - for (i=0;i<(*num_groups);i++) { + if (!(*user_gids)) { + result = NT_STATUS_NO_MEMORY; + goto done; + } + + for (i=0;iname, group_rid)); + + *num_names = 0; + + retry = 0; + do { + /* Get sam handle */ + + if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd))) + goto done; + + /* Get domain handle */ + + result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, + des_access, &domain->sid, &dom_pol); + } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && + hnd && hnd->cli && hnd->cli->fd == -1); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + got_dom_pol = True; + + /* Get alias handle */ + result = cli_samr_open_alias(hnd->cli, mem_ctx, &dom_pol, + des_access, group_rid, &group_pol); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + got_group_pol = True; + + /* Step #1: Get a list of user rids that are the members of the + group. */ + + result = cli_samr_query_aliasmem(hnd->cli, mem_ctx, + &group_pol, num_names, &sids); + + + DEBUG(0,("query aliasmem -> %s\n", nt_errstr(result))); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + /* Step #2: Convert list of rids into list of usernames. Do this + in bunches of ~1000 to avoid crashing NT4. It looks like there + is a buffer overflow or something like that lurking around + somewhere. */ + +#define MAX_LOOKUP_RIDS 900 + + *names = talloc_zero(mem_ctx, *num_names * sizeof(char *)); + *name_types = talloc_zero(mem_ctx, *num_names * sizeof(uint32)); + *sid_mem = talloc_zero(mem_ctx, *num_names * sizeof(DOM_SID *)); + + if (!*names || !*name_types) { + result = NT_STATUS_NO_MEMORY; + goto done; + } + + for (i = 0; i < *num_names; i++) { + enum SID_NAME_USE ntype; + NTSTATUS status; + + status = sid_to_name(domain, mem_ctx, + &sids[i], &(*names)[total_names], &ntype); + if (NT_STATUS_IS_OK(status)) { + (*name_types)[total_names] = ntype; + (*sid_mem)[total_names] = &sids[i]; + total_names++; + } + } + + *num_names = total_names; + + done: + if (got_group_pol) + cli_samr_close(hnd->cli, mem_ctx, &group_pol); + + if (got_dom_pol) + cli_samr_close(hnd->cli, mem_ctx, &dom_pol); + + return result; +} + + /* Lookup group membership given a rid. */ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, @@ -477,8 +848,27 @@ result = cli_samr_open_group(hnd->cli, mem_ctx, &dom_pol, des_access, group_rid, &group_pol); - if (!NT_STATUS_IS_OK(result)) - goto done; + if (!NT_STATUS_IS_OK(result)) { + DOM_SID **sid_mem; + uint32 num_names2; + char **names2; + uint32 *name_types2; + + result = lookup_aliasmem(domain, mem_ctx, group_rid, &num_names2, + &sid_mem, &names2, &name_types2); + if (NT_STATUS_IS_OK(result)) { + (*rid_mem) = talloc(mem_ctx, num_names2 * sizeof(uint32)); + (*names) = talloc(mem_ctx, num_names2 * sizeof(**names)); + (*name_types) = talloc(mem_ctx, num_names2 * sizeof(uint32)); + for (i=0;isam_entry_index].name)); } /* Out of domains */ Only in ./nsswitch: winbindd_user.o diff -ur ../../samba-2.2.8/source/nsswitch/winbindd_util.c ./nsswitch/winbindd_util.c --- ../../samba-2.2.8/source/nsswitch/winbindd_util.c Sat Mar 15 08:34:48 2003 +++ source/nsswitch/winbindd_util.c Sun Apr 6 16:39:02 2003 @@ -388,3 +388,21 @@ user); } } + + +/* Help with RID -> SID conversion */ + +DOM_SID *rid_to_talloced_sid(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 rid) +{ + DOM_SID *sid; + sid = talloc(mem_ctx, sizeof(*sid)); + if (!sid) { + smb_panic("rid_to_to_talloced_sid: talloc for DOM_SID failed!\n"); + } + sid_copy(sid, &domain->sid); + sid_append_rid(sid, rid); + return sid; +} + diff -ur ../../samba-2.2.8/source/passdb/pdb_ldap.c ./passdb/pdb_ldap.c --- ../../samba-2.2.8/source/passdb/pdb_ldap.c Sat Mar 15 08:34:48 2003 +++ source/passdb/pdb_ldap.c Fri Apr 4 16:02:44 2003 @@ -115,7 +115,9 @@ { int port; int version; +#ifdef HAVE_LDAP_START_TLS_S int tls, rc; +#endif uid_t uid = geteuid(); struct passwd* pass; @@ -265,20 +267,17 @@ int *method, int freeit ) # endif { - register char *to_clear = *credp; - if (freeit) { SAFE_FREE(*whop); memset(*credp, '\0', strlen(*credp)); SAFE_FREE(*credp); } else { - *whop = strdup(ldap_state->bind_dn); + *whop = strdup(lp_ldap_admin_dn()); if (!*whop) { return LDAP_NO_MEMORY; } - DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", - whop)); + DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", *whop)); *credp = strdup(ldap_secret); if (!*credp) { @@ -1106,6 +1105,7 @@ pdb_get_username(newpwd), ldap_err2string(rc), ld_error)); free(ld_error); + ldap_mods_free(mods, 1); ldap_unbind(ldap_struct); return False; } diff -ur ../../samba-2.2.8/source/rpc_parse/parse_samr.c ./rpc_parse/parse_samr.c --- ../../samba-2.2.8/source/rpc_parse/parse_samr.c Sat Mar 15 08:34:48 2003 +++ source/rpc_parse/parse_samr.c Sun Apr 6 16:04:37 2003 @@ -4514,6 +4514,10 @@ return False; } + if (UNMARSHALLING(ps)) { + r_u->sid = talloc(ps->mem_ctx, r_u->num_sids1 * sizeof(DOM_SID2)); + } + for (i = 0; i < r_u->num_sids1; i++) { if (ptr_sid[i] != 0) { if(!smb_io_dom_sid2("", &r_u->sid[i], ps, depth)) diff -ur ../../samba-2.2.8/source/rpc_server/srv_lsa_nt.c ./rpc_server/srv_lsa_nt.c --- ../../samba-2.2.8/source/rpc_server/srv_lsa_nt.c Fri Jun 7 07:31:34 2002 +++ source/rpc_server/srv_lsa_nt.c Mon Apr 7 14:20:20 2003 @@ -393,7 +393,7 @@ } case 0x03: /* Request PolicyPrimaryDomainInformation. */ - switch (lp_server_role()) { + switch (dva_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: name = dos_domain; @@ -419,7 +419,7 @@ break; case 0x05: /* Request PolicyAccountDomainInformation. */ - switch (lp_server_role()) { + switch (dva_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: name = dos_domain; @@ -439,7 +439,7 @@ init_dom_query(&r_u->dom.id5, name, sid); break; case 0x06: - switch (lp_server_role()) { + switch (dva_server_role()) { case ROLE_DOMAIN_BDC: /* * only a BDC is a backup controller diff -ur ../../samba-2.2.8/source/rpc_server/srv_reg_nt.c ./rpc_server/srv_reg_nt.c --- ../../samba-2.2.8/source/rpc_server/srv_reg_nt.c Sat Mar 15 08:34:49 2003 +++ source/rpc_server/srv_reg_nt.c Mon Apr 7 14:25:23 2003 @@ -148,7 +148,7 @@ goto out; } - switch (lp_server_role()) { + switch (dva_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: key = "LanmanNT"; diff -ur ../../samba-2.2.8/source/rpc_server/srv_samr_nt.c ./rpc_server/srv_samr_nt.c --- ../../samba-2.2.8/source/rpc_server/srv_samr_nt.c Sat Mar 15 08:34:49 2003 +++ source/rpc_server/srv_samr_nt.c Mon Apr 7 14:26:20 2003 @@ -2092,6 +2092,12 @@ return True; } +/* wow, this is a nasty hack */ +int dva_server_role(void) +{ + return ROLE_DOMAIN_BDC; +} + /********************************************************************** api_samr_enum_domains **********************************************************************/ @@ -2104,7 +2110,7 @@ r_u->status = NT_STATUS_OK; - switch (lp_server_role()) { + switch (dva_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: name = global_myworkgroup; Only in ./rpc_server: srv_samr_nt.c.~1.1.2.70.~ Only in ./rpc_server: srv_samr_nt.o Only in ./rpc_server: srv_spoolss.o diff -ur ../../samba-2.2.8/source/rpc_server/srv_spoolss_nt.c ./rpc_server/srv_spoolss_nt.c --- ../../samba-2.2.8/source/rpc_server/srv_spoolss_nt.c Sat Mar 15 08:34:49 2003 +++ source/rpc_server/srv_spoolss_nt.c Fri Apr 4 16:02:45 2003 @@ -4,8 +4,8 @@ * Copyright (C) Andrew Tridgell 1992-2000, * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, * Copyright (C) Jean François Micouleau 1998-2000, - * Copyright (C) Jeremy Allison 2001, - * Copyright (C) Gerald Carter 2000-2001, + * Copyright (C) Jeremy Allison 2001-2002, + * Copyright (C) Gerald Carter 2000-2003, * Copyright (C) Tim Potter 2001-2002. * * This program is free software; you can redistribute it and/or modify @@ -499,16 +499,16 @@ ZERO_STRUCTP(new_printer); - new_printer->notify.option=NULL; - - /* Add to the internal list. */ - DLIST_ADD(printers_list, new_printer); - if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) { SAFE_FREE(new_printer); return False; } + + /* Add to the internal list. */ + DLIST_ADD(printers_list, new_printer); + new_printer->notify.option=NULL; + if (!set_printer_hnd_printertype(new_printer, name)) { close_printer_handle(p, hnd); return False; @@ -1154,8 +1154,10 @@ /* NT doesn't let us connect to a printer if the connecting user doesn't have print permission. */ - if (!get_printer_snum(p, handle, &snum)) + if (!get_printer_snum(p, handle, &snum)) { + close_printer_handle(p, handle); return WERR_BADFID; + } se_map_standard(&printer_default->access_required, &printer_std_mapping); diff -ur ../../samba-2.2.8/source/smbd/blocking.c ./smbd/blocking.c --- ../../samba-2.2.8/source/smbd/blocking.c Sat Mar 1 02:56:20 2003 +++ source/smbd/blocking.c Mon Apr 7 14:23:47 2003 @@ -523,7 +523,7 @@ brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); @@ -554,7 +554,7 @@ blocking_lock_reply_error(blr,NT_STATUS_CANCELLED); brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum, blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); continue; @@ -651,7 +651,7 @@ brl_unlock(fsp->dev, fsp->inode, fsp->fnum, blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); @@ -669,7 +669,7 @@ brl_unlock(fsp->dev, fsp->inode, fsp->fnum, blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); @@ -685,7 +685,7 @@ brl_unlock(fsp->dev, fsp->inode, fsp->fnum, blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); @@ -703,7 +703,7 @@ brl_unlock(fsp->dev, fsp->inode, fsp->fnum, blr->lock_pid, sys_getpid(), conn->cnum, - blr->offset, blr->count, True); + blr->offset, blr->count, True, NULL, NULL); free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev)); blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue)); Only in ./smbd: blocking.o Only in ./smbd: chgpasswd.o diff -ur ../../samba-2.2.8/source/smbd/close.c ./smbd/close.c --- ../../samba-2.2.8/source/smbd/close.c Sat Mar 1 02:56:20 2003 +++ source/smbd/close.c Mon Apr 7 14:23:47 2003 @@ -198,6 +198,7 @@ DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \ with error %s\n", fsp->fsp_name, strerror(errno) )); } + process_pending_change_notify_queue((time_t)0); } unlock_share_entry_fsp(fsp); @@ -264,6 +265,7 @@ if(ok) remove_pending_change_notify_requests_by_filename(fsp); + process_pending_change_notify_queue((time_t)0); } /* diff -ur ../../samba-2.2.8/source/smbd/posix_acls.c ./smbd/posix_acls.c --- ../../samba-2.2.8/source/smbd/posix_acls.c Sat Mar 15 08:34:49 2003 +++ source/smbd/posix_acls.c Fri Apr 4 16:08:37 2003 @@ -1003,12 +1003,12 @@ if (nt4_compatible_acls()) psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY; - } else if (sid_to_uid( ¤t_ace->trustee, ¤t_ace->unix_ug.uid, &sid_type)) { - current_ace->owner_type = UID_ACE; - current_ace->type = SMB_ACL_USER; } else if (sid_to_gid( ¤t_ace->trustee, ¤t_ace->unix_ug.gid, &sid_type)) { current_ace->owner_type = GID_ACE; current_ace->type = SMB_ACL_GROUP; + } else if (sid_to_uid( ¤t_ace->trustee, ¤t_ace->unix_ug.uid, &sid_type)) { + current_ace->owner_type = UID_ACE; + current_ace->type = SMB_ACL_USER; } else { fstring str; @@ -2464,6 +2464,12 @@ DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n")); sd_size = 0; } else { +#if 0 + /* + tridge: I have disabled this to allow recursive ACL application using + explorer from win2k workstations + */ + /* * Windows 2000: The DACL_PROTECTED flag in the security * descriptor marks the ACL as non-inheriting, i.e., no @@ -2474,6 +2480,7 @@ * flag doesn't seem to bother Windows NT. */ (*ppdesc)->type |= SE_DESC_DACL_PROTECTED; +#endif } done: Only in ./smbd: posix_acls.o Only in ./smbd: process.o Only in ./smbd: quotas.o diff -ur ../../samba-2.2.8/source/smbd/reply.c ./smbd/reply.c --- ../../samba-2.2.8/source/smbd/reply.c Sat Mar 15 08:34:49 2003 +++ source/smbd/reply.c Fri Apr 4 14:36:19 2003 @@ -1162,7 +1162,9 @@ if (check_name(name,conn)) { if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0) - ok = S_ISDIR(sbuf.st_mode); + if (!(ok = S_ISDIR(sbuf.st_mode))) + errno = ENOTDIR; + } if (!ok) { Only in ./smbd: reply.o Only in ./smbd: sec_ctx.o diff -ur ../../samba-2.2.8/source/smbd/server.c ./smbd/server.c --- ../../samba-2.2.8/source/smbd/server.c Sat Mar 15 08:34:49 2003 +++ source/smbd/server.c Fri Apr 4 14:36:19 2003 @@ -789,7 +789,7 @@ reopen_logs(); DEBUG(0,( "smbd version %s started.\n", VERSION)); - DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2002\n")); + DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2003\n")); DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); Only in ./smbd: server.c.orig Only in ./smbd: server.o Only in ./smbd: service.o Only in ./smbd: session.o Only in ./smbd: ssl.o Only in ./smbd: ssl.po Only in ./smbd: statcache.o diff -ur ../../samba-2.2.8/source/smbd/trans2.c ./smbd/trans2.c --- ../../samba-2.2.8/source/smbd/trans2.c Sat Mar 15 08:34:49 2003 +++ source/smbd/trans2.c Mon Apr 7 14:23:47 2003 @@ -2208,6 +2208,9 @@ DEBUG(10,("set_delete_on_close_over_all: %s delete on close flag for fnum = %d, file %s\n", delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name )); + if (fsp->is_directory || fsp->is_stat) + return NT_STATUS_OK; + if (lock_share_entry_fsp(fsp) == False) return NT_STATUS_ACCESS_DENIED; @@ -3043,7 +3046,7 @@ { char *params = *pparams; enum remote_arch_types ra_type = get_remote_arch(); - BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K)); + BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K) || (ra_type == RA_WINXP) || (ra_type == RA_WIN2K3)); pstring pathname; int reply_size = 0; int max_referral_level; diff -ur ../../samba-2.2.8/source/utils/smbpasswd.c ./utils/smbpasswd.c --- ../../samba-2.2.8/source/utils/smbpasswd.c Sat Mar 15 08:34:49 2003 +++ source/utils/smbpasswd.c Fri Apr 4 16:02:46 2003 @@ -34,7 +34,7 @@ /* forced running in root-mode */ static BOOL local_mode; -static BOOL joining_domain = False, got_pass = False, got_username = False, changing_trust_pw = False; +static BOOL joining_domain = False, got_pass = False, got_username = False, changing_trust_pw = False, changing_trust_pw_secrets_only = False; static int local_flags = 0; static BOOL stdin_passwd_get = False; static fstring user_name, user_password; @@ -97,6 +97,7 @@ printf(" -x delete user\n"); printf(" -j DOMAIN join domain name\n"); printf(" -t DOMAIN change trust account password on domain\n"); + printf(" -T DOMAIN change trust account password in secrets database only\n"); printf(" -S DOMAIN Retrieve the domain SID for DOMAIN\n"); printf(" -R ORDER name resolve order\n"); printf(" -W S-1-5-... Write the SID S-1-5-... to the secrets file\n"); @@ -121,7 +122,7 @@ user_name[0] = '\0'; - while ((ch = getopt(argc, argv, "c:axdehmnj:t:r:sw:R:D:U:LSW:X:")) != EOF) { + while ((ch = getopt(argc, argv, "c:axdehmnj:t:T:r:sw:R:D:U:LSW:X:")) != EOF) { switch(ch) { case 'L': local_mode = amroot = True; @@ -168,6 +169,12 @@ strupper(new_domain); changing_trust_pw = True; break; + case 'T': + if (!amroot) goto bad_args; + new_domain = optarg; + strupper(new_domain); + changing_trust_pw_secrets_only = True; + break; case 'r': remote_machine = optarg; break; @@ -958,6 +965,29 @@ return 1; } + /* Change trust password in secrets database only */ + if (changing_trust_pw_secrets_only) + { + char *trust_pw; + char trust_pw_hash[16]; + + trust_pw = get_pass("Trust account password: ",stdin_passwd_get); + + E_md4hash(trust_pw,trust_pw_hash); + + if(!secrets_store_trust_account_password(new_domain,trust_pw_hash)) + { + fprintf(stderr, "Unable to write the machine account password for \ + machine %s in domain %s.\n", global_myname, new_domain); + return 1; + } + else + { + fprintf(stdout, "Modified trust account password in secrets database\n"); + } + + return 0; + } /* * get the domain sid from a PDC and store it in secrets.tdb