1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

r13494: Merge the stuff I've done in head the last days.

Volker
(This used to be commit bb40e544de68f01a6e774753f508e69373b39899)
This commit is contained in:
Volker Lendecke 2006-02-13 17:08:25 +00:00 committed by Gerald (Jerry) Carter
parent 3b67210eec
commit 301d51e13a
17 changed files with 1070 additions and 1471 deletions

View File

@ -194,7 +194,7 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/interfaces.o lib/pidfile.o lib/replace.o lib/replace1.o \
lib/signal.o lib/system.o lib/sendfile.o lib/time.o \
lib/ufc.o lib/genrand.o lib/username.o \
lib/util_getent.o lib/util_pw.o lib/access.o lib/smbrun.o \
lib/util_pw.o lib/access.o lib/smbrun.o \
lib/bitmap.o lib/crc32.o $(SNPRINTF_OBJ) lib/dprintf.o \
lib/xfile.o lib/wins_srv.o \
lib/util_str.o lib/clobber.o lib/util_sid.o lib/util_uuid.o \
@ -209,7 +209,7 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
lib/module.o lib/events.o lib/ldap_escape.o @CHARSET_STATIC@ \
lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o @SOCKWRAP@ \
libads/krb5_errs.o
libads/krb5_errs.o lib/system_smbd.o
LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o
LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ)
@ -326,7 +326,7 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
passdb/util_wellknown.o passdb/util_builtin.o passdb/pdb_compat.o \
passdb/util_unixsids.o passdb/lookup_sid.o \
passdb/login_cache.o @PDB_STATIC@ \
lib/system_smbd.o lib/account_pol.o lib/privileges.o
lib/account_pol.o lib/privileges.o
DEVEL_HELP_WEIRD_OBJ = modules/weird.o
CP850_OBJ = modules/CP850.o
@ -386,7 +386,7 @@ SMBD_OBJ_MAIN = smbd/server.o
BUILDOPT_OBJ = smbd/build_options.o
SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/utmp.o smbd/session.o \
smbd/utmp.o smbd/session.o smbd/map_username.o \
smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o \
smbd/share_access.o smbd/fileio.o \
smbd/ipc.o smbd/lanman.o smbd/negprot.o \

View File

@ -1018,6 +1018,72 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
return result;
}
/***************************************************************************
Build upon create_token_from_username:
Expensive helper function to figure out whether a user given its name is
member of a particular group.
***************************************************************************/
BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
{
NTSTATUS status;
uid_t uid;
gid_t gid;
char *found_username;
struct nt_user_token *token;
BOOL result;
TALLOC_CTX *mem_ctx;
mem_ctx = talloc_new(NULL);
if (mem_ctx == NULL) {
DEBUG(0, ("talloc_new failed\n"));
return False;
}
status = create_token_from_username(mem_ctx, username, False,
&uid, &gid, &found_username,
&token);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("could not create token for %s\n", username));
return False;
}
result = nt_token_check_sid(group_sid, token);
talloc_free(mem_ctx);
return result;
}
BOOL user_in_group(const char *username, const char *groupname)
{
TALLOC_CTX *mem_ctx;
DOM_SID group_sid;
NTSTATUS status;
BOOL ret;
mem_ctx = talloc_new(NULL);
if (mem_ctx == NULL) {
DEBUG(0, ("talloc_new failed\n"));
return False;
}
ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
NULL, NULL, &group_sid, NULL);
talloc_free(mem_ctx);
if (!ret) {
DEBUG(10, ("lookup_name(%s) failed: %s\n", groupname,
nt_errstr(status)));
return False;
}
return user_in_group_sid(username, &group_sid);
}
/***************************************************************************
Make (and fill) a user_info struct from a Kerberos PAC logon_info by
conversion to a SAM_ACCOUNT

View File

@ -157,26 +157,26 @@ static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
/****************************************************************************
initialise first time the mapping list
****************************************************************************/
BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use, const char *nt_name, const char *comment)
NTSTATUS add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use, const char *nt_name, const char *comment)
{
GROUP_MAP map;
if(!init_group_mapping()) {
DEBUG(0,("failed to initialize group mapping\n"));
return(False);
return NT_STATUS_UNSUCCESSFUL;
}
map.gid=gid;
if (!string_to_sid(&map.sid, sid)) {
DEBUG(0, ("string_to_sid failed: %s", sid));
return False;
return NT_STATUS_UNSUCCESSFUL;
}
map.sid_name_use=sid_name_use;
fstrcpy(map.nt_name, nt_name);
fstrcpy(map.comment, comment);
return NT_STATUS_IS_OK(pdb_add_group_mapping_entry(&map));
return pdb_add_group_mapping_entry(&map);
}
/****************************************************************************
@ -856,7 +856,7 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
Create a UNIX group on demand.
****************************************************************************/
int smb_create_group(char *unix_group, gid_t *new_gid)
int smb_create_group(const char *unix_group, gid_t *new_gid)
{
pstring add_script;
int ret = -1;
@ -901,7 +901,7 @@ int smb_create_group(char *unix_group, gid_t *new_gid)
Delete a UNIX group on demand.
****************************************************************************/
int smb_delete_group(char *unix_group)
int smb_delete_group(const char *unix_group)
{
pstring del_script;
int ret;
@ -947,7 +947,7 @@ int smb_set_primary_group(const char *unix_group, const char* unix_user)
Add a user to a UNIX group.
****************************************************************************/
int smb_add_user_group(char *unix_group, char *unix_user)
int smb_add_user_group(const char *unix_group, const char *unix_user)
{
pstring add_script;
int ret;
@ -1122,8 +1122,7 @@ NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods,
const DOM_SID *sid)
{
return pdb_delete_group_mapping_entry(*sid) ?
NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
return pdb_delete_group_mapping_entry(*sid);
}
NTSTATUS pdb_default_get_aliasinfo(struct pdb_methods *methods,

View File

@ -262,6 +262,13 @@ struct pdb_methods
NTSTATUS (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username);
NTSTATUS (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid);
NTSTATUS (*create_user)(struct pdb_methods *, TALLOC_CTX *tmp_ctx,
const char *name, uint32 acct_flags,
uint32 *rid);
NTSTATUS (*delete_user)(struct pdb_methods *, TALLOC_CTX *tmp_ctx,
SAM_ACCOUNT *sam_acct);
NTSTATUS (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
@ -279,6 +286,13 @@ struct pdb_methods
NTSTATUS (*getgrnam)(struct pdb_methods *methods, GROUP_MAP *map, const char *name);
NTSTATUS (*create_dom_group)(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx, const char *name,
uint32 *rid);
NTSTATUS (*delete_dom_group)(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx, uint32 rid);
NTSTATUS (*add_group_mapping_entry)(struct pdb_methods *methods,
GROUP_MAP *map);
@ -305,6 +319,18 @@ struct pdb_methods
DOM_SID **pp_sids, gid_t **pp_gids,
size_t *p_num_groups);
NTSTATUS (*set_unix_primary_group)(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
SAM_ACCOUNT *user);
NTSTATUS (*add_groupmem)(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
uint32 group_rid, uint32 member_rid);
NTSTATUS (*del_groupmem)(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
uint32 group_rid, uint32 member_rid);
NTSTATUS (*find_alias)(struct pdb_methods *methods,
const char *name, DOM_SID *sid);

View File

@ -123,14 +123,16 @@ static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grp
DEBUG(10,("sys_getgrouplist: user [%s]\n", user));
/* see if we should disable winbindd lookups for local users */
if (strchr(user, *lp_winbind_separator()) == NULL) {
if ( !winbind_off() )
DEBUG(0,("sys_getgroup_list: Insufficient environment space "
"for %s\n", WINBINDD_DONT_ENV));
else
DEBUG(10,("sys_getgrouplist(): disabled winbindd for group "
"lookup [user == %s]\n", user));
/* This is only ever called for Unix users, remote memberships are
* always determined by the info3 coming back from auth3 or the
* PAC. */
if ( !winbind_off() ) {
DEBUG(0,("sys_getgroup_list: Insufficient environment space "
"for %s\n", WINBINDD_DONT_ENV));
} else {
DEBUG(10,("sys_getgrouplist(): disabled winbindd for group "
"lookup [user == %s]\n", user));
}
#ifdef HAVE_GETGROUPLIST
@ -198,62 +200,3 @@ BOOL getgroups_unix_user(TALLOC_CTX *mem_ctx, const char *user,
SAFE_FREE(temp_groups);
return True;
}
NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
SAM_ACCOUNT *user,
DOM_SID **pp_sids,
gid_t **pp_gids,
size_t *p_num_groups)
{
size_t i;
gid_t gid;
if ( !sid_to_gid(pdb_get_group_sid(user), &gid) )
{
uint32 rid;
struct passwd *pwd;
/* second try, allow the DOMAIN_USERS group to pass */
if ( !sid_peek_check_rid( get_global_sam_sid(), pdb_get_group_sid(user), &rid ) )
return NT_STATUS_NO_SUCH_USER;
if ( rid != DOMAIN_GROUP_RID_USERS ) {
DEBUG(10, ("sid_to_gid failed\n"));
return NT_STATUS_NO_SUCH_USER;
}
DEBUG(5,("pdb_default_enum_group_memberships: sid_to_gid() failed but giving "
"free pass to 'Domain Users' as primary group\n"));
if ( !(pwd = getpwnam_alloc( NULL, pdb_get_username(user) ) ) )
return NT_STATUS_NO_SUCH_USER;
gid = pwd->pw_gid;
TALLOC_FREE( pwd );
}
if (!getgroups_unix_user(mem_ctx, pdb_get_username(user), gid,
pp_gids, p_num_groups)) {
return NT_STATUS_NO_SUCH_USER;
}
if (*p_num_groups == 0) {
smb_panic("primary group missing");
}
*pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups);
if (*pp_sids == NULL) {
talloc_free(*pp_gids);
return NT_STATUS_NO_MEMORY;
}
for (i=0; i<*p_num_groups; i++) {
gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]);
}
return NT_STATUS_OK;
}

View File

