Index: include/byteorder.h =================================================================== RCS file: /home/cvs/samba/source/include/byteorder.h,v retrieving revision 1.29.4.4.2.3 diff -u -u -r1.29.4.4.2.3 byteorder.h --- include/byteorder.h 27 Jul 2002 04:55:54 -0000 1.29.4.4.2.3 +++ include/byteorder.h 9 Oct 2003 11:10:48 -0000 @@ -105,7 +105,7 @@ #define CAREFUL_ALIGNMENT 1 #endif -#define CVAL(buf,pos) (((const unsigned char *)(buf))[pos]) +#define CVAL(buf,pos) ((unsigned)(((const unsigned char *)(buf))[pos])) #define CVAL_NC(buf,pos) (((unsigned char *)(buf))[pos]) /* Non-const version of CVAL */ #define PVAL(buf,pos) (CVAL(buf,pos)) #define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val)) Index: include/local.h =================================================================== RCS file: /home/cvs/samba/source/include/local.h,v retrieving revision 1.54.6.6 diff -u -u -r1.54.6.6 local.h --- include/local.h 28 Feb 2003 14:42:42 -0000 1.54.6.6 +++ include/local.h 9 Oct 2003 11:10:48 -0000 @@ -196,4 +196,10 @@ /* Max number of simultaneous winbindd socket connections. */ #define WINBINDD_MAX_SIMULTANEOUS_CLIENTS 200 + +/* extended attribute to use for DOS attributes */ +#define XATTR_DOS_ATTRIB "user.DOSATTRIB" + #endif + + Index: include/proto.h =================================================================== RCS file: /home/cvs/samba/source/include/Attic/proto.h,v retrieving revision 1.900.2.137.2.19 diff -u -u -r1.900.2.137.2.19 proto.h --- include/proto.h 14 Mar 2003 21:21:31 -0000 1.900.2.137.2.19 +++ include/proto.h 9 Oct 2003 11:10:53 -0000 @@ -1064,6 +1064,12 @@ int sys_dlclose (void *handle); const char *sys_dlerror(void); void sys_adminlog(int priority, const char *format_str, ...); +ssize_t sys_getxattr(const char *path, const char *name, void *value, size_t size); +ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size); +int sys_setxattr(const char *path, const char *name, const void *value, + size_t size, int flags); +int sys_fsetxattr(int filedes, const char *name, const void *value, + size_t size, int flags); /* The following definitions come from lib/talloc.c */ @@ -1277,7 +1283,8 @@ BOOL string_to_sid(DOM_SID *sidout, const char *sidstr); BOOL sid_append_rid(DOM_SID *sid, uint32 rid); BOOL sid_split_rid(DOM_SID *sid, uint32 *rid); -BOOL sid_peek_rid(DOM_SID *sid, uint32 *rid); +BOOL sid_peek_rid(const DOM_SID *sid, uint32 *rid); +BOOL sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *rid); void sid_copy(DOM_SID *dst, const DOM_SID *src); DOM_SID *sid_dup(DOM_SID *src); BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid); @@ -1471,7 +1478,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); BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, @@ -4126,6 +4135,7 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u); NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u); NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u); +int dva_server_role(void); NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u); NTSTATUS _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u); NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u); Index: include/smb.h =================================================================== RCS file: /home/cvs/samba/source/include/smb.h,v retrieving revision 1.325.2.21.2.15 diff -u -u -r1.325.2.21.2.15 smb.h --- include/smb.h 14 Mar 2003 21:21:32 -0000 1.325.2.21.2.15 +++ include/smb.h 9 Oct 2003 11:10:55 -0000 @@ -93,6 +93,7 @@ #define aVOLID (1L<<3) /* 0x08 */ #define aDIR (1L<<4) /* 0x10 */ #define aARCH (1L<<5) /* 0x20 */ +#define aNORMAL (1L<<6) /* 0x80 */ /* deny modes */ #define DENY_DOS 0 Index: lib/access.c =================================================================== RCS file: /home/cvs/samba/source/lib/access.c,v retrieving revision 1.19.4.3.2.6 diff -u -u -r1.19.4.3.2.6 access.c --- lib/access.c 14 Mar 2003 21:21:32 -0000 1.19.4.3.2.6 +++ lib/access.c 9 Oct 2003 11:10:56 -0000 @@ -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) { Index: lib/system.c =================================================================== RCS file: /home/cvs/samba/source/lib/system.c,v retrieving revision 1.55.4.9.2.4 diff -u -u -r1.55.4.9.2.4 system.c --- lib/system.c 14 Mar 2003 21:21:32 -0000 1.55.4.9.2.4 +++ lib/system.c 9 Oct 2003 11:10:57 -0000 @@ -1331,3 +1331,28 @@ #endif SAFE_FREE(*msgbuf); } + + +/* interface to extended attributes */ + +ssize_t sys_getxattr(const char *path, const char *name, void *value, size_t size) +{ + return getxattr(path, name, value, size); +} + +ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size) +{ + return fgetxattr(filedes, name, value, size); +} + +int sys_setxattr(const char *path, const char *name, const void *value, + size_t size, int flags) +{ + return setxattr(path, name, value, size, flags); +} + +int sys_fsetxattr(int filedes, const char *name, const void *value, + size_t size, int flags) +{ + return fsetxattr(filedes, name, value, size, flags); +} Index: lib/util_sid.c =================================================================== RCS file: /home/cvs/samba/source/lib/util_sid.c,v retrieving revision 1.24.2.6.2.7 diff -u -u -r1.24.2.6.2.7 util_sid.c --- lib/util_sid.c 14 Mar 2003 21:21:33 -0000 1.24.2.6.2.7 +++ lib/util_sid.c 9 Oct 2003 11:10:57 -0000 @@ -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 *****************************************************************/ @@ -696,8 +715,11 @@ sid_copy(&dom, sid); sid_split_rid(&dom, &rid); + /* we need to support the BUILTIN domain for DVA */ +#if 0 if (sid_equal(&dom, &global_sid_Builtin)) return True; +#endif if (sid_equal(&dom, &global_sid_Creator_Owner_Domain)) return True; Index: libsmb/cli_samr.c =================================================================== RCS file: /home/cvs/samba/source/libsmb/Attic/cli_samr.c,v retrieving revision 1.5.2.1.2.8 diff -u -u -r1.5.2.1.2.8 cli_samr.c --- libsmb/cli_samr.c 14 Mar 2003 21:21:33 -0000 1.5.2.1.2.8 +++ libsmb/cli_samr.c 9 Oct 2003 11:10:58 -0000 @@ -703,7 +703,7 @@ *num_mem = r.num_sids; - if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) { + if (*num_mem && !(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) { result = NT_STATUS_UNSUCCESSFUL; goto done; } Index: libsmb/libsmbclient.c =================================================================== RCS file: /home/cvs/samba/source/libsmb/libsmbclient.c,v retrieving revision 1.32.2.5 diff -u -u -r1.32.2.5 libsmbclient.c --- libsmb/libsmbclient.c 28 Feb 2003 14:42:45 -0000 1.32.2.5 +++ libsmb/libsmbclient.c 9 Oct 2003 11:10:59 -0000 @@ -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); Index: locking/brlock.c =================================================================== RCS file: /home/cvs/samba/source/locking/brlock.c,v retrieving revision 1.15.4.3.2.5 diff -u -u -r1.15.4.3.2.5 brlock.c --- locking/brlock.c 28 Feb 2003 14:42:46 -0000 1.15.4.3.2.5 +++ locking/brlock.c 9 Oct 2003 11:10:59 -0000 @@ -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; } Index: nmbd/nmbd.c =================================================================== RCS file: /home/cvs/samba/source/nmbd/nmbd.c,v retrieving revision 1.105.2.4.2.6 diff -u -u -r1.105.2.4.2.6 nmbd.c --- nmbd/nmbd.c 14 Mar 2003 21:21:33 -0000 1.105.2.4.2.6 +++ nmbd/nmbd.c 9 Oct 2003 11:11:02 -0000 @@ -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); Index: nsswitch/winbindd.h =================================================================== RCS file: /home/cvs/samba/source/nsswitch/winbindd.h,v retrieving revision 1.3.6.5 diff -u -u -r1.3.6.5 winbindd.h --- nsswitch/winbindd.h 28 Feb 2003 14:42:46 -0000 1.3.6.5 +++ nsswitch/winbindd.h 9 Oct 2003 11:11:02 -0000 @@ -82,6 +82,23 @@ 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; + } *per_alias; +}; + /* Structures to hold per domain information */ struct winbindd_domain { @@ -106,6 +123,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 @@ -127,6 +146,12 @@ 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, @@ -152,7 +177,7 @@ NTSTATUS (*lookup_usergroups)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 user_rid, - uint32 *num_groups, uint32 **user_gids); + uint32 *num_sids, DOM_SID **user_sids); /* find all members of the group with the specified group_rid */ NTSTATUS (*lookup_groupmem)(struct winbindd_domain *domain, Index: nsswitch/winbindd_cache.c =================================================================== RCS file: /home/cvs/samba/source/nsswitch/winbindd_cache.c,v retrieving revision 1.5.4.2.2.6 diff -u -u -r1.5.4.2.2.6 winbindd_cache.c --- nsswitch/winbindd_cache.c 9 Oct 2002 19:50:27 -0000 1.5.4.2.2.6 +++ nsswitch/winbindd_cache.c 9 Oct 2003 11:11:02 -0000 @@ -189,6 +189,20 @@ return ret; } + +/* pull a SID from a cache entry, using the supplied + talloc context +*/ +static DOM_SID centry_sid(struct cache_entry *centry, TALLOC_CTX *mem_ctx) +{ + DOM_SID ret; + const char *s = centry_string(centry, mem_ctx); + if (!s || !string_to_sid(&ret, s)) { + ZERO_STRUCT(ret); + } + return ret; +} + /* the server is considered down if it can't give us a sequence number */ static BOOL wcache_server_down(struct winbindd_domain *domain) { @@ -372,6 +386,16 @@ centry->ofs += len; } + +/* + push a SID into a centry + */ +static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid) +{ + centry_put_string(centry, sid_string_static(sid)); +} + + /* start a centry for output. When finished, call centry_end() */ @@ -633,6 +657,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, @@ -767,7 +863,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 user_rid, - uint32 *num_groups, uint32 **user_gids) + uint32 *num_sids, DOM_SID **user_sids) { struct winbind_cache *cache = get_cache(domain); struct cache_entry *centry = NULL; @@ -779,14 +875,14 @@ centry = wcache_fetch(cache, domain, "UG/%s/%d", domain->name, user_rid); if (!centry) goto do_query; - *num_groups = centry_uint32(centry); + *num_sids = centry_uint32(centry); - if (*num_groups == 0) goto do_cached; + if (*num_sids == 0) goto do_cached; - (*user_gids) = talloc(mem_ctx, sizeof(**user_gids) * (*num_groups)); - if (! (*user_gids)) smb_panic("lookup_usergroups out of memory"); - for (i=0; i<(*num_groups); i++) { - (*user_gids)[i] = centry_uint32(centry); + (*user_sids) = talloc(mem_ctx, sizeof(**user_sids) * (*num_sids)); + if (! (*user_sids)) smb_panic("lookup_usergroups out of memory"); + for (i=0; i<(*num_sids); i++) { + (*user_sids)[i] = centry_sid(centry, mem_ctx); } do_cached: @@ -795,23 +891,23 @@ return status; do_query: - (*num_groups) = 0; - (*user_gids) = NULL; + (*num_sids) = 0; + (*user_sids) = NULL; /* Return status value returned by seq number check */ if (!NT_STATUS_IS_OK(domain->last_status)) return domain->last_status; - status = cache->backend->lookup_usergroups(domain, mem_ctx, user_rid, num_groups, user_gids); + status = cache->backend->lookup_usergroups(domain, mem_ctx, user_rid, num_sids, user_sids); /* and save it */ refresh_sequence_number(domain, True); centry = centry_start(domain, status); if (!centry) goto skip_save; - centry_put_uint32(centry, *num_groups); - for (i=0; i<(*num_groups); i++) { - centry_put_uint32(centry, (*user_gids)[i]); + centry_put_uint32(centry, *num_sids); + for (i=0; i<(*num_sids); i++) { + centry_put_sid(centry, &(*user_sids)[i]); } centry_end(centry, "UG/%s/%d", domain->name, user_rid); centry_free(centry); @@ -929,6 +1025,7 @@ True, query_user_list, enum_dom_groups, + enum_local_groups, name_to_sid, sid_to_name, query_user, Index: nsswitch/winbindd_cm.c =================================================================== RCS file: /home/cvs/samba/source/nsswitch/winbindd_cm.c,v retrieving revision 1.21.2.3 diff -u -u -r1.21.2.3 winbindd_cm.c --- nsswitch/winbindd_cm.c 9 Oct 2002 19:50:27 -0000 1.21.2.3 +++ nsswitch/winbindd_cm.c 9 Oct 2003 11:11:02 -0000 @@ -81,6 +81,10 @@ struct in_addr *ip_list = NULL, dc_ip, exclude_ip; int count, i; + if (strcasecmp(domain, "BUILTIN") == 0) { + domain = lp_workgroup(); + } + zero_ip(&exclude_ip); /* Lookup domain controller name. Try the real PDC first to avoid SAM sync delays */ Index: nsswitch/winbindd_group.c =================================================================== RCS file: /home/cvs/samba/source/nsswitch/winbindd_group.c,v retrieving revision 1.3.4.1.2.7 diff -u -u -r1.3.4.1.2.7 winbindd_group.c --- nsswitch/winbindd_group.c 15 Oct 2002 21:36:47 -0000 1.3.4.1.2.7 +++ nsswitch/winbindd_group.c 9 Oct 2003 11:11:03 -0000 @@ -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)); @@ -129,8 +123,12 @@ /* Append domain name */ - fill_domain_username(name, domain->name, the_name); - + if (strcasecmp(domain->name, "BUILTIN") == 0) { + fill_domain_username(name, lp_workgroup(), the_name); + } else { + fill_domain_username(name, domain->name, the_name); + } + len = strlen(name); /* Add to list or calculate buffer length */ @@ -396,7 +394,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 +436,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; @@ -778,9 +812,9 @@ fstring name_domain, name_user; DOM_SID user_sid; enum SID_NAME_USE name_type; - uint32 user_rid, num_groups, num_gids; + uint32 user_rid, num_sids, num_gids; NTSTATUS status; - uint32 *user_gids; + DOM_SID *user_sids; struct winbindd_domain *domain; enum winbindd_result result = WINBINDD_ERROR; gid_t *gid_list; @@ -824,24 +858,27 @@ sid_split_rid(&user_sid, &user_rid); - status = domain->methods->lookup_usergroups(domain, mem_ctx, user_rid, &num_groups, &user_gids); + status = domain->methods->lookup_usergroups(domain, mem_ctx, user_rid, &num_sids, &user_sids); if (!NT_STATUS_IS_OK(status)) goto done; + if (num_sids >= sysconf(_SC_NGROUPS_MAX)) { + DEBUG(0,("WARNING! num_sids >= NGROUPS_MAX (num_sids=%d)\n", num_sids)); + } + /* Copy data back to client */ num_gids = 0; - gid_list = malloc(sizeof(gid_t) * num_groups); + gid_list = malloc(sizeof(gid_t) * num_sids); if (state->response.extra_data) goto done; - for (i = 0; i < num_groups; i++) { - if (!winbindd_idmap_get_gid_from_rid(domain->name, - user_gids[i], + for (i = 0; i < num_sids; i++) { + if (!winbindd_idmap_get_gid_from_sid(&user_sids[i], &gid_list[num_gids])) { - DEBUG(1, ("unable to convert group rid %d to gid\n", - user_gids[i])); + DEBUG(1, ("unable to convert group sid %s to gid\n", + sid_string_static(&user_sids[i]))); continue; } Index: nsswitch/winbindd_proto.h =================================================================== RCS file: /home/cvs/samba/source/nsswitch/Attic/winbindd_proto.h,v retrieving revision 1.2.6.4 diff -u -u -r1.2.6.4 winbindd_proto.h --- nsswitch/winbindd_proto.h 9 Oct 2002 19:50:27 -0000 1.2.6.4 +++ nsswitch/winbindd_proto.h 9 Oct 2003 11:11:03 -0000 @@ -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 */ Index: nsswitch/winbindd_rpc.c =================================================================== RCS file: /home/cvs/samba/source/nsswitch/winbindd_rpc.c,v retrieving revision 1.26.2.5 diff -u -u -r1.26.2.5 winbindd_rpc.c --- nsswitch/winbindd_rpc.c 28 Feb 2003 14:42:46 -0000 1.26.2.5 +++ nsswitch/winbindd_rpc.c 9 Oct 2003 11:11:03 -0000 @@ -41,6 +41,13 @@ return s; } +/* Lookup sids in an alias given an alias sid */ +static NTSTATUS lookup_alias_sids(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + DOM_SID *group_sid, uint32 *num_names, + DOM_SID **sids); + + /* 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, @@ -293,7 +370,8 @@ DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name)); /* Paranoia */ - if (strcasecmp(domain->name, domains[0]) != 0) { + if (strcasecmp(domain->name, "BUILTIN") != 0 && + strcasecmp(domain->name, domains[0]) != 0) { DEBUG(1, ("domain name from domain param and PDC lookup return differ! (%s vs %s)\n", domain->name, domains[0])); return NT_STATUS_UNSUCCESSFUL; } @@ -370,33 +448,231 @@ 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); + + domain->alias_cache->num_dom_aliases = 0; + domain->alias_cache->dom_aliases = NULL; + + do { + struct acct_info *dom_aliases; + uint32 num_dom_aliases; + TALLOC_CTX *mem_ctx2; + + mem_ctx2 = talloc_init(); + + result = cli_samr_enum_als_groups(hnd->cli, mem_ctx2, + &dom_pol, &idx, + 0xffff, + &dom_aliases, + &num_dom_aliases); + + if (!NT_STATUS_IS_ERR(result)) { + domain->alias_cache->dom_aliases = talloc_realloc(mem_ctx, + domain->alias_cache->dom_aliases, + sizeof(struct acct_info) * + (domain->alias_cache->num_dom_aliases + + num_dom_aliases)); + memcpy(domain->alias_cache->dom_aliases + domain->alias_cache->num_dom_aliases, + dom_aliases, + num_dom_aliases * sizeof(struct acct_info)); + domain->alias_cache->num_dom_aliases += num_dom_aliases; + } + talloc_destroy(mem_ctx2); + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + + 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; + + status = lookup_alias_sids(domain, mem_ctx, + rid_to_talloced_sid(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); + 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) && domain->alias_cache) { + 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 void add_local_groups(TALLOC_CTX *mem_ctx, DOM_SID *user_sid, + uint32 n_groups, DOM_GID *user_groups, + uint32 *groups_out, DOM_SID **sids_out) +{ + int i; + struct winbindd_domain *dom; + DOM_SID user_dom; + + sid_copy(&user_dom, user_sid); + user_dom.num_auths--; + + for (dom=domain_list(); dom; dom=dom->next) { + init_alias_cache(dom); + if (!dom->alias_cache) { + continue; + } + + for (i=0;ialias_cache->num_dom_aliases;i++) { + DOM_SID alias_sid; + int j, k; + BOOL added = False; + struct alias_cache_info *alias = &dom->alias_cache->per_alias[i]; + + sid_copy(&alias_sid, &dom->sid); + sid_append_rid(&alias_sid, dom->alias_cache->dom_aliases[i].rid); + + for (j=0;!added && jnum_members;j++) { + uint32 alias_rid; + BOOL add_alias = False; + + if (sid_compare(user_sid, &alias->alias_sid_mem[j]) == 0) { + add_alias = True; + } + + + sid_peek_rid(&alias->alias_sid_mem[j], &alias_rid); + + if (!add_alias && + sid_compare_domain(&user_dom, + &alias->alias_sid_mem[j]) == 0) { + 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,9 +681,10 @@ got_dom_pol = True; + /* Get user handle */ result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol, - des_access, user_rid, &user_pol); + des_access, user_rid, &user_pol); if (!NT_STATUS_IS_OK(result)) goto done; @@ -416,16 +693,32 @@ /* 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)) + goto done; + + sid_copy(&user_sid, &domain->sid); + sid_append_rid(&user_sid, user_rid); + init_dom_sid2(&sid2, &user_sid); + + /* ignore errors from this */ + + (*num_sids) = n_groups; - if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0) + (*user_sids) = talloc(mem_ctx, sizeof(**user_sids) * (*num_sids)); + if (!(*user_sids)) { + result = NT_STATUS_NO_MEMORY; goto done; + } - (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups)); - for (i=0;i<(*num_groups);i++) { - (*user_gids)[i] = user_groups[i].g_rid; + for (i=0;isid); + sid_append_rid(&(*user_sids)[i], user_groups[i].g_rid); } - + + add_local_groups(mem_ctx, &user_sid, n_groups, user_groups, num_sids, user_sids); + done: /* Clean up policy handles */ if (got_user_pol) @@ -438,6 +731,119 @@ } +/* Lookup sids in an alias given an alias sid */ +static NTSTATUS lookup_alias_sids(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + DOM_SID *group_sid, uint32 *num_names, + DOM_SID **sids) +{ + CLI_POLICY_HND *hnd = NULL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + POLICY_HND dom_pol, group_pol; + uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; + BOOL got_dom_pol = False, got_group_pol = False; + int retry; + uint32 group_rid; + + DEBUG(10,("rpc: lookup_alias_sids %s sid=%s\n", domain->name, sid_string_static(group_sid))); + + *num_names = 0; + + if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) { + goto done; + } + + 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; + + result = cli_samr_query_aliasmem(hnd->cli, mem_ctx, + &group_pol, num_names, sids); + + 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 alias membership given a rid. */ +static NTSTATUS lookup_aliasmem(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + DOM_SID *group_sid, uint32 *num_names, + DOM_SID ***sid_mem, char ***names, + uint32 **name_types) +{ + NTSTATUS result; + uint32 i, total_names = 0; + DOM_SID *sids; + + + result = lookup_alias_sids(domain, mem_ctx, group_sid, num_names, &sids); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + if (*num_names == 0) { + goto done; + } + + *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: + return result; +} + + /* Lookup group membership given a rid. */ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, @@ -477,8 +883,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, rid_to_talloced_sid(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 */ Index: nsswitch/winbindd_util.c =================================================================== RCS file: /home/cvs/samba/source/nsswitch/winbindd_util.c,v retrieving revision 1.7.6.6 diff -u -u -r1.7.6.6 winbindd_util.c --- nsswitch/winbindd_util.c 14 Mar 2003 21:21:34 -0000 1.7.6.6 +++ nsswitch/winbindd_util.c 9 Oct 2003 11:11:04 -0000 @@ -149,6 +149,7 @@ domain->name, sid_string_static(&domain->sid))); + DEBUG(1, ("getting trusted domain list\n")); result = cache_methods.trusted_domains(domain, mem_ctx, (uint *)&num_domains, @@ -167,6 +168,11 @@ } } +#if 0 + domain = add_trusted_domain("BUILTIN", &cache_methods); + string_to_sid(&domain->sid, "S-1-5-32"); +#endif + talloc_destroy(mem_ctx); return True; } @@ -388,3 +394,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; +} + Index: passdb/pdb_ldap.c =================================================================== RCS file: /home/cvs/samba/source/passdb/pdb_ldap.c,v retrieving revision 1.4.2.10 diff -u -u -r1.4.2.10 pdb_ldap.c --- passdb/pdb_ldap.c 14 Mar 2003 21:21:35 -0000 1.4.2.10 +++ passdb/pdb_ldap.c 9 Oct 2003 11:11:05 -0000 @@ -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; } Index: rpc_parse/parse_samr.c =================================================================== RCS file: /home/cvs/samba/source/rpc_parse/parse_samr.c,v retrieving revision 1.94.4.25.2.8 diff -u -u -r1.94.4.25.2.8 parse_samr.c --- rpc_parse/parse_samr.c 14 Mar 2003 21:21:36 -0000 1.94.4.25.2.8 +++ rpc_parse/parse_samr.c 9 Oct 2003 11:11:07 -0000 @@ -4485,7 +4485,6 @@ prs_struct *ps, int depth) { uint32 i; - uint32 ptr_sid[MAX_LOOKUP_SIDS]; if (r_u == NULL) return False; @@ -4501,24 +4500,31 @@ if(!prs_uint32("ptr", ps, depth, &r_u->ptr)) return False; - if (r_u->ptr != 0) { - SMB_ASSERT_ARRAY(ptr_sid, r_u->num_sids); + if (r_u->ptr != 0 && r_u->num_sids != 0) { + uint32 *ptr_sid; - if (r_u->num_sids != 0) { - if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1)) - return False; + if(!prs_uint32("num_sids1", ps, depth, &r_u->num_sids1)) + return False; - for (i = 0; i < r_u->num_sids1; i++) { - ptr_sid[i] = 1; - if(!prs_uint32("", ps, depth, &ptr_sid[i])) - return False; - } - - 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)) - return False; - } + ptr_sid = talloc(ps->mem_ctx, sizeof(uint32) * r_u->num_sids1); + if (!ptr_sid) { + return False; + } + + for (i = 0; i < r_u->num_sids1; i++) { + ptr_sid[i] = 1; + if(!prs_uint32("", ps, depth, &ptr_sid[i])) + 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)) + return False; } } } Index: rpc_server/srv_lsa_nt.c =================================================================== RCS file: /home/cvs/samba/source/rpc_server/srv_lsa_nt.c,v retrieving revision 1.1.2.16.2.5 diff -u -u -r1.1.2.16.2.5 srv_lsa_nt.c --- rpc_server/srv_lsa_nt.c 17 Jun 2002 18:36:28 -0000 1.1.2.16.2.5 +++ rpc_server/srv_lsa_nt.c 9 Oct 2003 11:11:08 -0000 @@ -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 Index: rpc_server/srv_reg_nt.c =================================================================== RCS file: /home/cvs/samba/source/rpc_server/srv_reg_nt.c,v retrieving revision 1.1.2.7.2.3 diff -u -u -r1.1.2.7.2.3 srv_reg_nt.c --- rpc_server/srv_reg_nt.c 14 Mar 2003 21:21:37 -0000 1.1.2.7.2.3 +++ rpc_server/srv_reg_nt.c 9 Oct 2003 11:11:08 -0000 @@ -148,7 +148,7 @@ goto out; } - switch (lp_server_role()) { + switch (dva_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: key = "LanmanNT"; Index: rpc_server/srv_samr_nt.c =================================================================== RCS file: /home/cvs/samba/source/rpc_server/srv_samr_nt.c,v retrieving revision 1.1.2.31.2.9 diff -u -u -r1.1.2.31.2.9 srv_samr_nt.c --- rpc_server/srv_samr_nt.c 14 Mar 2003 21:21:37 -0000 1.1.2.31.2.9 +++ rpc_server/srv_samr_nt.c 9 Oct 2003 11:11:10 -0000 @@ -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; Index: rpc_server/srv_spoolss_nt.c =================================================================== RCS file: /home/cvs/samba/source/rpc_server/srv_spoolss_nt.c,v retrieving revision 1.115.2.83.2.12 diff -u -u -r1.115.2.83.2.12 srv_spoolss_nt.c --- rpc_server/srv_spoolss_nt.c 14 Mar 2003 21:21:37 -0000 1.115.2.83.2.12 +++ rpc_server/srv_spoolss_nt.c 9 Oct 2003 11:11:14 -0000 @@ -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); Index: rpcclient/cmd_samr.c =================================================================== RCS file: /home/cvs/samba/source/rpcclient/cmd_samr.c,v retrieving revision 1.104.4.3.2.8 diff -u -u -r1.104.4.3.2.8 cmd_samr.c --- rpcclient/cmd_samr.c 14 Mar 2003 21:21:39 -0000 1.104.4.3.2.8 +++ rpcclient/cmd_samr.c 9 Oct 2003 11:11:15 -0000 @@ -682,14 +682,14 @@ start_idx = 0; size = 0xffff; - result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol, - &start_idx, size, - &dom_groups, &num_dom_groups); - - for (i = 0; i < num_dom_groups; i++) - printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name, - dom_groups[i].rid); - + do { + result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol, + &start_idx, size, + &dom_groups, &num_dom_groups); + for (i = 0; i < num_dom_groups; i++) + printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name, + dom_groups[i].rid); + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); done: return result; } Index: smbd/blocking.c =================================================================== RCS file: /home/cvs/samba/source/smbd/blocking.c,v retrieving revision 1.14.4.1.2.7 diff -u -u -r1.14.4.1.2.7 blocking.c --- smbd/blocking.c 28 Feb 2003 14:42:47 -0000 1.14.4.1.2.7 +++ smbd/blocking.c 9 Oct 2003 11:11:16 -0000 @@ -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)); Index: smbd/close.c =================================================================== RCS file: /home/cvs/samba/source/smbd/close.c,v retrieving revision 1.22.4.8.2.5 diff -u -u -r1.22.4.8.2.5 close.c --- smbd/close.c 28 Feb 2003 14:42:47 -0000 1.22.4.8.2.5 +++ smbd/close.c 9 Oct 2003 11:11:16 -0000 @@ -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); } /* Index: smbd/dosmode.c =================================================================== RCS file: /home/cvs/samba/source/smbd/dosmode.c,v retrieving revision 1.14.4.8.2.2 diff -u -u -r1.14.4.8.2.2 dosmode.c --- smbd/dosmode.c 30 Apr 2002 13:28:19 -0000 1.14.4.8.2.2 +++ smbd/dosmode.c 9 Oct 2003 11:11:16 -0000 @@ -45,71 +45,60 @@ ****************************************************************************/ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname) { - mode_t result = (S_IRUSR | S_IRGRP | S_IROTH); - mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */ + mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); + mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */ - if ( !IS_DOS_READONLY(dosmode) ) - result |= (S_IWUSR | S_IWGRP | S_IWOTH); - - if (fname && lp_inherit_perms(SNUM(conn))) { - char *dname; - SMB_STRUCT_STAT sbuf; - - dname = parent_dirname(fname); - DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); - if (vfs_stat(conn,dname,&sbuf) != 0) { - DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); - return(0); /* *** shouldn't happen! *** */ - } - - /* Save for later - but explicitly remove setuid bit for safety. */ - dir_mode = sbuf.st_mode & ~S_ISUID; - DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode)); - /* Clear "result" */ - result = 0; - } - - if (IS_DOS_DIR(dosmode)) { - /* We never make directories read only for the owner as under DOS a user - can always create a file in a read-only directory. */ - result |= (S_IFDIR | S_IWUSR); - - if (dir_mode) { - /* Inherit mode of parent directory. */ - result |= dir_mode; - } else { - /* Provisionally add all 'x' bits */ - result |= (S_IXUSR | S_IXGRP | S_IXOTH); - - /* Apply directory mask */ - result &= lp_dir_mask(SNUM(conn)); - /* Add in force bits */ - result |= lp_force_dir_mode(SNUM(conn)); - } - } else { - if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode)) - result |= S_IXUSR; - - if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode)) - result |= S_IXGRP; - - if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode)) - result |= S_IXOTH; - - if (dir_mode) { - /* Inherit 666 component of parent directory mode */ - result |= dir_mode - & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); - } else { - /* Apply mode mask */ - result &= lp_create_mask(SNUM(conn)); - /* Add in force bits */ - result |= lp_force_create_mode(SNUM(conn)); - } - } - - DEBUG(3,("unix_mode(%s) returning 0%o\n",fname,(int)result )); - return(result); + if (fname && lp_inherit_perms(SNUM(conn))) { + char *dname; + SMB_STRUCT_STAT sbuf; + + dname = parent_dirname(fname); + DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname)); + if (vfs_stat(conn,dname,&sbuf) != 0) { + DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno))); + return(0); /* *** shouldn't happen! *** */ + } + + /* Save for later - but explicitly remove setuid bit for safety. */ + dir_mode = sbuf.st_mode & ~S_ISUID; + DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode)); + /* Clear "result" */ + result = 0; + } + + if (IS_DOS_DIR(dosmode)) { + /* We never make directories read only for the owner as under DOS a user + can always create a file in a read-only directory. */ + result |= (S_IFDIR | S_IWUSR); + + if (dir_mode) { + /* Inherit mode of parent directory. */ + result |= dir_mode; + } else { + /* Provisionally add all 'x' bits */ + result |= (S_IXUSR | S_IXGRP | S_IXOTH); + + /* Apply directory mask */ + result &= lp_dir_mask(SNUM(conn)); + /* Add in force bits */ + result |= lp_force_dir_mode(SNUM(conn)); + } + + } else { + if (dir_mode) { + /* Inherit 666 component of parent directory mode */ + result |= dir_mode + & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); + } else { + /* Apply mode mask */ + result &= lp_create_mask(SNUM(conn)); + /* Add in force bits */ + result |= lp_force_create_mode(SNUM(conn)); + } + } + + DEBUG(4,("unix_mode(%s) returning 0%o\n",fname,(int)result )); + return(result); } @@ -118,63 +107,36 @@ ****************************************************************************/ int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf) { - int result = 0; + fstring attr; + int rc, dosattr; + int ret = 0; - DEBUG(8,("dos_mode: %s\n", path)); - - if ((sbuf->st_mode & S_IWUSR) == 0) - result |= aRONLY; + if (S_ISDIR(sbuf->st_mode)) { + ret |= aDIR; + } - if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) - result |= aARCH; - - if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0)) - result |= aSYSTEM; - - if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0)) - result |= aHIDDEN; - - if (S_ISDIR(sbuf->st_mode)) - result = aDIR | (result & aRONLY); - -#ifdef S_ISLNK -#if LINKS_READ_ONLY - if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode)) - result |= aRONLY; -#endif -#endif - - /* hide files with a name starting with a . */ - if (lp_hide_dot_files(SNUM(conn))) - { - char *p = strrchr(path,'/'); - if (p) - p++; - else - p = path; - - if (p[0] == '.' && p[1] != '.' && p[1] != 0) - result |= aHIDDEN; - } - - /* Optimization : Only call is_hidden_path if it's not already - hidden. */ - if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) - { - result |= aHIDDEN; - } - - DEBUG(8,("dos_mode returning ")); - - if (result & aHIDDEN) DEBUG(8, ("h")); - if (result & aRONLY ) DEBUG(8, ("r")); - if (result & aSYSTEM) DEBUG(8, ("s")); - if (result & aDIR ) DEBUG(8, ("d")); - if (result & aARCH ) DEBUG(8, ("a")); + rc = sys_getxattr(path, XATTR_DOS_ATTRIB, attr, sizeof(attr)); + if (rc == -1) { + if (errno != ENODATA) { + DEBUG(0,("getxattr failed for %s - %s\n", path, strerror(errno))); + } + return ret; + } + + attr[rc] = 0; + + if (rc < 2 || + strncmp(attr, "0x", 2) != 0 || + sscanf(attr, "%i", &dosattr) != 1) { + DEBUG(3,("Badly formed DOSATTRIB - %s\n", attr)); + return ret; + } - DEBUG(8,("\n")); + ret |= dosattr; - return(result); + DEBUG(4,("dosmode for %s is 0x%x\n", path, ret)); + + return ret; } /******************************************************************* @@ -183,65 +145,36 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st) { SMB_STRUCT_STAT st1; - int mask=0; - mode_t tmp; - mode_t unixmode; int ret = -1; + fstring attr; if (!st) { st = &st1; - if (vfs_stat(conn,fname,st)) - return(-1); + if (vfs_stat(conn,fname,st)) { + return -1; + } } - if (S_ISDIR(st->st_mode)) + if (S_ISDIR(st->st_mode)) { dosmode |= aDIR; - else + } else { dosmode &= ~aDIR; - - if (dos_mode(conn,fname,st) == dosmode) - return(0); - - unixmode = unix_mode(conn,dosmode,fname); - - /* preserve the s bits */ - mask |= (S_ISUID | S_ISGID); - - /* preserve the t bit */ -#ifdef S_ISVTX - mask |= S_ISVTX; -#endif - - /* possibly preserve the x bits */ - if (!MAP_ARCHIVE(conn)) - mask |= S_IXUSR; - if (!MAP_SYSTEM(conn)) - mask |= S_IXGRP; - if (!MAP_HIDDEN(conn)) - mask |= S_IXOTH; - - unixmode |= (st->st_mode & mask); - - /* if we previously had any r bits set then leave them alone */ - if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) { - unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH); - unixmode |= tmp; } - /* if we previously had any w bits set then leave them alone - whilst adding in the new w bits, if the new mode is not rdonly */ - if (!IS_DOS_READONLY(dosmode)) { - unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)); + if (dos_mode(conn,fname,st) == dosmode) { + return 0; } - if ((ret = vfs_chmod(conn,fname,unixmode)) == 0) + snprintf(attr, sizeof(attr)-1, "0x%x", dosmode & 0x3F); + + ret = sys_setxattr(fname, XATTR_DOS_ATTRIB, attr, strlen(attr), 0); + if (ret == 0) { return 0; + } + - if((errno != EPERM) && (errno != EACCES)) - return -1; + DEBUG(3,("setxattr failed for %s - %s\n", fname, strerror(errno))); - if(!lp_dos_filemode(SNUM(conn))) - return -1; /* We want DOS semantics, ie allow non owner with write permission to change the bits on a file. Just like file_utime below. @@ -249,24 +182,16 @@ /* Check if we have write access. */ if (CAN_WRITE(conn)) { - /* - * We need to open the file with write access whilst - * still in our current user context. This ensures we - * are not violating security in doing the fchmod. - * This file open does *not* break any oplocks we are - * holding. We need to review this.... may need to - * break batch oplocks open by others. JRA. - */ files_struct *fsp = open_file_fchmod(conn,fname,st); if (!fsp) return -1; become_root(); - ret = conn->vfs_ops.fchmod(fsp, fsp->fd, unixmode); + ret = sys_fsetxattr(fsp->fd, XATTR_DOS_ATTRIB, attr, strlen(attr), 0); unbecome_root(); close_file_fchmod(fsp); } - return( ret ); + return ret; } Index: smbd/fileio.c =================================================================== RCS file: /home/cvs/samba/source/smbd/fileio.c,v retrieving revision 1.23.2.7.2.4 diff -u -u -r1.23.2.7.2.4 fileio.c --- smbd/fileio.c 10 Dec 2002 16:35:39 -0000 1.23.2.7.2.4 +++ smbd/fileio.c 9 Oct 2003 11:11:17 -0000 @@ -177,8 +177,9 @@ if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&st) == 0) { int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st); fsp->size = (SMB_BIG_UINT)st.st_size; - if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) + if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) { file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st); + } /* * If this is the first write and we have an exclusive oplock then setup Index: smbd/nttrans.c =================================================================== RCS file: /home/cvs/samba/source/smbd/nttrans.c,v retrieving revision 1.104.4.15.2.12 diff -u -u -r1.104.4.15.2.12 nttrans.c --- smbd/nttrans.c 14 Mar 2003 21:21:40 -0000 1.104.4.15.2.12 +++ smbd/nttrans.c 9 Oct 2003 11:11:18 -0000 @@ -902,6 +902,12 @@ END_PROFILE(SMBntcreateX); return ERROR_DOS(ERRDOS,ERRnoaccess); } + + /* files should be initially set as archive */ + if (smb_action == FILE_WAS_CREATED) { + file_chmod(fsp->conn,fsp->fsp_name,fmode | aARCH,&sbuf); + } + /* Save the requested allocation size. */ allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_ntcreate_AllocationSize); Index: smbd/posix_acls.c =================================================================== RCS file: /home/cvs/samba/source/smbd/posix_acls.c,v retrieving revision 1.1.4.33.2.8 diff -u -u -r1.1.4.33.2.8 posix_acls.c --- smbd/posix_acls.c 14 Mar 2003 21:21:40 -0000 1.1.4.33.2.8 +++ smbd/posix_acls.c 9 Oct 2003 11:11:20 -0000 @@ -19,6 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define ACL_FORCE_UNMAPPABLE 1 + #include "includes.h" /**************************************************************************** @@ -1003,12 +1005,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 +2466,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 +2482,7 @@ * flag doesn't seem to bother Windows NT. */ (*ppdesc)->type |= SE_DESC_DACL_PROTECTED; +#endif } done: Index: smbd/reply.c =================================================================== RCS file: /home/cvs/samba/source/smbd/reply.c,v retrieving revision 1.240.2.26.2.20 diff -u -u -r1.240.2.26.2.20 reply.c --- smbd/reply.c 7 Apr 2003 14:51:23 -0000 1.240.2.26.2.20 +++ smbd/reply.c 9 Oct 2003 11:11:24 -0000 @@ -713,9 +713,12 @@ BOOL doencrypt = SMBENCRYPT(); fstring domain; NT_USER_TOKEN *ptok = NULL; + userdom_struct current_user_info_saved; START_PROFILE(SMBsesssetupX); + current_user_info_saved = current_user_info; + *smb_apasswd = 0; *smb_ntpasswd = 0; *domain = 0; @@ -884,6 +887,8 @@ alpha_strcpy(user, user, ". _-$", sizeof(user)); alpha_strcpy(domain, domain, ". _-@", sizeof(domain)); if (strstr(user, "..") || strstr(domain,"..")) { + current_user_info = current_user_info_saved; + sub_set_smb_name(current_user_info.smb_name); return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw); } @@ -895,6 +900,8 @@ if (*user && (user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) { END_PROFILE(SMBsesssetupX); + current_user_info = current_user_info_saved; + sub_set_smb_name(current_user_info.smb_name); return session_trust_account(conn, inbuf, outbuf, user, smb_apasswd, smb_apasslen, smb_ntpasswd, smb_ntpasslen); @@ -911,6 +918,8 @@ if (!*user && !*smb_apasswd && !*domain) { DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n")); END_PROFILE(SMBsesssetupX); + current_user_info = current_user_info_saved; + sub_set_smb_name(current_user_info.smb_name); return(ERROR_DOS(ERRDOS,ERRnoaccess)); } } @@ -1019,10 +1028,12 @@ { if (lp_map_to_guest() == NEVER_MAP_TO_GUEST) { - delete_nt_token(&ptok); - DEBUG(1,("Rejecting user '%s': authentication failed\n", user)); - END_PROFILE(SMBsesssetupX); - return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw); + delete_nt_token(&ptok); + DEBUG(1,("Rejecting user '%s': authentication failed\n", user)); + END_PROFILE(SMBsesssetupX); + current_user_info = current_user_info_saved; + sub_set_smb_name(current_user_info.smb_name); + return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw); } if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) @@ -1047,6 +1058,8 @@ DEBUG(1,("Rejecting user '%s': bad password\n", user)); END_PROFILE(SMBsesssetupX); pdb_free_sam(sampass); + current_user_info = current_user_info_saved; + sub_set_smb_name(current_user_info.smb_name); return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw); } @@ -1103,6 +1116,8 @@ delete_nt_token(&ptok); DEBUG(1,("Username %s is invalid on this system\n",user)); END_PROFILE(SMBsesssetupX); + current_user_info = current_user_info_saved; + sub_set_smb_name(current_user_info.smb_name); return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw); } gid = pw->pw_gid; @@ -1121,6 +1136,8 @@ if (sess_vuid == -1) { END_PROFILE(SMBsesssetupX); + current_user_info = current_user_info_saved; + sub_set_smb_name(current_user_info.smb_name); return(ERROR_DOS(ERRDOS,ERRnoaccess)); } @@ -1162,7 +1179,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) { Index: smbd/server.c =================================================================== RCS file: /home/cvs/samba/source/smbd/server.c,v retrieving revision 1.305.2.16.2.9 diff -u -u -r1.305.2.16.2.9 server.c --- smbd/server.c 14 Mar 2003 21:21:40 -0000 1.305.2.16.2.9 +++ smbd/server.c 9 Oct 2003 11:11:25 -0000 @@ -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())); Index: smbd/trans2.c =================================================================== RCS file: /home/cvs/samba/source/smbd/trans2.c,v retrieving revision 1.149.4.16.2.17 diff -u -u -r1.149.4.16.2.17 trans2.c --- smbd/trans2.c 7 Apr 2003 14:51:23 -0000 1.149.4.16.2.17 +++ smbd/trans2.c 9 Oct 2003 11:11:27 -0000 @@ -2206,6 +2206,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; @@ -3041,7 +3044,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; Index: utils/smbpasswd.c =================================================================== RCS file: /home/cvs/samba/source/utils/smbpasswd.c,v retrieving revision 1.93.2.2.2.10 diff -u -u -r1.93.2.2.2.10 smbpasswd.c --- utils/smbpasswd.c 14 Mar 2003 21:21:41 -0000 1.93.2.2.2.10 +++ utils/smbpasswd.c 9 Oct 2003 11:11:29 -0000 @@ -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