1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

Started to canonicalize our handling of uid -> sid code in order to

get ready and fix se_access_check().
Added cannonical lookup_name(), lookup_sid(), uid_to_sid(), gid_to_sid()
functions that look via winbind first the fall back on local lookup.

All Samba should use these rather than trying to call winbindd code
directly.

Added NT_USER_TOKEN struct in user_struct, contains list of NT sids
associated with this user.

se_access_check() should use this (cached) value rather than attempting
to do the same thing itself when given a uid/gid pair.

More work needs to be done to preserve these things accross security
context changes (especially with the tricky pipe problem) but I'm
beginning to see how this will be done..... probably by registering
a new vuid for an authenticated RPC pipe and not treating the
pipe calls specially.

More thoughts needed - but we're almost there...

Jeremy.
This commit is contained in:
Jeremy Allison 0001-01-01 00:00:00 +00:00
parent c55bcec817
commit 5e5cc6efe2
13 changed files with 259 additions and 226 deletions

View File

@ -1278,8 +1278,12 @@ void expire_workgroups_and_servers(time_t t);
BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type);
BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
uint8 *name_type);
BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid);
BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid);
BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid);
BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid);
BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type);
BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type);
DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid);
DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid);
/*The following definitions come from nsswitch/wb_common.c */
@ -1622,9 +1626,10 @@ gid_t pdb_user_rid_to_gid(uint32 user_rid);
uint32 pdb_uid_to_user_rid(uid_t uid);
uint32 pdb_gid_to_group_rid(gid_t gid);
BOOL pdb_rid_is_user(uint32 rid);
BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use);
BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
BOOL setup_user_sids(user_struct *vuser);
BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use);
BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid);
DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid);
/*The following definitions come from passdb/secrets.c */
@ -3540,8 +3545,8 @@ user_struct *get_valid_user_struct(uint16 vuid);
void invalidate_vuid(uint16 vuid);
char *validated_username(uint16 vuid);
char *validated_domain(uint16 vuid);
int setup_groups(char *user, char *domain,
uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
int initialize_groups(char *user, uid_t uid, gid_t gid);
void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups);
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
char *domain,BOOL guest);
void add_session_user(char *user);
@ -3667,6 +3672,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
/*The following definitions come from smbd/sec_ctx.c */
int get_current_groups(int *p_ngroups, gid_t **p_groups);
BOOL push_sec_ctx(void);
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups);
void set_root_sec_ctx(void);

View File

@ -399,6 +399,15 @@ typedef struct sid_info
} DOM_SID;
/*
* The complete list of SIDS belonging to this user.
* Created when a vuid is registered.
*/
typedef struct _nt_user_token {
size_t num_sids;
DOM_SID *user_sids;
} NT_USER_TOKEN;
/*** query a local group, get a list of these: shows who is in that group ***/
@ -556,8 +565,8 @@ typedef struct connection_struct
char *connectpath;
char *origpath;
struct vfs_ops vfs_ops; /* Filesystem operations */
struct vfs_connection_struct *vfs_conn; /* VFS specific connection stuff */
struct vfs_ops vfs_ops; /* Filesystem operations */
struct vfs_connection_struct *vfs_conn; /* VFS specific connection stuff */
char *user; /* name of user who *opened* this connection */
uid_t uid; /* uid of user who *opened* this connection */
@ -1663,12 +1672,7 @@ typedef struct
int n_groups;
gid_t *groups;
#if 0
NET_USER_INFO_3 usr; /* This should not be here. */
#else
DOM_SID user_sid;
DOM_SID *group_sids;
#endif
NT_USER_TOKEN nt_user_token;
/* per-user authentication information on NT RPCs */
/* lkclXXXX - THIS SHOULD NOT BE HERE! */

View File