@ -29,16 +29,6 @@ static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, i
struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
int N);
/*****************************************************************
Check if a user or group name is local (this is a *local* name for
*local* people, there's nothing for you here...).
*****************************************************************/
static BOOL name_is_local(const char *name)
{
return !(strchr_m(name, *lp_winbind_separator()));
}
/****************************************************************************
Get a users home directory.
****************************************************************************/
@ -58,161 +48,6 @@ char *get_user_home_dir(const char *user)
return(pass->pw_dir);
}
/*******************************************************************
Map a username from a dos name to a unix name by looking in the username
map. Note that this modifies the name in place.
This is the main function that should be called *once* on
any incoming or new username - in order to canonicalize the name.
This is being done to de-couple the case conversions from the user mapping
function. Previously, the map_username was being called
every time Get_Pwnam was called.
Returns True if username was changed, false otherwise.
********************************************************************/
BOOL map_username(fstring user)
{
static BOOL initialised=False;
static fstring last_from,last_to;
XFILE *f;
char *mapfile = lp_username_map();
char *s;
pstring buf;
BOOL mapped_user = False;
char *cmd = lp_username_map_script();
if (!*user)
return False;
if (strequal(user,last_to))
return False;
if (strequal(user,last_from)) {
DEBUG(3,("Mapped user %s to %s\n",user,last_to));
fstrcpy(user,last_to);
return True;
}
/* first try the username map script */
if ( *cmd ) {
char **qlines;
pstring command;
int numlines, ret, fd;
pstr_sprintf( command, "%s \"%s\"", cmd, user );
DEBUG(10,("Running [%s]\n", command));
ret = smbrun(command, &fd);
DEBUGADD(10,("returned [%d]\n", ret));
if ( ret != 0 ) {
if (fd != -1)
close(fd);
return False;
}
numlines = 0;
qlines = fd_lines_load(fd, &numlines,0);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
/* should be either no lines or a single line with the mapped username */
if (numlines) {
DEBUG(3,("Mapped user %s to %s\n", user, qlines[0] ));
fstrcpy( user, qlines[0] );
}
file_lines_free(qlines);
return numlines != 0;
}
/* ok. let's try the mapfile */
if (!*mapfile)
return False;
if (!initialised) {
*last_from = *last_to = 0;
initialised = True;
}
f = x_fopen(mapfile,O_RDONLY, 0);
if (!f) {
DEBUG(0,("can't open username map %s. Error %s\n",mapfile, strerror(errno) ));
return False;
}
DEBUG(4,("Scanning username map %s\n",mapfile));
while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) {
char *unixname = s;
char *dosname = strchr_m(unixname,'=');
char **dosuserlist;
BOOL return_if_mapped = False;
if (!dosname)
continue;
*dosname++ = 0;
while (isspace((int)*unixname))
unixname++;
if ('!' == *unixname) {
return_if_mapped = True;
unixname++;
while (*unixname && isspace((int)*unixname))
unixname++;
}
if (!*unixname || strchr_m("#;",*unixname))
continue;
{
int l = strlen(unixname);
while (l && isspace((int)unixname[l-1])) {
unixname[l-1] = 0;
l--;
}
}
dosuserlist = str_list_make(dosname, NULL);
if (!dosuserlist) {
DEBUG(0,("Unable to build user list\n"));
return False;
}
if (strchr_m(dosname,'*') ||
user_in_list(user, (const char **)dosuserlist)) {
DEBUG(3,("Mapped user %s to %s\n",user,unixname));
mapped_user = True;
fstrcpy( last_from,user );
fstrcpy( user, unixname );
fstrcpy( last_to,user );
if ( return_if_mapped ) {
str_list_free (&dosuserlist);
x_fclose(f);
return True;
}
}
str_list_free (&dosuserlist);
}
x_fclose(f);
/*
* Setup the last_from and last_to as an optimization so
* that we don't scan the file again for the same user.
*/
fstrcpy(last_from,user);
fstrcpy(last_to,user);
return mapped_user;
}
/****************************************************************************
* A wrapper for sys_getpwnam(). The following variations are tried:
* - as transmitted
@ -334,351 +169,6 @@ struct passwd *Get_Pwnam(const char *user)
return ret;
}
/****************************************************************************
Check if a user is in a netgroup user list. If at first we don't succeed,
try lower case.
****************************************************************************/
BOOL user_in_netgroup(const char *user, const char *ngname)
{
#ifdef HAVE_NETGROUP
static char *mydomain = NULL;
fstring lowercase_user;
if (mydomain == NULL)
yp_get_default_domain(&mydomain);
if(mydomain == NULL) {
DEBUG(5,("Unable to get default yp domain\n"));
return False;
}
DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
user, mydomain, ngname));
if (innetgr(ngname, NULL, user, mydomain)) {
DEBUG(5,("user_in_netgroup: Found\n"));
return (True);
} else {
/*
* Ok, innetgr is case sensitive. Try once more with lowercase
* just in case. Attempt to fix #703. JRA.
*/
fstrcpy(lowercase_user, user);
strlower_m(lowercase_user);
DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
lowercase_user, mydomain, ngname));
if (innetgr(ngname, NULL, lowercase_user, mydomain)) {
DEBUG(5,("user_in_netgroup: Found\n"));
return (True);
}
}
#endif /* HAVE_NETGROUP */
return False;
}
/****************************************************************************
Check if a user is in a winbind group.
****************************************************************************/
static BOOL user_in_winbind_group(const char *user, const char *gname,
BOOL *winbind_answered)
{
int i;
gid_t gid, gid_low, gid_high;
BOOL ret = False;
static gid_t *groups = NULL;
static int num_groups = 0;
static fstring last_user = "";
*winbind_answered = False;
if ((gid = nametogid(gname)) == (gid_t)-1) {
DEBUG(0,("user_in_winbind_group: nametogid for group %s "
"failed.\n", gname ));
goto err;
}
if (!lp_idmap_gid(&gid_low, &gid_high)) {
DEBUG(4, ("winbind gid range not configured, therefore %s "
"cannot be a winbind group\n", gname));
goto err;
}
if (gid < gid_low || gid > gid_high) {
DEBUG(4, ("group %s is not a winbind group\n", gname));
goto err;
}
/* try to user the last user we looked up */
/* otherwise fall back to lookups */
if ( !strequal( last_user, user ) || !groups )
{
/* clear any cached information */
SAFE_FREE(groups);
fstrcpy( last_user, "" );
/*
* Get the gid's that this user belongs to.
*/
if ((num_groups = winbind_getgroups(user, &groups)) == -1)
return False;
if ( num_groups == -1 )
return False;
if ( num_groups == 0 ) {
*winbind_answered = True;
return False;
}
/* save the last username */
fstrcpy( last_user, user );
}
else
DEBUG(10,("user_in_winbind_group: using cached user "
"groups for [%s]\n", user));
if ( DEBUGLEVEL >= 10 ) {
DEBUG(10,("user_in_winbind_group: using groups -- "));
for ( i=0; i<num_groups; i++ )
DEBUGADD(10,("%lu ", (unsigned long)groups[i]));
DEBUGADD(10,("\n"));
}
/*
* Now we have the gid list for this user - convert the gname to a
* gid_t via either winbind or the local UNIX lookup and do the
* comparison.
*/
for (i = 0; i < num_groups; i++) {
if (gid == groups[i]) {
ret = True;
break;
}
}
*winbind_answered = True;
SAFE_FREE(groups);
return ret;
err:
*winbind_answered = False;
SAFE_FREE(groups);
return False;
}
/****************************************************************************
Check if a user is in a UNIX group.
****************************************************************************/
BOOL user_in_unix_group(const char *user,const char *gname)
{
struct passwd *pass = Get_Pwnam(user);
struct sys_userlist *user_list;
struct sys_userlist *member;
DEBUG(10,("user_in_unix_group: checking user %s in group %s\n",
user, gname));
/*
* We need to check the users primary group as this
* group is implicit and often not listed in the group database.
*/
if (pass) {
if (strequal(gname,gidtoname(pass->pw_gid))) {
DEBUG(10,("user_in_unix_group: group %s is "
"primary group.\n", gname ));
return True;
}
}
user_list = get_users_in_group(gname);
if (user_list == NULL) {
DEBUG(10,("user_in_unix_group: no such group %s\n",
gname ));
return False;
}
for (member = user_list; member; member = member->next) {
DEBUG(10,("user_in_unix_group: checking user %s against "
"member %s\n", user, member->unix_name ));
if (strequal(member->unix_name,user)) {
free_userlist(user_list);
return(True);
}
}
free_userlist(user_list);
return False;
}
/****************************************************************************
Check if a user is in a group list. Ask winbind first, then use UNIX.
****************************************************************************/
BOOL user_in_group(const char *user, const char *gname)
{
BOOL winbind_answered = False;
BOOL ret;
ret = user_in_winbind_group(user, gname, &winbind_answered);
if (!winbind_answered)
ret = user_in_unix_group(user, gname);
if (ret)
DEBUG(10,("user_in_group: user |%s| is in group |%s|\n",
user, gname));
return ret;
}
/****************************************************************************
Check if a user is in a user list - can check combinations of UNIX
and netgroup lists.
****************************************************************************/
BOOL user_in_list(const char *user,const char **list)
{
if (!list || !*list)
return False;
DEBUG(10,("user_in_list: checking user %s in list\n", user));
while (*list) {
DEBUG(10,("user_in_list: checking user |%s| against |%s|\n",
user, *list));
/*
* Check raw username.
*/
if (strequal(user, *list))
return(True);
/*
* Now check to see if any combination
* of UNIX and netgroups has been specified.
*/
if(**list == '@') {
/*
* Old behaviour. Check netgroup list
* followed by UNIX list.
*/
if(user_in_netgroup(user, *list +1))
return True;
if(user_in_group(user, *list +1))
return True;
} else if (**list == '+') {
if((*(*list +1)) == '&') {
/*
* Search UNIX list followed by netgroup.
*/
if(user_in_group(user, *list +2))
return True;
if(user_in_netgroup(user, *list +2))
return True;
} else {
/*
* Just search UNIX list.
*/
if(user_in_group(user, *list +1))
return True;
}
} else if (**list == '&') {
if(*(*list +1) == '+') {
/*
* Search netgroup list followed by UNIX list.
*/
if(user_in_netgroup(user, *list +2))
return True;
if(user_in_group(user, *list +2))
return True;
} else {
/*
* Just search netgroup list.
*/
if(user_in_netgroup(user, *list +1))
return True;
}
} else if (!name_is_local(*list)) {
/*
* If user name did not match and token is not a unix
* group and the token has a winbind separator in the
* name then see if it is a Windows group.
*/
DOM_SID g_sid;
enum SID_NAME_USE name_type;
BOOL winbind_answered = False;
BOOL ret;
fstring groupname, domain;
/* Parse a string of the form DOMAIN/user into a
* domain and a user */
char *p = strchr(*list,*lp_winbind_separator());
DEBUG(10,("user_in_list: checking if user |%s| is in "
"winbind group |%s|\n", user, *list));
if (p) {
fstrcpy(groupname, p+1);
fstrcpy(domain, *list);
domain[PTR_DIFF(p, *list)] = 0;
/* Check to see if name is a Windows group;
Win2k native mode DCs will return domain
local groups; while NT4 or mixed mode 2k
DCs will not */
if ( winbind_lookup_name(domain, groupname,
&g_sid, &name_type)
&& ( name_type==SID_NAME_DOM_GRP ||
(strequal(lp_workgroup(), domain) &&
name_type==SID_NAME_ALIAS) ) )
{
/* Check if user name is in the
* Windows group */
ret = user_in_winbind_group(
user, *list,
&winbind_answered);
if (winbind_answered && ret == True) {
DEBUG(10,("user_in_list: user "
"|%s| is in winbind "
"group |%s|\n",
user, *list));
return ret;
}
}
}
}
list++;
}
return(False);
}
/* The functions below have been taken from password.c and slightly modified */
/****************************************************************************
Apply a function to upper/lower case combinations

View File

@ -1,337 +0,0 @@
/*
Unix SMB/CIFS implementation.
Samba utility functions
Copyright (C) Simo Sorce 2001
Copyright (C) Jeremy Allison 2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
/****************************************************************
Returns a single linked list of group entries.
Use grent_free() to free it after use.
****************************************************************/
struct sys_grent * getgrent_list(void)
{
struct sys_grent *glist;
struct sys_grent *gent;
struct group *grp;
gent = SMB_MALLOC_P(struct sys_grent);
if (gent == NULL) {
DEBUG (0, ("Out of memory in getgrent_list!\n"));
return NULL;
}
memset(gent, '\0', sizeof(struct sys_grent));
glist = gent;
setgrent();
grp = getgrent();
if (grp == NULL) {
endgrent();
SAFE_FREE(glist);
return NULL;
}
while (grp != NULL) {
int i,num;
if (grp->gr_name) {
if ((gent->gr_name = SMB_STRDUP(grp->gr_name)) == NULL)
goto err;
}
if (grp->gr_passwd) {
if ((gent->gr_passwd = SMB_STRDUP(grp->gr_passwd)) == NULL)
goto err;
}
gent->gr_gid = grp->gr_gid;
/* number of strings in gr_mem */
for (num = 0; grp->gr_mem[num]; num++)
;
/* alloc space for gr_mem string pointers */
if ((gent->gr_mem = SMB_MALLOC_ARRAY(char *, num+1)) == NULL)
goto err;
memset(gent->gr_mem, '\0', (num+1) * sizeof(char *));
for (i=0; i < num; i++) {
if ((gent->gr_mem[i] = SMB_STRDUP(grp->gr_mem[i])) == NULL)
goto err;
}
gent->gr_mem[num] = NULL;
grp = getgrent();
if (grp) {
gent->next = SMB_MALLOC_P(struct sys_grent);
if (gent->next == NULL)
goto err;
gent = gent->next;
memset(gent, '\0', sizeof(struct sys_grent));
}
}
endgrent();
return glist;
err:
endgrent();
DEBUG(0, ("Out of memory in getgrent_list!\n"));
grent_free(glist);
return NULL;
}
/****************************************************************
Free the single linked list of group entries made by
getgrent_list()
****************************************************************/
void grent_free (struct sys_grent *glist)
{
while (glist) {
struct sys_grent *prev;
SAFE_FREE(glist->gr_name);
SAFE_FREE(glist->gr_passwd);
if (glist->gr_mem) {
int i;
for (i = 0; glist->gr_mem[i]; i++)
SAFE_FREE(glist->gr_mem[i]);
SAFE_FREE(glist->gr_mem);
}
prev = glist;
glist = glist->next;
SAFE_FREE(prev);
}
}
/****************************************************************
Returns a single linked list of passwd entries.
Use pwent_free() to free it after use.
****************************************************************/
struct sys_pwent * getpwent_list(void)
{
struct sys_pwent *plist;
struct sys_pwent *pent;
struct passwd *pwd;
pent = SMB_MALLOC_P(struct sys_pwent);
if (pent == NULL) {
DEBUG (0, ("Out of memory in getpwent_list!\n"));
return NULL;
}
plist = pent;
setpwent();
pwd = getpwent();
while (pwd != NULL) {
memset(pent, '\0', sizeof(struct sys_pwent));
if (pwd->pw_name) {
if ((pent->pw_name = SMB_STRDUP(pwd->pw_name)) == NULL)
goto err;
}
if (pwd->pw_passwd) {
if ((pent->pw_passwd = SMB_STRDUP(pwd->pw_passwd)) == NULL)
goto err;
}
pent->pw_uid = pwd->pw_uid;
pent->pw_gid = pwd->pw_gid;
if (pwd->pw_gecos) {
if ((pent->pw_gecos = SMB_STRDUP(pwd->pw_gecos)) == NULL)
goto err;
}
if (pwd->pw_dir) {
if ((pent->pw_dir = SMB_STRDUP(pwd->pw_dir)) == NULL)
goto err;
}
if (pwd->pw_shell) {
if ((pent->pw_shell = SMB_STRDUP(pwd->pw_shell)) == NULL)
goto err;
}
pwd = getpwent();
if (pwd) {
pent->next = SMB_MALLOC_P(struct sys_pwent);
if (pent->next == NULL)
goto err;
pent = pent->next;
}
}
endpwent();
return plist;
err:
endpwent();
DEBUG(0, ("Out of memory in getpwent_list!\n"));
pwent_free(plist);
return NULL;
}
/****************************************************************
Free the single linked list of passwd entries made by
getpwent_list()
****************************************************************/
void pwent_free (struct sys_pwent *plist)
{
while (plist) {
struct sys_pwent *prev;
SAFE_FREE(plist->pw_name);
SAFE_FREE(plist->pw_passwd);
SAFE_FREE(plist->pw_gecos);
SAFE_FREE(plist->pw_dir);
SAFE_FREE(plist->pw_shell);
prev = plist;
plist = plist->next;
SAFE_FREE(prev);
}
}
/****************************************************************
Add the individual group users onto the list.
****************************************************************/
static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_head, const struct group *grp)
{
size_t num_users, i;
/* Count the number of users. */
for (num_users = 0; grp->gr_mem[num_users]; num_users++)
;
for (i = 0; i < num_users; i++) {
struct sys_userlist *entry = SMB_MALLOC_P(struct sys_userlist);
if (entry == NULL) {
free_userlist(list_head);
return NULL;
}
entry->unix_name = (char *)SMB_STRDUP(grp->gr_mem[i]);
if (entry->unix_name == NULL) {
SAFE_FREE(entry);
free_userlist(list_head);
return NULL;
}
DLIST_ADD(list_head, entry);
}
return list_head;
}
/*****************************************************************
Splits passed user or group name to domain and user/group name parts
Returns True if name was splitted and False otherwise.
*****************************************************************/
static BOOL split_domain_and_name(const char *name, char *domain,
char* username)
{
char *p = strchr(name,*lp_winbind_separator());
/* Parse a string of the form DOMAIN/user into a domain and a user */
DEBUG(10,("split_domain_and_name: checking whether name |%s| local or "
"not\n", name));
if (p) {
fstrcpy(username, p+1);
fstrcpy(domain, name);
domain[PTR_DIFF(p, name)] = 0;
} else if (lp_winbind_use_default_domain()) {
fstrcpy(username, name);
fstrcpy(domain, lp_workgroup());
} else {
return False;
}
DEBUG(10,("split_domain_and_name: all is fine, domain is |%s| and "
"name is |%s|\n", domain, username));
return True;
}
/****************************************************************
Get the list of UNIX users in a group.
We have to enumerate the /etc/group file as some UNIX getgrnam()
calls won't do that for us (notably Tru64 UNIX).
****************************************************************/
struct sys_userlist *get_users_in_group(const char *gname)
{
struct sys_userlist *list_head = NULL;
struct group *gptr;
fstring domain;
fstring groupname;
DOM_SID sid;
enum SID_NAME_USE name_type;
/* No point using winbind if we can't split it in the
first place */
if (split_domain_and_name(gname, domain, groupname)) {
/*
* If we're doing this via winbindd, don't do the
* entire group list enumeration as we know this is
* pointless (and slow).
*/
if (winbind_lookup_name(domain, groupname, &sid, &name_type)
&& name_type == SID_NAME_DOM_GRP) {
if ((gptr = (struct group *)getgrnam(gname)) == NULL)
return NULL;
return add_members_to_userlist(list_head, gptr);
}
}
#if !defined(BROKEN_GETGRNAM)
if ((gptr = (struct group *)getgrnam(gname)) == NULL)
return NULL;
return add_members_to_userlist(list_head, gptr);
#else
/* BROKEN_GETGRNAM - True64 */
setgrent();
while((gptr = getgrent()) != NULL) {
if (strequal(gname, gptr->gr_name)) {
list_head = add_members_to_userlist(list_head, gptr);
if (list_head == NULL)
return NULL;
}
}
endgrent();
return list_head;
#endif
}
/****************************************************************
Free list allocated above.
****************************************************************/
void free_userlist(struct sys_userlist *list_head)
{
while (list_head) {
struct sys_userlist *old_head = list_head;
DLIST_REMOVE(list_head, list_head);
SAFE_FREE(old_head->unix_name);
SAFE_FREE(old_head);
}
}

