static int next_vuid = VUID_OFFSET;
static int num_validated_vuids;
-extern userdom_struct current_user_info;
-
-
/****************************************************************************
Check if a uid has been validated, and return an pointer to the user_struct
if it has. NULL if not. vuid is biased by an offset. This allows us to
session_yield(vuser);
SAFE_FREE(vuser->session_keystr);
- talloc_free(vuser->server_info);
+ TALLOC_FREE(vuser->server_info);
data_blob_free(&vuser->session_key);
conn_clear_vuid_cache(vuid);
SAFE_FREE(vuser->groups);
- talloc_free(vuser->nt_user_token);
+ TALLOC_FREE(vuser->nt_user_token);
SAFE_FREE(vuser);
num_validated_vuids--;
}
{
user_struct *vuser = NULL;
- /* Ensure no vuid gets registered in share level security. */
+ /* Paranoia check. */
if(lp_security() == SEC_SHARE) {
- data_blob_free(&session_key);
- return UID_FIELD_INVALID;
+ smb_panic("Tried to register uid in security=share\n");
}
/* Limit allowed vuids to 16bits - VUID_OFFSET. */
vuser->vuid = next_vuid;
if (!server_info) {
+ /*
+ * This happens in an unfinished NTLMSSP session setup. We
+ * need to allocate a vuid between the first and second calls
+ * to NTLMSSP.
+ */
next_vuid++;
num_validated_vuids++;
"vuser->groups\n"));
data_blob_free(&session_key);
free(vuser);
- talloc_free(server_info);
+ TALLOC_FREE(server_info);
return UID_FIELD_INVALID;
}
}
if (passwd) {
vuser->unix_homedir =
smb_xstrdup(passwd->pw_dir);
- talloc_free(passwd);
+ TALLOC_FREE(passwd);
}
}
} else {
DEBUG(1, ("server_info does not contain a user_token - "
"cannot continue\n"));
- talloc_free(server_info);
+ TALLOC_FREE(server_info);
data_blob_free(&session_key);
SAFE_FREE(vuser->homedir);
SAFE_FREE(vuser->unix_homedir);
DEBUG(1, ("Failed to claim session for vuid=%d\n",
vuser->vuid));
invalidate_vuid(vuser->vuid);
- return -1;
+ return UID_FIELD_INVALID;
}
/* Register a home dir service for this user iff
"too large.\n"));
return;
}
- newlist = (char *)SMB_REALLOC(
+ newlist = (char *)SMB_REALLOC_KEEP_OLD_ON_ERROR(
session_userlist,
len_session_userlist + PSTRING_LEN );
if( newlist == NULL ) {
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, let's try without specifying it\n"));
+ }
+
+ DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
+ user, mydomain?mydomain:"(ANY)", 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?mydomain:"(ANY)", 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.
****************************************************************************/
str_list_copy(&invalid, lp_invalid_users(snum));
if (invalid &&
str_list_substitute(invalid, "%S", lp_servicename(snum))) {
- if ( invalid &&
- str_list_sub_basic(invalid,
- current_user_info.smb_name) ) {
+
+ /* This is used in sec=share only, so no current user
+ * around to pass to str_list_sub_basic() */
+
+ if ( invalid && str_list_sub_basic(invalid, "", "") ) {
ret = !user_in_list(user,
(const char **)invalid);
}
str_list_copy(&valid, lp_valid_users(snum));
if ( valid &&
str_list_substitute(valid, "%S", lp_servicename(snum)) ) {
- if ( valid &&
- str_list_sub_basic(valid,
- current_user_info.smb_name) ) {
+
+ /* This is used in sec=share only, so no current user
+ * around to pass to str_list_sub_basic() */
+
+ if ( valid && str_list_sub_basic(valid, "", "") ) {
ret = user_in_list(user, (const char **)valid);
}
}