@ -99,12 +99,12 @@ static BOOL check_ace(SEC_ACE *ace, BOOL is_owner, DOM_SID *sid,
sid_to_string(sid_str, sid);
sid_to_string(ace_sid_str, &ace->sid);
if (!winbind_lookup_sid(sid, name_dom, name, &name_type)) {
if (!lookup_sid(sid, name_dom, name, &name_type)) {
fstrcpy(name_dom, "UNKNOWN");
fstrcpy(name, "UNKNOWN");
}
if (!winbind_lookup_sid(&ace->sid, ace_name_dom, ace_name,
if (!lookup_sid(&ace->sid, ace_name_dom, ace_name,
&name_type)) {
fstrcpy(ace_name_dom, "UNKNOWN");
fstrcpy(ace_name, "UNKNOWN");
@ -208,6 +208,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
uint32 acc_desired, uint32 *acc_granted, uint32 *status)
{
DOM_SID user_sid, group_sid;
DOM_SID owner_sid;
DOM_SID **group_sids = NULL;
int i, j;
uint ngroup_sids = 0;
@ -215,25 +216,30 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
uint8 check_ace_type;
fstring sid_str;
if (!status || !acc_granted) return False;
if (!status || !acc_granted)
return False;
*status = NT_STATUS_ACCESS_DENIED;
*acc_granted = 0;
/* No security descriptor allows all access */
/*
* No security descriptor or security descriptor with no DACL
* present allows all access.
*/
if (!sd) {
if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
*status = NT_STATUS_NOPROBLEMO;
*acc_granted = acc_desired;
acc_desired = 0;
DEBUG(3, ("no sd, access allowed\n"));
goto done;
DEBUG(3, ("se_access_check: no sd or blank DACL, access allowed\n"));
goto done;
}
/* If desired access mask is empty then no access is allowed */
if (acc_desired == 0) {
*status = NT_STATUS_ACCESS_DENIED;
*acc_granted = 0;
goto done;
}
@ -246,12 +252,12 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
/* Create user sid */
if (!winbind_uid_to_sid(user->uid, &user_sid)) {
if (!uid_to_sid(&user_sid, user->uid)) {
DEBUG(3, ("could not lookup sid for uid %d\n", user->uid));
goto done;
}
sid_to_string(sid_str, &user_sid);
DEBUG(3, ("user sid is %s\n", sid_str));
DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &user_sid) ));
/* If we're the owner, then we can do anything */
@ -266,8 +272,9 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
/* Create group sid */
if (!winbind_gid_to_sid(user->gid, &group_sid)) {
if (!gid_to_sid(&group_sid, user->gid)) {
DEBUG(3, ("could not lookup sid for gid %d\n", user->gid));
goto done;
}
sid_to_string(sid_str, &group_sid);
@ -279,7 +286,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
for (i = 0; i < user->ngroups; i++) {
if (user->groups[i] != user->gid) {
if (winbind_gid_to_sid(user->groups[i], &group_sid)) {
if (gid_to_sid(&group_sid, user->groups[i])) {
/* If we're a group member then we can also
do anything */
@ -310,18 +317,18 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
acl = sd->dacl;
if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) {
if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) {
/* Checks against a NULL ACL succeed and return access
granted = access requested. */
granted = access requested. */
*status = NT_STATUS_NOPROBLEMO;
*acc_granted = acc_desired;
acc_desired = 0;
DEBUG(3, ("null ace, access allowed\n"));
goto done;
}
goto done;
}
/* Check each ACE in ACL. We break out of the loop if an ACE is
either explicitly denied or explicitly allowed by the
@ -370,7 +377,8 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
}
done:
free_sid_array(ngroup_sids, group_sids);
free_sid_array(ngroup_sids, group_sids);
/* If any access desired bits are still on, return access denied
and turn off any bits already granted. */
@ -380,5 +388,5 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
*status = NT_STATUS_ACCESS_DENIED;
}
return *status == NT_STATUS_NOPROBLEMO;
return *status == NT_STATUS_NOPROBLEMO;
}

View File

@ -29,7 +29,6 @@
BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type)
{
extern pstring global_myname;
struct winbindd_request request;
struct winbindd_response response;
enum nss_status result;
@ -47,14 +46,6 @@ BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type)
&response)) == NSS_STATUS_SUCCESS) {
string_to_sid(sid, response.data.sid.sid);
*name_type = response.data.sid.type;
} else {
/*
* Try a local lookup - winbindd may not
* be running.
*/
return lookup_local_name(global_myname, name, sid, name_type);
}
return result == NSS_STATUS_SUCCESS;
@ -85,7 +76,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
if (sid_equal(&global_sam_sid, &tmp_sid)) {
return map_domain_sid_to_name(&tmp_sid, dom_name) &&
lookup_local_rid(rid, name, name_type);
local_lookup_rid(rid, name, name_type);
}
}
@ -106,15 +97,6 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
if (result == NSS_STATUS_SUCCESS) {
parse_domain_user(response.data.name.name, dom_name, name);
*name_type = response.data.name.type;
} else {
DEBUG(10,("winbind_lookup_sid: winbind lookup for %s failed - trying builtin.\n",
sid_str));
sid_copy(&tmp_sid, sid);
sid_split_rid(&tmp_sid, &rid);
return map_domain_sid_to_name(&tmp_sid, dom_name) &&
lookup_known_rid(&tmp_sid, rid, name, name_type);
}
return (result == NSS_STATUS_SUCCESS);
@ -122,13 +104,14 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
/* Call winbindd to convert uid to sid */
BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid)
BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
if (!sid) return False;
if (!sid)
return False;
/* Initialise request */
@ -154,13 +137,14 @@ BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid)
/* Call winbindd to convert uid to sid */
BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid)
BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
if (!sid) return False;
if (!sid)
return False;
/* Initialise request */
@ -183,3 +167,79 @@ BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid)
return (result == NSS_STATUS_SUCCESS);
}
/*****************************************************************
*THE CANNONICAL* convert name to SID function.
Tries winbind first - then uses local lookup.
*****************************************************************/
BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type)
{
extern pstring global_myname;
if (!winbind_lookup_name(name, psid, name_type)) {
DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name ));
return local_lookup_name(global_myname, name, psid, name_type);
}
return True;
}
/*****************************************************************
*THE CANNONICAL* convert SID to name function.
Tries winbind first - then uses local lookup.
*****************************************************************/
BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type)
{
if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
fstring sid_str;
DOM_SID tmp_sid;
uint32 rid;
DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
sid_copy(&tmp_sid, sid);
sid_split_rid(&tmp_sid, &rid);
return map_domain_sid_to_name(&tmp_sid, dom_name) &&
lookup_known_rid(&tmp_sid, rid, name, name_type);
}
return True;
}
/*****************************************************************
*THE CANNONICAL* convert uid_t to SID function.
Tries winbind first - then uses local lookup.
Returns SID pointer.
*****************************************************************/
DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
{
if (!winbind_uid_to_sid(psid, uid)) {
DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid ));
return local_uid_to_sid(psid, uid);
}
return psid;
}
/*****************************************************************
*THE CANNONICAL* convert gid_t to SID function.
Tries winbind first - then uses local lookup.
Returns SID pointer.
*****************************************************************/
DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
{
if (!winbind_gid_to_sid(psid, gid)) {
DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid ));
return local_gid_to_sid(psid, gid);
}
return psid;
}