View File

@ -6,6 +6,7 @@
Copyright (C) Gerald (Jerry) Carter 2000-2001
Copyright (C) Andrew Bartlett 2001-2002
Copyright (C) Simo Sorce 2003
Copyright (C) Volker Lendecke 2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -844,111 +845,70 @@ BOOL algorithmic_pdb_rid_is_user(uint32 rid)
Convert a name into a SID. Used in the lookup name rpc.
********************************************************************/
BOOL lookup_global_sam_name(const char *c_user, int flags, uint32_t *rid,
BOOL lookup_global_sam_name(const char *user, int flags, uint32_t *rid,
enum SID_NAME_USE *type)
{
fstring user;
SAM_ACCOUNT *sam_account = NULL;
struct group *grp;
GROUP_MAP map;
/*
* user may be quoted a const string, and map_username and
* friends can modify it. Make a modifiable copy. JRA.
*/
fstrcpy(user, c_user);
(void)map_username(user);
if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
return False;
}
/* BEGIN ROOT BLOCK */
become_root();
BOOL ret;
/* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
* correctly in the case where foo also exists as a user. If the flag
* is set, don't look for users at all. */
if (((flags & LOOKUP_NAME_GROUP) == 0) &&
pdb_getsampwnam(sam_account, user)) {
const DOM_SID *user_sid;
if ((flags & LOOKUP_NAME_GROUP) == 0) {
SAM_ACCOUNT *sam_account = NULL;
DOM_SID user_sid;
unbecome_root();
user_sid = pdb_get_user_sid(sam_account);
if (!sid_check_is_in_our_domain(user_sid)) {
DEBUG(0, ("User %s with invalid SID %s in passdb\n",
user, sid_string_static(user_sid)));
if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
return False;
}
become_root();
ret = pdb_getsampwnam(sam_account, user);
unbecome_root();
sid_peek_rid(user_sid, rid);
*type = SID_NAME_USER;
if (ret) {
sid_copy(&user_sid, pdb_get_user_sid(sam_account));
}
pdb_free_sam(&sam_account);
return True;
}
pdb_free_sam(&sam_account);
if (ret) {
if (!sid_check_is_in_our_domain(&user_sid)) {
DEBUG(0, ("User %s with invalid SID %s in passdb\n",
user, sid_string_static(&user_sid)));
return False;
}
sid_peek_rid(&user_sid, rid);
*type = SID_NAME_USER;
return True;
}
}
/*
* Maybe it was a group ?
* Maybe it is a group ?
*/
/* check if it's a mapped group */
if (pdb_getgrnam(&map, user)) {
unbecome_root();
/* BUILTIN groups are looked up elsewhere */
if (!sid_check_is_in_our_domain(&map.sid)) {
DEBUG(10, ("Found group %s (%s) not in our domain -- "
"ignoring.", user,
sid_string_static(&map.sid)));
return False;
}
/* yes it's a mapped group */
sid_peek_rid(&map.sid, rid);
*type = map.sid_name_use;
return True;
}
return False;
/* it's not a mapped group */
grp = getgrnam(user);
if(!grp) {
unbecome_root(); /* ---> exit form block */
return False;
}
/*
*check if it's mapped, if it is reply it doesn't exist
*
* that's to prevent this case:
*
* unix group ug is mapped to nt group ng
* someone does a lookup on ug
* we must not reply as it doesn't "exist" anymore
* for NT. For NT only ng exists.
* JFM, 30/11/2001
*/
if (pdb_getgrgid(&map, grp->gr_gid)) {
unbecome_root(); /* ---> exit form block */
return False;
}
become_root();
ret = pdb_getgrnam(&map, user);
unbecome_root();
/* END ROOT BLOCK */
*rid = pdb_gid_to_group_rid(grp->gr_gid);
*type = SID_NAME_ALIAS;
if (!ret) {
return False;
}
/* BUILTIN groups are looked up elsewhere */
if (!sid_check_is_in_our_domain(&map.sid)) {
DEBUG(10, ("Found group %s (%s) not in our domain -- "
"ignoring.", user,
sid_string_static(&map.sid)));
return False;
}
/* yes it's a mapped group */
sid_peek_rid(&map.sid, rid);
*type = map.sid_name_use;
return True;
}
@ -1086,7 +1046,7 @@ NTSTATUS local_password_change(const char *user_name, int local_flags,
}
if (local_flags & LOCAL_ADD_USER) {
if (pdb_add_sam_account(sam_pass)) {
if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) {
slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
pdb_free_sam(&sam_pass);
return NT_STATUS_OK;
@ -1096,7 +1056,7 @@ NTSTATUS local_password_change(const char *user_name, int local_flags,
return NT_STATUS_UNSUCCESSFUL;
}
} else if (local_flags & LOCAL_DELETE_USER) {
if (!pdb_delete_sam_account(sam_pass)) {
if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) {
slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
pdb_free_sam(&sam_pass);
return NT_STATUS_UNSUCCESSFUL;

View File

@ -4,6 +4,7 @@
Copyright (C) Andrew Bartlett 2002
Copyright (C) Jelmer Vernooij 2002
Copyright (C) Simo Sorce 2003
Copyright (C) Volker Lendecke 2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -331,15 +332,141 @@ BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
return NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
}
BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct)
static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
TALLOC_CTX *tmp_ctx, const char *name,
uint32 acb_info, uint32 *rid)
{
SAM_ACCOUNT *sam_pass = NULL;
NTSTATUS status;
if (Get_Pwnam_alloc(tmp_ctx, name) == NULL) {
pstring add_script;
int add_ret;
if ((acb_info & ACB_NORMAL) && name[strlen(name)-1] != '$') {
pstrcpy(add_script, lp_adduser_script());
} else {
pstrcpy(add_script, lp_addmachine_script());
}
if (add_script[0] == '\0') {
DEBUG(3, ("Could not find user %s and no add script "
"defined\n", name));
return NT_STATUS_NO_SUCH_USER;
}
all_string_sub(add_script, "%u", name, sizeof(add_script));
add_ret = smbrun(add_script,NULL);
DEBUG(add_ret ? 0 : 3, ("_samr_create_user: Running the "
"command `%s' gave %d\n",
add_script, add_ret));
}
/* implicit call to getpwnam() next. we have a valid SID coming out
* of this call */
flush_pwnam_cache();
status = pdb_init_sam_new(&sam_pass, name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("pdb_init_sam_new failed: %s\n", nt_errstr(status)));
return status;
}
if (!sid_peek_check_rid(get_global_sam_sid(),
pdb_get_user_sid(sam_pass), rid)) {
DEBUG(0, ("Could not get RID of fresh user\n"));
return NT_STATUS_INTERNAL_ERROR;
}
/* Disable the account on creation, it does not have a reasonable
* password yet. */
acb_info |= ACB_DISABLED;
pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
status = pdb_add_sam_account(sam_pass);
pdb_free_sam(&sam_pass);
return status;
}
NTSTATUS pdb_create_user(TALLOC_CTX *mem_ctx, const char *name, uint32 flags,
uint32 *rid)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return False;
return NT_STATUS_UNSUCCESSFUL;
}
return pdb->create_user(pdb, mem_ctx, name, flags, rid);
}
/****************************************************************************
Delete a UNIX user on demand.
****************************************************************************/
static int smb_delete_user(const char *unix_user)
{
pstring del_script;
int ret;
pstrcpy(del_script, lp_deluser_script());
if (! *del_script)
return -1;
all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
ret = smbrun(del_script,NULL);
flush_pwnam_cache();
DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
return ret;
}
static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
SAM_ACCOUNT *sam_acct)
{
NTSTATUS status;
status = pdb_delete_sam_account(sam_acct);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/*
* Now delete the unix side ....
* note: we don't check if the delete really happened as the script is
* not necessary present and maybe the sysadmin doesn't want to delete
* the unix side
*/
smb_delete_user( pdb_get_username(sam_acct) );
return status;
}
NTSTATUS pdb_delete_user(TALLOC_CTX *mem_ctx, SAM_ACCOUNT *sam_acct)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
return pdb->delete_user(pdb, mem_ctx, sam_acct);
}
NTSTATUS pdb_add_sam_account(SAM_ACCOUNT *sam_acct)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
return NT_STATUS_IS_OK(pdb->add_sam_account(pdb, sam_acct));
return pdb->add_sam_account(pdb, sam_acct);
}
NTSTATUS pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
@ -358,12 +485,12 @@ NTSTATUS pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
return pdb->update_sam_account(pdb, sam_acct);
}
BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
NTSTATUS pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return False;
return NT_STATUS_UNSUCCESSFUL;
}
if (csamuser != NULL) {
@ -371,7 +498,7 @@ BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
csamuser = NULL;
}
return NT_STATUS_IS_OK(pdb->delete_sam_account(pdb, sam_acct));
return pdb->delete_sam_account(pdb, sam_acct);
}
NTSTATUS pdb_rename_sam_account(SAM_ACCOUNT *oldname, const char *newname)
@ -434,6 +561,115 @@ BOOL pdb_getgrnam(GROUP_MAP *map, const char *name)
return NT_STATUS_IS_OK(pdb->getgrnam(pdb, map, name));
}
static NTSTATUS pdb_default_create_dom_group(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
const char *name,
uint32 *rid)
{
DOM_SID group_sid;
struct group *grp;
grp = getgrnam(name);
if (grp == NULL) {
gid_t gid;
if (smb_create_group(name, &gid) != 0) {
return NT_STATUS_ACCESS_DENIED;
}
grp = getgrgid(gid);
}
if (grp == NULL) {
return NT_STATUS_ACCESS_DENIED;
}
if (pdb_rid_algorithm()) {
*rid = pdb_gid_to_group_rid( grp->gr_gid );
} else {
if (!pdb_new_rid(rid)) {
return NT_STATUS_ACCESS_DENIED;
}
}
sid_compose(&group_sid, get_global_sam_sid(), *rid);
return add_initial_entry(grp->gr_gid, sid_string_static(&group_sid),
SID_NAME_DOM_GRP, name, NULL);
}
NTSTATUS pdb_create_dom_group(TALLOC_CTX *mem_ctx, const char *name,
uint32 *rid)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
return pdb->create_dom_group(pdb, mem_ctx, name, rid);
}
static NTSTATUS pdb_default_delete_dom_group(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
uint32 rid)
{
DOM_SID group_sid;
GROUP_MAP map;
NTSTATUS status;
struct group *grp;
const char *grp_name;
sid_compose(&group_sid, get_global_sam_sid(), rid);
if (!get_domain_group_from_sid(group_sid, &map)) {
DEBUG(10, ("Could not find group for rid %d\n", rid));
return NT_STATUS_NO_SUCH_GROUP;
}
/* We need the group name for the smb_delete_group later on */
if (map.gid == (gid_t)-1) {
return NT_STATUS_NO_SUCH_GROUP;
}
grp = getgrgid(map.gid);
if (grp == NULL) {
return NT_STATUS_NO_SUCH_GROUP;
}
/* Copy the name, no idea what pdb_delete_group_mapping_entry does.. */
grp_name = talloc_strdup(mem_ctx, grp->gr_name);
if (grp_name == NULL) {
return NT_STATUS_NO_MEMORY;
}
status = pdb_delete_group_mapping_entry(group_sid);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* Don't check the result of smb_delete_group */
smb_delete_group(grp_name);
return NT_STATUS_OK;
}
NTSTATUS pdb_delete_dom_group(TALLOC_CTX *mem_ctx, uint32 rid)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
return pdb->delete_dom_group(pdb, mem_ctx, rid);
}
NTSTATUS pdb_add_group_mapping_entry(GROUP_MAP *map)
{
struct pdb_methods *pdb = pdb_get_methods(False);
@ -456,15 +692,15 @@ NTSTATUS pdb_update_group_mapping_entry(GROUP_MAP *map)
return pdb->update_group_mapping_entry(pdb, map);
}
BOOL pdb_delete_group_mapping_entry(DOM_SID sid)
NTSTATUS pdb_delete_group_mapping_entry(DOM_SID sid)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return False;
return NT_STATUS_UNSUCCESSFUL;
}
return NT_STATUS_IS_OK(pdb->delete_group_mapping_entry(pdb, sid));
return pdb->delete_group_mapping_entry(pdb, sid);
}
BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **pp_rmap,
@ -510,6 +746,200 @@ NTSTATUS pdb_enum_group_memberships(TALLOC_CTX *mem_ctx, SAM_ACCOUNT *user,
pp_sids, pp_gids, p_num_groups);
}
static NTSTATUS pdb_default_set_unix_primary_group(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
SAM_ACCOUNT *sampass)
{
struct group *grp;
gid_t gid;
if (!sid_to_gid(pdb_get_group_sid(sampass), &gid) ||
(grp = getgrgid(gid)) == NULL) {
return NT_STATUS_INVALID_PRIMARY_GROUP;
}
if (smb_set_primary_group(grp->gr_name,
pdb_get_username(sampass)) != 0) {
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
}
NTSTATUS pdb_set_unix_primary_group(TALLOC_CTX *mem_ctx, SAM_ACCOUNT *user)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
return pdb->set_unix_primary_group(pdb, mem_ctx, user);
}
/*
* Helper function to see whether a user is in a group. We can't use
* user_in_group_sid here because this creates dependencies only smbd can
* fulfil.
*/
static BOOL pdb_user_in_group(TALLOC_CTX *mem_ctx, SAM_ACCOUNT *account,
const DOM_SID *group_sid)
{
DOM_SID *sids;
gid_t *gids;
size_t i, num_groups;
if (!NT_STATUS_IS_OK(pdb_enum_group_memberships(mem_ctx, account,
&sids, &gids,
&num_groups))) {
return False;
}
for (i=0; i<num_groups; i++) {
if (sid_equal(group_sid, &sids[i])) {
return True;
}
}
return False;
}
static NTSTATUS pdb_default_add_groupmem(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
uint32 group_rid,
uint32 member_rid)
{
DOM_SID group_sid, member_sid;
SAM_ACCOUNT *account = NULL;
GROUP_MAP map;
struct group *grp;
struct passwd *pwd;
const char *group_name;
uid_t uid;
NTSTATUS status;
sid_compose(&group_sid, get_global_sam_sid(), group_rid);
sid_compose(&member_sid, get_global_sam_sid(), member_rid);
if (!get_domain_group_from_sid(group_sid, &map) ||
(map.gid == (gid_t)-1) ||
((grp = getgrgid(map.gid)) == NULL)) {
return NT_STATUS_NO_SUCH_GROUP;
}
group_name = talloc_strdup(mem_ctx, grp->gr_name);
if (group_name == NULL) {
return NT_STATUS_NO_MEMORY;
}
if (!NT_STATUS_IS_OK(status = pdb_init_sam(&account))) {
return status;
}
if (!pdb_getsampwsid(account, &member_sid) ||
!sid_to_uid(&member_sid, &uid) ||
((pwd = getpwuid_alloc(mem_ctx, uid)) == NULL)) {
return NT_STATUS_NO_SUCH_USER;
}
if (pdb_user_in_group(mem_ctx, account, &group_sid)) {
return NT_STATUS_MEMBER_IN_GROUP;
}
/*
* ok, the group exist, the user exist, the user is not in the group,
* we can (finally) add it to the group !
*/
smb_add_user_group(group_name, pwd->pw_name);
if (!pdb_user_in_group(mem_ctx, account, &group_sid)) {
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
}
NTSTATUS pdb_add_groupmem(TALLOC_CTX *mem_ctx, uint32 group_rid,
uint32 member_rid)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
return pdb->add_groupmem(pdb, mem_ctx, group_rid, member_rid);
}
static NTSTATUS pdb_default_del_groupmem(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
uint32 group_rid,
uint32 member_rid)
{
DOM_SID group_sid, member_sid;
SAM_ACCOUNT *account = NULL;
GROUP_MAP map;
struct group *grp;
struct passwd *pwd;
const char *group_name;
uid_t uid;
NTSTATUS status;
sid_compose(&group_sid, get_global_sam_sid(), group_rid);
sid_compose(&member_sid, get_global_sam_sid(), member_rid);
if (!get_domain_group_from_sid(group_sid, &map) ||
(map.gid == (gid_t)-1) ||
((grp = getgrgid(map.gid)) == NULL)) {
return NT_STATUS_NO_SUCH_GROUP;
}
group_name = talloc_strdup(mem_ctx, grp->gr_name);
if (group_name == NULL) {
return NT_STATUS_NO_MEMORY;
}
if (!NT_STATUS_IS_OK(status = pdb_init_sam(&account))) {
return status;
}
if (!pdb_getsampwsid(account, &member_sid) ||
!sid_to_uid(&member_sid, &uid) ||
((pwd = getpwuid_alloc(mem_ctx, uid)) == NULL)) {
return NT_STATUS_NO_SUCH_USER;
}
if (!pdb_user_in_group(mem_ctx, account, &group_sid)) {
return NT_STATUS_MEMBER_NOT_IN_GROUP;
}
/*
* ok, the group exist, the user exist, the user is in the group,
* we can (finally) delete it from the group!
*/
smb_delete_user_group(group_name, pwd->pw_name);
if (pdb_user_in_group(mem_ctx, account, &group_sid)) {
return NT_STATUS_ACCESS_DENIED;
}
return NT_STATUS_OK;
}
NTSTATUS pdb_del_groupmem(TALLOC_CTX *mem_ctx, uint32 group_rid,
uint32 member_rid)
{
struct pdb_methods *pdb = pdb_get_methods(False);
if ( !pdb ) {
return NT_STATUS_UNSUCCESSFUL;
}
return pdb->del_groupmem(pdb, mem_ctx, group_rid, member_rid);
}
BOOL pdb_find_alias(const char *name, DOM_SID *sid)
{
struct pdb_methods *pdb = pdb_get_methods(False);
@ -977,7 +1407,7 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size
{
struct group *grp;
char **gr;
struct sys_pwent *userlist, *user;
struct passwd *pwd;
*pp_uids = NULL;
*p_num = 0;
@ -993,15 +1423,14 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size
/* Primary group members */
userlist = getpwent_list();
for (user = userlist; user != NULL; user = user->next) {
if (user->pw_gid != gid)
continue;
add_uid_to_array_unique(mem_ctx, user->pw_uid, pp_uids, p_num);
setpwent();
while ((pwd = getpwent()) != NULL) {
if (pwd->pw_gid == gid) {
add_uid_to_array_unique(mem_ctx, pwd->pw_uid,
pp_uids, p_num);
}
}
pwent_free(userlist);
endpwent();
/* Secondary group members */
@ -1048,7 +1477,7 @@ NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
uid_to_sid(&sid, uids[i]);
if (!sid_check_is_in_our_domain(&sid)) {
DEBUG(1, ("Inconsistent SAM -- group member uid not "
DEBUG(5, ("Inconsistent SAM -- group member uid not "
"in our domain\n"));
continue;
}
@ -1060,6 +1489,44 @@ NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
return NT_STATUS_OK;
}
NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
TALLOC_CTX *mem_ctx,
SAM_ACCOUNT *user,
DOM_SID **pp_sids,
gid_t **pp_gids,
size_t *p_num_groups)
{
size_t i;
gid_t gid;
if (!sid_to_gid(pdb_get_group_sid(user), &gid)) {
DEBUG(10, ("sid_to_gid failed\n"));
return NT_STATUS_NO_SUCH_USER;
}
if (!getgroups_unix_user(mem_ctx, pdb_get_username(user), gid,
pp_gids, p_num_groups)) {
return NT_STATUS_NO_SUCH_USER;
}
if (*p_num_groups == 0) {
smb_panic("primary group missing");
}
*pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups);
if (*pp_sids == NULL) {
talloc_free(*pp_gids);
return NT_STATUS_NO_MEMORY;
}
for (i=0; i<*p_num_groups; i++) {
gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]);
}
return NT_STATUS_OK;
}
/*******************************************************************
Look up a rid in the SAM we're responsible for (i.e. passdb)
********************************************************************/
@ -1603,6 +2070,8 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods )
(*methods)->getsampwent = pdb_default_getsampwent;
(*methods)->getsampwnam = pdb_default_getsampwnam;
(*methods)->getsampwsid = pdb_default_getsampwsid;
(*methods)->create_user = pdb_default_create_user;
(*methods)->delete_user = pdb_default_delete_user;
(*methods)->add_sam_account = pdb_default_add_sam_account;
(*methods)->update_sam_account = pdb_default_update_sam_account;
(*methods)->delete_sam_account = pdb_default_delete_sam_account;
@ -1612,12 +2081,17 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods )
(*methods)->getgrsid = pdb_default_getgrsid;
(*methods)->getgrgid = pdb_default_getgrgid;
(*methods)->getgrnam = pdb_default_getgrnam;
(*methods)->create_dom_group = pdb_default_create_dom_group;
(*methods)->delete_dom_group = pdb_default_delete_dom_group;
(*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
(*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
(*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
(*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
(*methods)->enum_group_members = pdb_default_enum_group_members;
(*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
(*methods)->set_unix_primary_group = pdb_default_set_unix_primary_group;
(*methods)->add_groupmem = pdb_default_add_groupmem;
(*methods)->del_groupmem = pdb_default_del_groupmem;
(*methods)->find_alias = pdb_default_find_alias;
(*methods)->create_alias = pdb_default_create_alias;
(*methods)->delete_alias = pdb_default_delete_alias;

View File

@ -2410,18 +2410,13 @@ static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
SAMR_R_CREATE_USER *r_u)
{
SAM_ACCOUNT *sam_pass=NULL;
fstring account;
char *account;
DOM_SID sid;
pstring add_script;
POLICY_HND dom_pol = q_u->domain_pol;
UNISTR2 user_account = q_u->uni_name;
uint16 acb_info = q_u->acb_info;
POLICY_HND *user_pol = &r_u->user_pol;
struct samr_info *info = NULL;
BOOL ret;
NTSTATUS nt_status;
struct passwd *pw;
uint32 acc_granted;
SEC_DESC *psd;
size_t sd_size;
@ -2450,33 +2445,20 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
return NT_STATUS_INVALID_PARAMETER;
}
rpcstr_pull(account, user_account.buffer, sizeof(account),
user_account.uni_str_len*2, 0);
strlower_m(account);
account = rpcstr_pull_unistr2_talloc(p->mem_ctx, &q_u->uni_name);
if (account == NULL) {
return NT_STATUS_NO_MEMORY;
}
nt_status = can_create(p->mem_ctx, account);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
/*********************************************************************
* HEADS UP! If we have to create a new user account, we have to get
* a new RID from somewhere. This used to be done by the passdb
* backend. It has been moved into idmap now. Since idmap is now
* wrapped up behind winbind, this means you have to run winbindd if
* you want new accounts to get a new RID when "enable rid algorithm =
* no". Tough. We now have a uniform way of allocating RIDs
* regardless of what ever passdb backend people may use. --jerry
* (2003-07-10)
*********************************************************************/
pw = Get_Pwnam(account);
/* determine which user right we need to check based on the acb_info */
if ( acb_info & ACB_WSTRUST )
{
pstrcpy(add_script, lp_addmachine_script());
se_priv_copy( &se_rights, &se_machine_account );
can_add_account = user_has_privileges(
p->pipe_user.nt_user_token, &se_rights );
@ -2486,7 +2468,6 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
else if ( acb_info & ACB_NORMAL &&
(account[strlen(account)-1] != '$') )
{
pstrcpy(add_script, lp_adduser_script());
se_priv_copy( &se_rights, &se_add_users );
can_add_account = user_has_privileges(
p->pipe_user.nt_user_token, &se_rights );
@ -2494,7 +2475,6 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
else /* implicit assumption of a BDC or domain trust account here
* (we already check the flags earlier) */
{
pstrcpy(add_script, lp_addmachine_script());
if ( lp_enable_privileges() ) {
/* only Domain Admins can add a BDC or domain trust */
se_priv_copy( &se_rights, &se_priv_none );
@ -2512,40 +2492,9 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
if ( can_add_account )
become_root();
if ( !pw ) {
if (*add_script) {
int add_ret;
nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
&r_u->user_rid);
all_string_sub(add_script, "%u", account,
sizeof(add_script));
add_ret = smbrun(add_script,NULL);
DEBUG(add_ret ? 0 : 3,("_samr_create_user: Running "
"the command `%s' gave %d\n",
add_script, add_ret));
}
}
/* implicit call to getpwnam() next. we have a valid SID coming out
* of this call */
flush_pwnam_cache();
nt_status = pdb_init_sam_new(&sam_pass, account);
/* this code is order such that we have no unnecessary retuns
out of the admin block of code */
if ( NT_STATUS_IS_OK(nt_status) ) {
pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
pdb_free_sam(&sam_pass);
DEBUG(0, ("could not add user/computer %s to passdb. "
"Check permissions?\n",
account));
nt_status = NT_STATUS_ACCESS_DENIED;
}
}
if ( can_add_account )
unbecome_root();
@ -2557,8 +2506,8 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
return nt_status;
/* Get the user's SID */
sid_copy(&sid, pdb_get_user_sid(sam_pass));
sid_compose(&sid, get_global_sam_sid(), r_u->user_rid);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
&sid, SAMR_USR_RIGHTS_WRITE_PW);
@ -2574,7 +2523,6 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
/* associate the user's SID with the new handle. */
if ((info = get_samr_info_by_sid(&sid)) == NULL) {
pdb_free_sam(&sam_pass);
return NT_STATUS_NO_MEMORY;
}
@ -2584,19 +2532,14 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
pdb_free_sam(&sam_pass);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
/* After a "set" ensure we have no cached display info. */
force_flush_samr_cache(info->disp_info);
r_u->user_rid=pdb_get_user_rid(sam_pass);
r_u->access_granted = acc_granted;
pdb_free_sam(&sam_pass);
return NT_STATUS_OK;
}
@ -3097,41 +3040,6 @@ static BOOL set_user_info_18(SAM_USER_INFO_18 *id18, SAM_ACCOUNT *pwd)
return True;
}
/*******************************************************************
The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
********************************************************************/
static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
{
struct group *grp;
gid_t gid;
if (!sid_to_gid(pdb_get_group_sid(sampass), &gid)) {
DEBUG(2,("Could not get gid for primary group of "
"user %s\n", pdb_get_username(sampass)));
return False;
}
grp = getgrgid(gid);
if (grp == NULL) {
DEBUG(2,("Could not find primary group %lu for "
"user %s\n", (unsigned long)gid,
pdb_get_username(sampass)));
return False;
}
if (smb_set_primary_group(grp->gr_name,
pdb_get_username(sampass)) != 0) {
DEBUG(2,("Could not set primary group for user %s to "
"%s\n",
pdb_get_username(sampass), grp->gr_name));
return False;
}
return True;
}
/*******************************************************************
set_user_info_20
********************************************************************/
@ -3159,12 +3067,14 @@ static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
set_user_info_21
********************************************************************/
static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
SAM_ACCOUNT *pwd)
{
NTSTATUS status;
if (id21 == NULL) {
DEBUG(5, ("set_user_info_21: NULL id21\n"));
return False;
return NT_STATUS_INVALID_PARAMETER;
}
copy_id21_to_sam_passwd(pwd, id21);
@ -3176,33 +3086,38 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
* id21. I don't know if they need to be set. --jerry
*/
if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
set_unix_primary_group(pwd);
if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
pwd))) {
return status;
}
/* write the change out */
if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
pdb_free_sam(&pwd);
return False;
return status;
}
pdb_free_sam(&pwd);
return True;
return NT_STATUS_OK;
}
/*******************************************************************
set_user_info_23
********************************************************************/
static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, SAM_USER_INFO_23 *id23,
SAM_ACCOUNT *pwd)
{
pstring plaintext_buf;
uint32 len;
uint16 acct_ctrl;
NTSTATUS status;
if (id23 == NULL) {
DEBUG(5, ("set_user_info_23: NULL id23\n"));
return False;
return NT_STATUS_INVALID_PARAMETER;
}
DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
@ -3212,12 +3127,12 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
if (!decode_pw_buffer(id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
pdb_free_sam(&pwd);
return False;
return NT_STATUS_INVALID_PARAMETER;
}
if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
pdb_free_sam(&pwd);
return False;
return NT_STATUS_ACCESS_DENIED;
}
copy_id23_to_sam_passwd(pwd, id23);
@ -3237,24 +3152,28 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
pdb_free_sam(&pwd);
return False;
return NT_STATUS_ACCESS_DENIED;
}
}
}
ZERO_STRUCT(plaintext_buf);
if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
set_unix_primary_group(pwd);
if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
(!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
pwd)))) {
pdb_free_sam(&pwd);
return False;
return status;
}
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
pdb_free_sam(&pwd);
return status;
}
pdb_free_sam(&pwd);
return True;
return NT_STATUS_OK;
}
/*******************************************************************
@ -3444,8 +3363,8 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
dump_data(100, (char *)ctr->info.id23->pass, 516);
if (!set_user_info_23(ctr->info.id23, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
r_u->status = set_user_info_23(p->mem_ctx,
ctr->info.id23, pwd);
break;
default:
@ -3558,8 +3477,8 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
case 21:
if (!set_user_info_21(ctr->info.id21, pwd))
return NT_STATUS_ACCESS_DENIED;
r_u->status = set_user_info_21(p->mem_ctx,
ctr->info.id21, pwd);
break;
case 23:
if (!p->session_key.length) {
@ -3569,8 +3488,8 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
dump_data(100, (char *)ctr->info.id23->pass, 516);
if (!set_user_info_23(ctr->info.id23, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
r_u->status = set_user_info_23(p->mem_ctx,
ctr->info.id23, pwd);
break;
case 26:
if (!p->session_key.length) {
@ -3713,70 +3632,6 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_
return NT_STATUS_OK;
}
static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
{
int i;
for (i=0; i<*num; i++) {
if ((*uids)[i] == uid)
return;
}
*uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
if (*uids == NULL)
return;
(*uids)[*num] = uid;
*num += 1;
}
static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
{
struct group *grp;
char **gr;
struct sys_pwent *userlist, *user;
*uids = NULL;
*num = 0;
/* We only look at our own sam, so don't care about imported stuff */
winbind_off();
if ((grp = getgrgid(gid)) == NULL) {
winbind_on();
return False;
}
/* Primary group members */
userlist = getpwent_list();
for (user = userlist; user != NULL; user = user->next) {
if (user->pw_gid != gid)
continue;
add_uid_to_array_unique(user->pw_uid, uids, num);
}
pwent_free(userlist);
/* Secondary group members */
for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
struct passwd *pw = getpwnam(*gr);
if (pw == NULL)
continue;
add_uid_to_array_unique(pw->pw_uid, uids, num);
}
winbind_on();
return True;
}
/*********************************************************************
_samr_query_groupmem
*********************************************************************/
@ -3931,16 +3786,7 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
{
DOM_SID group_sid;
DOM_SID user_sid;
fstring group_sid_str;
uid_t uid;
struct passwd *pwd;
struct group *grp;
fstring grp_name;
GROUP_MAP map;
NTSTATUS ret;
SAM_ACCOUNT *sam_user=NULL;
BOOL check;
uint32 group_rid;
uint32 acc_granted;
SE_PRIV se_rights;
BOOL can_add_accounts;
@ -3954,53 +3800,11 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
return r_u->status;
}
sid_to_string(group_sid_str, &group_sid);
DEBUG(10, ("sid is %s\n", group_sid_str));
DEBUG(10, ("sid is %s\n", sid_string_static(&group_sid)));
if (sid_compare(&group_sid, get_global_sam_sid())<=0)
return NT_STATUS_NO_SUCH_GROUP;
DEBUG(10, ("lookup on Domain SID\n"));
if(!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
sid_copy(&user_sid, get_global_sam_sid());
sid_append_rid(&user_sid, q_u->rid);
ret = pdb_init_sam(&sam_user);
if (!NT_STATUS_IS_OK(ret))
return ret;
check = pdb_getsampwsid(sam_user, &user_sid);
if (check != True) {
pdb_free_sam(&sam_user);
return NT_STATUS_NO_SUCH_USER;
}
/* check a real user exist before we run the script to add a user to a group */
if (!sid_to_uid(pdb_get_user_sid(sam_user), &uid)) {
pdb_free_sam(&sam_user);
return NT_STATUS_NO_SUCH_USER;
}
pdb_free_sam(&sam_user);
if ((pwd=getpwuid_alloc(p->mem_ctx, uid)) == NULL) {
return NT_STATUS_NO_SUCH_USER;
}
if ((grp=getgrgid(map.gid)) == NULL) {
return NT_STATUS_NO_SUCH_GROUP;
}
/* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
fstrcpy(grp_name, grp->gr_name);
/* if the user is already in the group */
if(user_in_unix_group(pwd->pw_name, grp_name)) {
return NT_STATUS_MEMBER_IN_GROUP;
if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
&group_rid)) {
return NT_STATUS_INVALID_HANDLE;
}
se_priv_copy( &se_rights, &se_add_users );
@ -4010,28 +3814,17 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
if ( can_add_accounts )
become_root();
r_u->status = pdb_add_groupmem(p->mem_ctx, group_rid, q_u->rid);
/*
* ok, the group exist, the user exist, the user is not in the group,
*
* we can (finally) add it to the group !
*/
smb_add_user_group(grp_name, pwd->pw_name);
if ( can_add_accounts )
unbecome_root();
/******** END SeAddUsers BLOCK *********/
/* check if the user has been added then ... */
if(!user_in_unix_group(pwd->pw_name, grp_name)) {
return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
}
force_flush_samr_cache(disp_info);
return NT_STATUS_OK;
return r_u->status;
}
/*********************************************************************
@ -4041,11 +3834,7 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
{
DOM_SID group_sid;
DOM_SID user_sid;
SAM_ACCOUNT *sam_pass=NULL;
GROUP_MAP map;
fstring grp_name;
struct group *grp;
uint32 group_rid;
uint32 acc_granted;
SE_PRIV se_rights;
BOOL can_add_accounts;
@ -4064,37 +3853,12 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
return r_u->status;
}
if (!sid_check_is_in_our_domain(&group_sid))
return NT_STATUS_NO_SUCH_GROUP;
sid_copy(&user_sid, get_global_sam_sid());
sid_append_rid(&user_sid, q_u->rid);
if (!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
if ((grp=getgrgid(map.gid)) == NULL)
return NT_STATUS_NO_SUCH_GROUP;
/* we need to copy the name otherwise it's overloaded in user_in_group_list */
fstrcpy(grp_name, grp->gr_name);
/* check if the user exists before trying to remove it from the group */
pdb_init_sam(&sam_pass);
if (!pdb_getsampwsid(sam_pass, &user_sid)) {
DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
pdb_free_sam(&sam_pass);
return NT_STATUS_NO_SUCH_USER;
if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
&group_rid)) {
return NT_STATUS_INVALID_HANDLE;
}
/* if the user is not in the group */
if (!user_in_unix_group(pdb_get_username(sam_pass), grp_name)) {
pdb_free_sam(&sam_pass);
return NT_STATUS_MEMBER_NOT_IN_GROUP;
}
se_priv_copy( &se_rights, &se_add_users );
can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
@ -4103,45 +3867,16 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE
if ( can_add_accounts )
become_root();
smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
r_u->status = pdb_del_groupmem(p->mem_ctx, group_rid, q_u->rid);
if ( can_add_accounts )
unbecome_root();
/******** END SeAddUsers BLOCK *********/
/* check if the user has been removed then ... */
if (user_in_unix_group(pdb_get_username(sam_pass), grp_name)) {
pdb_free_sam(&sam_pass);
return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
}
pdb_free_sam(&sam_pass);
force_flush_samr_cache(disp_info);
return NT_STATUS_OK;
}
/****************************************************************************
Delete a UNIX user on demand.
****************************************************************************/
static int smb_delete_user(const char *unix_user)
{
pstring del_script;
int ret;
pstrcpy(del_script, lp_deluser_script());
if (! *del_script)
return -1;
all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
ret = smbrun(del_script,NULL);
flush_pwnam_cache();
DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
return ret;
return r_u->status;
}
/*********************************************************************
@ -4154,7 +3889,6 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
SAM_ACCOUNT *sam_pass=NULL;
uint32 acc_granted;
BOOL can_add_accounts;
BOOL ret;
DISP_INFO *disp_info = NULL;
DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
@ -4186,29 +3920,19 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
if ( can_add_accounts )
become_root();
/* First delete the samba side....
code is order to prevent unnecessary returns out of the admin
block of code */
if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
/*
* Now delete the unix side ....
* note: we don't check if the delete really happened
* as the script is not necessary present
* and maybe the sysadmin doesn't want to delete the unix side
*/
smb_delete_user( pdb_get_username(sam_pass) );
}
r_u->status = pdb_delete_user(p->mem_ctx, sam_pass);
if ( can_add_accounts )
unbecome_root();
/******** END SeAddUsers BLOCK *********/
if ( !ret ) {
DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
if ( !NT_STATUS_IS_OK(r_u->status) ) {
DEBUG(5,("_samr_delete_dom_user: Failed to delete entry for "
"user %s: %s.\n", pdb_get_username(sam_pass),
nt_errstr(r_u->status)));
pdb_free_sam(&sam_pass);
return NT_STATUS_CANNOT_DELETE;
return r_u->status;
}
@ -4229,16 +3953,10 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
{
DOM_SID group_sid;
DOM_SID dom_sid;
uint32 group_rid;
fstring group_sid_str;
gid_t gid;
struct group *grp;
GROUP_MAP map;
uint32 acc_granted;
SE_PRIV se_rights;
BOOL can_add_accounts;
BOOL ret;
DISP_INFO *disp_info = NULL;
DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
@ -4250,27 +3968,13 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
return r_u->status;
}
sid_copy(&dom_sid, &group_sid);
sid_to_string(group_sid_str, &dom_sid);
sid_split_rid(&dom_sid, &group_rid);
DEBUG(10, ("sid is %s\n", group_sid_str));
DEBUG(10, ("sid is %s\n", sid_string_static(&group_sid)));
/* we check if it's our SID before deleting */
if (!sid_equal(&dom_sid, get_global_sam_sid()))
return NT_STATUS_NO_SUCH_GROUP;
DEBUG(10, ("lookup on Domain SID\n"));
if(!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
gid=map.gid;
/* check if group really exists */
if ( (grp=getgrgid(gid)) == NULL)
if (!sid_peek_check_rid(get_global_sam_sid(), &group_sid,
&group_rid)) {
return NT_STATUS_NO_SUCH_GROUP;
}
se_priv_copy( &se_rights, &se_add_users );
can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
@ -4280,26 +3984,21 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
if ( can_add_accounts )
become_root();
/* delete mapping first */
if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
smb_delete_group( grp->gr_name );
}
r_u->status = pdb_delete_dom_group(p->mem_ctx, group_rid);
if ( can_add_accounts )
unbecome_root();
/******** END SeAddUsers BLOCK *********/
if ( !ret ) {
DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
group_sid_str));
return NT_STATUS_ACCESS_DENIED;
if ( !NT_STATUS_IS_OK(r_u->status) ) {
DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping "
"entry for group %s: %s\n",
sid_string_static(&group_sid),
nt_errstr(r_u->status)));
return r_u->status;
}
/* don't check that the unix group has been deleted. Work like
_samr_delet_dom_user() */
if (!close_policy_hnd(p, &q_u->group_pol))
return NT_STATUS_OBJECT_NAME_INVALID;
@ -4373,15 +4072,11 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
{
DOM_SID dom_sid;
DOM_SID info_sid;
fstring name;
fstring sid_string;
struct group *grp;
const char *name;
struct samr_info *info;
uint32 acc_granted;
gid_t gid;
SE_PRIV se_rights;
BOOL can_add_accounts;
NTSTATUS result;
DISP_INFO *disp_info = NULL;
/* Find the policy handle. Open a policy on it. */
@ -4395,7 +4090,10 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
if (!sid_equal(&dom_sid, get_global_sam_sid()))
return NT_STATUS_ACCESS_DENIED;
unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
name = rpcstr_pull_unistr2_talloc(p->mem_ctx, &q_u->uni_acct_desc);
if (name == NULL) {
return NT_STATUS_NO_MEMORY;
}
r_u->status = can_create(p->mem_ctx, name);
if (!NT_STATUS_IS_OK(r_u->status)) {
@ -4412,35 +4110,7 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
/* check that we successfully create the UNIX group */
result = NT_STATUS_ACCESS_DENIED;
if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
/* so far, so good */
result = NT_STATUS_OK;
if (pdb_rid_algorithm()) {
r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
} else {
if (!pdb_new_rid(&r_u->rid)) {
result = NT_STATUS_ACCESS_DENIED;
}
}
if (NT_STATUS_IS_OK(result)) {
/* add the group to the mapping table */
sid_copy( &info_sid, get_global_sam_sid() );
sid_append_rid( &info_sid, r_u->rid );
sid_to_string( sid_string, &info_sid );
/* reset the error code if we fail to add the mapping entry */
if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
result = NT_STATUS_ACCESS_DENIED;
}
}
r_u->status = pdb_create_dom_group(p->mem_ctx, name, &r_u->rid);
if ( can_add_accounts )
unbecome_root();
@ -4449,13 +4119,14 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
/* check if we should bail out here */
if ( !NT_STATUS_IS_OK(result) )
return result;
if ( !NT_STATUS_IS_OK(r_u->status) )
return r_u->status;
sid_compose(&info_sid, get_global_sam_sid(), r_u->rid);
if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
return NT_STATUS_NO_MEMORY;
/* they created it; let the user do what he wants with it */
info->acc_granted = GENERIC_RIGHTS_GROUP_ALL_ACCESS;
@ -4568,9 +4239,6 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM
{
DOM_SID group_sid;
GROUP_MAP map;
DOM_SID *sids=NULL;
uid_t *uids;
int num=0;
GROUP_INFO_CTR *ctr;
uint32 acc_granted;
BOOL ret;
@ -4593,14 +4261,25 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM
return NT_STATUS_NO_MEMORY;
switch (q_u->switch_level) {
case 1:
case 1: {
uint32 *members;
size_t num_members;
ctr->switch_value1 = 1;
if(!get_memberuids(map.gid, &uids, &num))
return NT_STATUS_NO_SUCH_GROUP;
SAFE_FREE(uids);
init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
SAFE_FREE(sids);
become_root();
r_u->status = pdb_enum_group_members(
p->mem_ctx, &group_sid, &members, &num_members);
unbecome_root();
if (!NT_STATUS_IS_OK(r_u->status)) {
return r_u->status;
}
init_samr_group_info1(&ctr->group.info1, map.nt_name,
map.comment, num_members);
break;
}
case 3:
ctr->switch_value1 = 3;
init_samr_group_info3(&ctr->group.info3);

View File

@ -1067,7 +1067,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
pass = Get_Pwnam(username);
if (!pass) {
DEBUG(1, ("check_oem_password: Username %s does not exist in system !?!\n", username));
DEBUG(1, ("change_oem_password: Username %s does not exist in system !?!\n", username));
return NT_STATUS_ACCESS_DENIED;
}

178
source3/smbd/map_username.c Normal file
View File

@ -0,0 +1,178 @@
/*
Unix SMB/CIFS implementation.
Username handling
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1997-2001.
Copyright (C) Volker Lendecke 2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
/*******************************************************************
Map a username from a dos name to a unix name by looking in the username
map. Note that this modifies the name in place.
This is the main function that should be called *once* on
any incoming or new username - in order to canonicalize the name.
This is being done to de-couple the case conversions from the user mapping
function. Previously, the map_username was being called
every time Get_Pwnam was called.
Returns True if username was changed, false otherwise.
********************************************************************/
BOOL map_username(fstring user)
{
static BOOL initialised=False;
static fstring last_from,last_to;
XFILE *f;
char *mapfile = lp_username_map();
char *s;
pstring buf;
BOOL mapped_user = False;
char *cmd = lp_username_map_script();
if (!*user)
return False;
if (strequal(user,last_to))
return False;
if (strequal(user,last_from)) {
DEBUG(3,("Mapped user %s to %s\n",user,last_to));
fstrcpy(user,last_to);
return True;
}
/* first try the username map script */
if ( *cmd ) {
char **qlines;
pstring command;
int numlines, ret, fd;
pstr_sprintf( command, "%s \"%s\"", cmd, user );
DEBUG(10,("Running [%s]\n", command));
ret = smbrun(command, &fd);
DEBUGADD(10,("returned [%d]\n", ret));
if ( ret != 0 ) {
if (fd != -1)
close(fd);
return False;
}
numlines = 0;
qlines = fd_lines_load(fd, &numlines,0);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
/* should be either no lines or a single line with the mapped username */
if (numlines) {
DEBUG(3,("Mapped user %s to %s\n", user, qlines[0] ));
fstrcpy( user, qlines[0] );
}
file_lines_free(qlines);
return numlines != 0;
}
/* ok. let's try the mapfile */
if (!*mapfile)
return False;
if (!initialised) {
*last_from = *last_to = 0;
initialised = True;
}
f = x_fopen(mapfile,O_RDONLY, 0);
if (!f) {
DEBUG(0,("can't open username map %s. Error %s\n",mapfile, strerror(errno) ));
return False;
}
DEBUG(4,("Scanning username map %s\n",mapfile));
while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) {
char *unixname = s;
char *dosname = strchr_m(unixname,'=');
char **dosuserlist;
BOOL return_if_mapped = False;
if (!dosname)
continue;
*dosname++ = 0;
while (isspace((int)*unixname))
unixname++;
if ('!' == *unixname) {
return_if_mapped = True;
unixname++;
while (*unixname && isspace((int)*unixname))
unixname++;
}
if (!*unixname || strchr_m("#;",*unixname))
continue;
{
int l = strlen(unixname);
while (l && isspace((int)unixname[l-1])) {
unixname[l-1] = 0;
l--;
}
}
dosuserlist = str_list_make(dosname, NULL);
if (!dosuserlist) {
DEBUG(0,("Unable to build user list\n"));
return False;
}
if (strchr_m(dosname,'*') ||
user_in_list(user, (const char **)dosuserlist)) {
DEBUG(3,("Mapped user %s to %s\n",user,unixname));
mapped_user = True;
fstrcpy( last_from,user );
fstrcpy( user, unixname );
fstrcpy( last_to,user );
if ( return_if_mapped ) {
str_list_free (&dosuserlist);
x_fclose(f);
return True;
}
}
str_list_free (&dosuserlist);
}
x_fclose(f);
/*
* Setup the last_from and last_to as an optimization so
* that we don't scan the file again for the same user.
*/
fstrcpy(last_from,user);
fstrcpy(last_to,user);
return mapped_user;
}

View File

@ -401,6 +401,135 @@ void add_session_user(const char *user)
safe_strcat(session_userlist,suser,len_session_userlist-1);
}
/****************************************************************************
Check if a user is in a netgroup user list. If at first we don't succeed,
try lower case.
****************************************************************************/
BOOL user_in_netgroup(const char *user, const char *ngname)
{
#ifdef HAVE_NETGROUP
static char *mydomain = NULL;
fstring lowercase_user;
if (mydomain == NULL)
yp_get_default_domain(&mydomain);
if(mydomain == NULL) {
DEBUG(5,("Unable to get default yp domain\n"));
return False;
}
DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
user, mydomain, ngname));
if (innetgr(ngname, NULL, user, mydomain)) {
DEBUG(5,("user_in_netgroup: Found\n"));
return (True);
} else {
/*
* Ok, innetgr is case sensitive. Try once more with lowercase
* just in case. Attempt to fix #703. JRA.
*/
fstrcpy(lowercase_user, user);
strlower_m(lowercase_user);
DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
lowercase_user, mydomain, ngname));
if (innetgr(ngname, NULL, lowercase_user, mydomain)) {
DEBUG(5,("user_in_netgroup: Found\n"));
return (True);
}
}
#endif /* HAVE_NETGROUP */
return False;
}
/****************************************************************************
Check if a user is in a user list - can check combinations of UNIX
and netgroup lists.
****************************************************************************/
BOOL user_in_list(const char *user,const char **list)
{
if (!list || !*list)
return False;
DEBUG(10,("user_in_list: checking user %s in list\n", user));
while (*list) {
DEBUG(10,("user_in_list: checking user |%s| against |%s|\n",
user, *list));
/*
* Check raw username.
*/
if (strequal(user, *list))
return(True);
/*
* Now check to see if any combination
* of UNIX and netgroups has been specified.
*/
if(**list == '@') {
/*
* Old behaviour. Check netgroup list
* followed by UNIX list.
*/
if(user_in_netgroup(user, *list +1))
return True;
if(user_in_group(user, *list +1))
return True;
} else if (**list == '+') {
if((*(*list +1)) == '&') {
/*
* Search UNIX list followed by netgroup.
*/
if(user_in_group(user, *list +2))
return True;
if(user_in_netgroup(user, *list +2))
return True;
} else {
/*
* Just search UNIX list.
*/
if(user_in_group(user, *list +1))
return True;
}
} else if (**list == '&') {
if(*(*list +1) == '+') {
/*
* Search netgroup list followed by UNIX list.
*/
if(user_in_netgroup(user, *list +2))
return True;
if(user_in_group(user, *list +2))
return True;
} else {
/*
* Just search netgroup list.
*/
if(user_in_netgroup(user, *list +1))
return True;
}
}
list++;
}
return(False);
}
/****************************************************************************
Check if a username is valid.
****************************************************************************/

