summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h20
-rw-r--r--source3/include/smb.h20
-rw-r--r--source3/lib/util_seaccess.c46
-rw-r--r--source3/nsswitch/wb_client.c106
-rw-r--r--source3/passdb/passdb.c86
-rw-r--r--source3/rpc_server/srv_lsa.c2
-rw-r--r--source3/rpc_server/srv_samr.c4
-rw-r--r--source3/smbd/password.c113
-rw-r--r--source3/smbd/process.c3
-rw-r--r--source3/smbd/sec_ctx.c34
-rw-r--r--source3/smbd/service.c4
-rw-r--r--source3/smbd/uid.c23
-rw-r--r--source3/smbd/unix_acls.c8
13 files changed, 251 insertions, 218 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 85ea676736..321f3098e9 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index bc9f17544c..aaebe56f33 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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! */
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c
index 05a7a30635..52696d2d30 100644
--- a/source3/lib/util_seaccess.c
+++ b/source3/lib/util_seaccess.c
@@ -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;
}
diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c
index 78de466636..47f1520efa 100644
--- a/source3/nsswitch/wb_client.c
+++ b/source3/nsswitch/wb_client.c
@@ -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;
+}
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 04f02e3704..f0fe2499df 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -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;
+ return psid;
+}
- vuser->group_sids = (DOM_SID *)malloc(sizeof(DOM_SID) * vuser->n_groups);
+/****************************************************************************
+ Convert a gid to SID - locally.
+****************************************************************************/
- if (vuser->group_sids == NULL)
- return False;
+DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+ extern DOM_SID global_sam_sid;
- 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]));
- }
- }
+ sid_copy(psid, &global_sam_sid);
+ sid_append_rid(psid, pdb_gid_to_group_rid(gid));
- 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;
}
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c
index bfb671d167..dc97d6db44 100644
--- a/source3/rpc_server/srv_lsa.c
+++ b/source3/rpc_server/srv_lsa.c
@@ -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;
}
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index 5a0f049ba7..e80175f71d 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -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]);
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index f9291b8705..0372e7a0f9 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -113,6 +113,16 @@ user_struct *get_valid_user_struct(uint16 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
****************************************************************************/
void invalidate_vuid(uint16 vuid)
@@ -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;
}
+ return 0;
+}
- ngroups = sys_getgroups(0,&grp);
- if (ngroups <= 0)
- {
- ngroups = groups_max();
- }
+/****************************************************************************
+ Create the SID list for this user.
+****************************************************************************/
- if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
- {
- DEBUG(0,("setup_groups malloc fail !\n"));
- return -1;
- }
+void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups)
+{
+ DOM_SID *psids;
+ int i;
- ngroups = sys_getgroups(ngroups,groups);
+ ZERO_STRUCTP(token);
- (*p_ngroups) = ngroups;
- (*p_groups) = groups;
+ if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL)
+ return;
- 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" ) );
+ psids = token->user_sids;
- return 0;
-}
+ 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));
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 2662db5896..37d8f8dd73 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -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));
}
diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index f7ea1e2d86..432cb223e2 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -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;
+
+ (*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;
+ }
+
+ if ((ngroups = sys_getgroups(ngroups,groups)) == -1)
+ return -1;
+
+ (*p_ngroups) = ngroups;
+ (*p_groups) = groups;
- if (!groups) {
- DEBUG(0, ("Out of memory in get_current_groups\n"));
- return;
+ 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" ) );
- getgroups(*ngroups, *groups);
+ return ngroups;
}
/* Create a new security context on the stack. It is the same as the old
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 2eab50c482..d4760ca92d 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -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,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 172e872020..4cb2c512b6 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -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);
}
/****************************************************************************
diff --git a/source3/smbd/unix_acls.c b/source3/smbd/unix_acls.c
index 7a2dc6ab6e..46c57af5de 100644
--- a/source3/smbd/unix_acls.c
+++ b/source3/smbd/unix_acls.c
@@ -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 );
}
/****************************************************************************