View File

@ -1091,12 +1091,12 @@ BOOL pdb_rid_is_user(uint32 rid)
Convert a rid into a name. Used in the lookup SID rpc.
********************************************************************/
BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use)
{
BOOL is_user = pdb_rid_is_user(rid);
DEBUG(5,("lookup_local_rid: looking up %s RID %u.\n", is_user ? "user" :
DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
"group", (unsigned int)rid));
if(is_user) {
@ -1118,7 +1118,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
*psid_name_use = SID_NAME_USER;
DEBUG(5,("lookup_local_rid: looking up uid %u %s\n", (unsigned int)uid,
DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid,
pass ? "succeeded" : "failed" ));
if(!pass) {
@ -1128,7 +1128,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
fstrcpy(name, pass->pw_name);
DEBUG(5,("lookup_local_rid: found user %s for rid %u\n", name,
DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name,
(unsigned int)rid ));
}
@ -1138,7 +1138,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
*psid_name_use = SID_NAME_ALIAS;
DEBUG(5,("lookup_local_rid: looking up gid %u %s\n", (unsigned int)gid,
DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
gr ? "succeeded" : "failed" ));
if(!gr) {
@ -1148,7 +1148,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
fstrcpy( name, gr->gr_name);
DEBUG(5,("lookup_local_rid: found group %s for rid %u\n", name,
DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
(unsigned int)rid ));
}
@ -1159,7 +1159,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
Convert a name into a SID. Used in the lookup name rpc.
********************************************************************/
BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use)
BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use)
{
extern DOM_SID global_sid_World_Domain;
struct passwd *pass = NULL;
@ -1206,71 +1206,29 @@ BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name
}
/****************************************************************************
Create a list of SIDS for a user - primary and group.
This is really the wrong way to do this and needs to go via winbind. JRA.
Convert a uid to SID - locally.
****************************************************************************/
BOOL setup_user_sids(user_struct *vuser)
DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
{
extern DOM_SID global_sam_sid;
sid_copy(&vuser->user_sid, &global_sam_sid);
sid_append_rid( &vuser->user_sid, pdb_uid_to_user_rid(vuser->uid));
sid_copy(psid, &global_sam_sid);
sid_append_rid(psid, pdb_uid_to_user_rid(uid));
if (vuser->n_groups != 0) {
int i;
vuser->group_sids = (DOM_SID *)malloc(sizeof(DOM_SID) * vuser->n_groups);
if (vuser->group_sids == NULL)
return False;
for (i = 0; i < vuser->n_groups; i++) {
sid_copy(&vuser->group_sids[i], &global_sam_sid);
sid_append_rid( &vuser->group_sids[i], pdb_gid_to_group_rid(vuser->groups[i]));
}
}
return True;
#if 0
/* Luke's code. */
if (usr == NULL)
{
int i;
extern DOM_SID global_sam_sid;
DEBUG(0,("vuser struct usr being filled in with trash, today\n"));
DEBUG(0,("this needs to be replaced with a proper surs impl.\n"));
DEBUG(0,("e.g. the one used in winbindd. in fact, all\n"));
DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n"));
DEBUG(0,("as soon as possible.\n"));
vuser->usr.user_id = pdb_uid_to_user_rid(uid);
vuser->usr.group_id = pdb_gid_to_group_rid(gid);
vuser->usr.num_groups = vuser->n_groups;
if (vuser->n_groups != 0)
{
vuser->usr.gids = g_new(DOM_GID, vuser->usr.num_groups);
if (vuser->usr.gids == NULL)
return UID_FIELD_INVALID;
}
for (i = 0; i < vuser->usr.num_groups; i++)
{
DOM_GID *ntgid = &vuser->usr.gids[i];
ntgid->attr = 0x7;
ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]);
}
/* this is possibly the worst thing to do, ever. it assumes */
/* that all users of this system are in the local SAM database */
/* however, because there is no code to do anything otherwise, */
/* we have no choice */
init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid);
}
else
{
vuser->usr = *usr;
}
#endif
return psid;
}
/****************************************************************************
Convert a gid to SID - locally.
****************************************************************************/
DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
{
extern DOM_SID global_sam_sid;
sid_copy(psid, &global_sam_sid);
sid_append_rid(psid, pdb_gid_to_group_rid(gid));
return psid;
}