View File

@ -1015,7 +1015,6 @@ static void apply_default_perms(files_struct *fsp, canon_ace *pace, mode_t type)
static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
{
fstring u_name;
fstring g_name;
/* "Everyone" always matches every uid. */
@ -1028,14 +1027,7 @@ static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
return True;
fstrcpy(u_name, uidtoname(uid_ace->unix_ug.uid));
fstrcpy(g_name, gidtoname(group_ace->unix_ug.gid));
/*
* Due to the winbind interfaces we need to do this via names,
* not uids/gids.
*/
return user_in_group(u_name, g_name);
return user_in_group_sid(u_name, &group_ace->trustee);
}
/****************************************************************************

View File

@ -473,7 +473,7 @@ static NTSTATUS find_forced_group(BOOL force_user,
*/
if (force_user && user_must_be_member) {
if (user_in_group(username, groupname)) {
if (user_in_group_sid(username, &group_sid)) {
sid_copy(pgroup_sid, &group_sid);
*pgid = gid;
DEBUG(3,("Forced group %s for member %s\n",

View File

@ -312,7 +312,7 @@ static int net_groupmap_add(int argc, const char **argv)
fstrcpy( ntgroup, unixgrp );
if (!add_initial_entry(gid, string_sid, sid_type, ntgroup, ntcomment)) {
if (!NT_STATUS_IS_OK(add_initial_entry(gid, string_sid, sid_type, ntgroup, ntcomment))) {
d_fprintf(stderr, "adding entry for group %s failed!\n", ntgroup);
return -1;
}
@ -494,7 +494,7 @@ static int net_groupmap_delete(int argc, const char **argv)
return -1;
}
if ( !pdb_delete_group_mapping_entry(sid) ) {
if ( !NT_STATUS_IS_OK(pdb_delete_group_mapping_entry(sid)) ) {
d_fprintf(stderr, "Failed to removing group %s from the mapping db!\n", ntgroup);
return -1;
}

View File

@ -550,7 +550,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
sam_account_from_delta(sam_account, delta);
DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n",
sid_to_string(sid_string, &user_sid), pdb_get_username(sam_account)));
if (!pdb_add_sam_account(sam_account)) {
if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account))) {
DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
account));
return NT_STATUS_ACCESS_DENIED;