View File

@ -238,7 +238,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
if (map_domain_name_to_sid(&dom_sid, dom_name)) {
dom_idx = init_dom_ref(ref, dom_name, &dom_sid);
if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid))
if (local_lookup_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid))
status = True;
}

View File

@ -978,7 +978,7 @@ static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
if(alias_rid == 0xffffffff)
r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
if(!lookup_local_rid(alias_rid, alias, &type))
if(!local_lookup_rid(alias_rid, alias, &type))
{
r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
}
@ -1151,7 +1151,7 @@ static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
if(sid_equal(&pol_sid, &global_sam_sid))
{
DOM_SID sid;
if(lookup_local_name(global_myname, name,
if(local_lookup_name(global_myname, name,
&sid, &type[i]))
{
sid_split_rid( &sid, &rid[i]);

View File

@ -112,6 +112,16 @@ user_struct *get_valid_user_struct(uint16 vuid)
return &validated_users[vuid];
}
/****************************************************************************
Delete the SID list for this user.
****************************************************************************/
static void delete_nt_token(NT_USER_TOKEN *token)
{
safe_free( token->user_sids );
ZERO_STRUCTP(token);
}
/****************************************************************************
invalidate a uid
****************************************************************************/
@ -133,8 +143,7 @@ void invalidate_vuid(uint16 vuid)
vuser->groups = NULL;
if (vuser->group_sids != NULL)
free (vuser->group_sids);
delete_nt_token(&vuser->nt_user_token);
}
@ -162,61 +171,54 @@ char *validated_domain(uint16 vuid)
/****************************************************************************
Setup the groups a user belongs to.
Initialize the groups a user belongs to.
****************************************************************************/
int setup_groups(char *user, char *domain,
uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
{
int i,ngroups;
gid_t grp = 0;
gid_t *groups = NULL;
if (-1 == initgroups(user,gid))
{
int initialize_groups(char *user, uid_t uid, gid_t gid)
{
if (initgroups(user,gid) == -1) {
DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) ));
if (getuid() == 0)
{
if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767)
{
if (getuid() == 0) {
if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) {
DEBUG(0,("This is probably a problem with the account %s\n", user));
}
}
return -1;
}
ngroups = sys_getgroups(0,&grp);
if (ngroups <= 0)
{
ngroups = groups_max();
}
if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
{
DEBUG(0,("setup_groups malloc fail !\n"));
return -1;
}
ngroups = sys_getgroups(ngroups,groups);
(*p_ngroups) = ngroups;
(*p_groups) = groups;
DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) );
for (i = 0; i < ngroups; i++ )
{
DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
}
DEBUG( 3, ( "\n" ) );
return 0;
}
/****************************************************************************
Create the SID list for this user.
****************************************************************************/
void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups)
{
DOM_SID *psids;
int i;
ZERO_STRUCTP(token);
if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL)
return;
psids = token->user_sids;
token->num_sids = ngroups + 2;
uid_to_sid( &psids[0], uid);
gid_to_sid( &psids[1], gid);
for (i = 0; i < ngroups; i++)
gid_to_sid( &psids[i+2], groups[i]);
}
/****************************************************************************
register a uid/name pair as being valid and that a valid password
has been given. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
char *domain,BOOL guest)
{
@ -227,37 +229,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
if(lp_security() == SEC_SHARE)
return UID_FIELD_INVALID;
#if 0
/*
* After observing MS-Exchange services writing to a Samba share
* I belive this code is incorrect. Each service does its own
* sessionsetup_and_X for the same user, and as each service shuts
* down, it does a user_logoff_and_X. As we are consolidating multiple
* sessionsetup_and_X's onto the same vuid here, when the first service
* shuts down, it invalidates all the open files for the other services.
* Hence I am removing this code and forcing each sessionsetup_and_X
* to get a new vuid.
* Jeremy Allison. (jallison@whistle.com).
*/
int i;
for(i = 0; i < num_validated_users; i++) {
vuser = &validated_users[i];
if ( vuser->uid == uid )
return (uint16)(i + VUID_OFFSET); /* User already validated */
}
#endif
validated_users = (user_struct *)Realloc(validated_users,
sizeof(user_struct)*
(num_validated_users+1));
if (!validated_users)
{
if (!validated_users) {
DEBUG(0,("Failed to realloc users struct!\n"));
num_validated_users = 0;
return UID_FIELD_INVALID;
}
}
vuser = &validated_users[num_validated_users];
num_validated_users++;
@ -274,22 +254,21 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
/* Find all the groups this uid is in and store them.
Used by become_user() */
setup_groups(unix_name,domain,uid,gid,
&vuser->n_groups,
&vuser->groups);
initialize_groups(unix_name, uid, gid);
get_current_groups( &vuser->n_groups, &vuser->groups);
setup_user_sids(vuser);
/* Create an NT_USER_TOKEN struct for this user. */
setup_nt_token(&vuser->nt_user_token, uid,gid, vuser->n_groups, vuser->groups);
DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
DEBUG(3, ("Clearing default real name\n"));
fstrcpy(vuser->user.full_name, "<Full Name>");
if (lp_unix_realname()) {
if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL)
{
if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) {
DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos));
fstrcpy(vuser->user.full_name, pwfile->pw_gecos);
}
}
}
memset(&vuser->dc, '\0', sizeof(vuser->dc));

View File

@ -561,8 +561,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
}
/* load service specific parameters */
if (conn &&
!become_service(conn,(flags & AS_USER)?True:False)) {
if (conn && !become_service(conn,(flags & AS_USER)?True:False)) {
return(ERROR(ERRSRV,ERRaccess));
}

View File

@ -125,17 +125,37 @@ static void gain_root(void)
/* Get the list of current groups */
static void get_current_groups(int *ngroups, gid_t **groups)
int get_current_groups(int *p_ngroups, gid_t **p_groups)
{
*ngroups = getgroups(0, NULL);
*groups = (gid_t *)malloc(*ngroups * sizeof(gid_t));
int i;
gid_t grp;
int ngroups = sys_getgroups(0,&grp);
gid_t *groups;
if (!groups) {
DEBUG(0, ("Out of memory in get_current_groups\n"));
return;
(*p_ngroups) = 0;
(*p_groups) = NULL;
if (ngroups <= 0)
return -1;
if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) {
DEBUG(0,("setup_groups malloc fail !\n"));
return -1;
}
getgroups(*ngroups, *groups);
if ((ngroups = sys_getgroups(ngroups,groups)) == -1)
return -1;
(*p_ngroups) = ngroups;
(*p_groups) = groups;
DEBUG( 3, ( "get_current_groups: uid %u is in %u groups: ", (unsigned int)getuid() , ngroups ) );
for (i = 0; i < ngroups; i++ ) {
DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
}
DEBUG( 3, ( "\n" ) );
return ngroups;
}
/* Create a new security context on the stack. It is the same as the old

View File

@ -511,8 +511,8 @@ connection_struct *make_connection(char *service,char *user,char *password, int
if (!IS_IPC(conn)) {
/* Find all the groups this uid is in and
store them. Used by become_user() */
setup_groups(conn->user,validated_domain(vuid),conn->uid,conn->gid,
&conn->ngroups,&conn->groups);
initialize_groups(conn->user, conn->uid, conn->gid);
get_current_groups(&conn->ngroups,&conn->groups);
/* check number of connections */
if (!claim_connection(conn,

View File

@ -38,7 +38,8 @@ BOOL become_guest(void)
if (!pass)
pass = Get_Pwnam(lp_guestaccount(-1),True);
if (!pass) return(False);
if (!pass)
return(False);
#ifdef AIX
/* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
@ -60,19 +61,21 @@ BOOL become_guest(void)
static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
{
int i;
for (i=0;i<conn->uid_cache.entries;i++)
if (conn->uid_cache.list[i] == vuser->uid) return(True);
int i;
for (i=0;i<conn->uid_cache.entries;i++)
if (conn->uid_cache.list[i] == vuser->uid)
return(True);
if (!user_ok(vuser->user.unix_name,snum)) return(False);
if (!user_ok(vuser->user.unix_name,snum))
return(False);
i = conn->uid_cache.entries % UID_CACHE_SIZE;
conn->uid_cache.list[i] = vuser->uid;
i = conn->uid_cache.entries % UID_CACHE_SIZE;
conn->uid_cache.list[i] = vuser->uid;
if (conn->uid_cache.entries < UID_CACHE_SIZE)
conn->uid_cache.entries++;
if (conn->uid_cache.entries < UID_CACHE_SIZE)
conn->uid_cache.entries++;
return(True);
return(True);
}
/****************************************************************************

View File

@ -28,12 +28,8 @@
static void create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
{
extern DOM_SID global_sam_sid;
sid_copy(powner_sid, &global_sam_sid);
sid_copy(pgroup_sid, &global_sam_sid);
sid_append_rid(powner_sid, pdb_uid_to_user_rid(psbuf->st_uid));
sid_append_rid(pgroup_sid, pdb_gid_to_group_rid(psbuf->st_gid));
uid_to_sid( powner_sid, psbuf->st_uid );
gid_to_sid( pgroup_sid, psbuf->st_gid );
}
/****************************************************************************