summaryrefslogtreecommitdiffstats
path: root/source3
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2004-03-16 16:41:54 +0000
committerGerald Carter <jerry@samba.org>2004-03-16 16:41:54 +0000
commitd24b8a2032a2e92d954781e610ab535361fefd88 (patch)
tree0f509e01c295b3001153a341225dc4cdedd49b4a /source3
parent96c5a010bb42b268b441f776ac44cad84d5f2261 (diff)
downloadsamba-d24b8a2032a2e92d954781e610ab535361fefd88.tar.gz
samba-d24b8a2032a2e92d954781e610ab535361fefd88.tar.xz
samba-d24b8a2032a2e92d954781e610ab535361fefd88.zip
BUG 1165, 1126: Fix bug with secondary groups (security = ads) and winbind use default domain = yes
(This used to be commit f2eaa14b1eb7e89c945b2b06a48e17998c75d620)
Diffstat (limited to 'source3')
-rw-r--r--source3/auth/auth_server.c21
-rw-r--r--source3/auth/auth_unix.c2
-rw-r--r--source3/auth/auth_util.c137
-rw-r--r--source3/smbd/sesssetup.c12
4 files changed, 96 insertions, 76 deletions
diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c
index 41adc217841..bc611ec229b 100644
--- a/source3/auth/auth_server.c
+++ b/source3/auth/auth_server.c
@@ -377,18 +377,17 @@ use this machine as the password server.\n"));
cli_ulogoff(cli);
if (NT_STATUS_IS_OK(nt_status)) {
- struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
- if (pass) {
- nt_status = make_server_info_pw(server_info, pass);
- } else {
- auth_add_user_script(user_info->domain.str, user_info->internal_username.str);
- pass = Get_Pwnam(user_info->internal_username.str);
+ fstring real_username;
+ struct passwd *pass;
- if (pass) {
- nt_status = make_server_info_pw(server_info, pass);
- } else {
- nt_status = NT_STATUS_NO_SUCH_USER;
- }
+ if ( (pass = smb_getpwnam( user_info->internal_username.str,
+ real_username, True )) != NULL )
+ {
+ nt_status = make_server_info_pw(server_info, pass->pw_name, pass);
+ }
+ else
+ {
+ nt_status = NT_STATUS_NO_SUCH_USER;
}
}
diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c
index b9de6f7acbd..f744cba0c43 100644
--- a/source3/auth/auth_unix.c
+++ b/source3/auth/auth_unix.c
@@ -108,7 +108,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context,
if (NT_STATUS_IS_OK(nt_status)) {
if (pass) {
- make_server_info_pw(server_info, pass);
+ make_server_info_pw(server_info, pass->pw_name, pass);
} else {
/* we need to do somthing more useful here */
nt_status = NT_STATUS_NO_SUCH_USER;
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 0f945b33cb3..dfc3f6cc210 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -757,6 +757,7 @@ Fill a server_info struct from a SAM_ACCOUNT with their groups
***************************************************************************/
static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
+ const char * unix_username,
SAM_ACCOUNT *sampass,
uid_t uid, gid_t gid)
{
@@ -770,7 +771,7 @@ static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
BOOL is_guest;
uint32 rid;
- nt_status = get_user_groups(pdb_get_username(sampass), uid, gid,
+ nt_status = get_user_groups(unix_username, uid, gid,
&n_groupSIDs, &groupSIDs, &unix_groups);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -828,9 +829,11 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
passwd_free(&pwd);
- if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass,
+ if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass),
+ sampass,
(*server_info)->uid,
- (*server_info)->gid))) {
+ (*server_info)->gid)))
+ {
free_server_info(server_info);
return nt_status;
}
@@ -848,7 +851,9 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
to a SAM_ACCOUNT
***************************************************************************/
-NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd)
+NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
+ char *unix_username,
+ struct passwd *pwd)
{
NTSTATUS nt_status;
SAM_ACCOUNT *sampass = NULL;
@@ -861,11 +866,13 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struc
(*server_info)->sam_account = sampass;
- if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass, pwd->pw_uid, pwd->pw_gid))) {
+ if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
+ sampass, pwd->pw_uid, pwd->pw_gid)))
+ {
return nt_status;
}
- (*server_info)->unix_name = smb_xstrdup(pwd->pw_name);
+ (*server_info)->unix_name = smb_xstrdup(unix_username);
(*server_info)->sam_fill_level = SAM_FILL_ALL;
(*server_info)->uid = pwd->pw_uid;
@@ -924,52 +931,30 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
SAM_ACCOUNT **sam_account)
{
fstring dom_user;
+ fstring real_username;
struct passwd *passwd;
fstr_sprintf(dom_user, "%s%s%s", domain, lp_winbind_separator(),
username);
- passwd = Get_Pwnam(dom_user);
-
- if ( passwd ) {
- char *p;
-
- /* make sure we get the case of the username correct */
- /* work around 'winbind use default domain = yes' */
-
- p = strchr( passwd->pw_name, *lp_winbind_separator() );
- if ( !p )
- fstr_sprintf(dom_user, "%s%s%s", domain,
- lp_winbind_separator(), passwd->pw_name);
- else
- fstrcpy( dom_user, passwd->pw_name );
- }
- else {
- /* if the lookup for DOMAIN\username failed, try again
- with just 'username'. This is need for accessing the server
- as a trust user that actually maps to a local account */
-
- fstrcpy( dom_user, username );
- passwd = Get_Pwnam( dom_user );
-
- /* make sure we get the case of the username correct */
- if ( passwd )
- fstrcpy( dom_user, passwd->pw_name );
- }
+ /* get the passwd struct but don't create the user if he/she
+ does not exist. We were explicitly called from a following
+ a winbindd authentication request so we should assume that
+ nss_winbindd is working */
- if ( !passwd )
+ if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) )
return NT_STATUS_NO_SUCH_USER;
*uid = passwd->pw_uid;
*gid = passwd->pw_gid;
- /* This is pointless -- there is no suport for differeing
+ /* This is pointless -- there is no suport for differing
unix and windows names. Make sure to always store the
one we actually looked up and succeeded. Have I mentioned
why I hate the 'winbind use default domain' parameter?
--jerry */
- *found_username = talloc_strdup(mem_ctx, dom_user);
+ *found_username = talloc_strdup( mem_ctx, real_username );
DEBUG(5,("fill_sam_account: located username was [%s]\n",
*found_username));
@@ -983,40 +968,72 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
the username if we fallback to the username only.
****************************************************************************/
-struct passwd *smb_getpwnam( char *domuser )
+struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create )
{
struct passwd *pw = NULL;
char *p;
fstring mapped_username;
+
+ /* we only save a copy of the username it has been mangled
+ by winbindd use default domain */
+
+ save_username[0] = '\0';
+
+ /* save a local copy of the username and run it through the
+ username map */
+
+ fstrcpy( mapped_username, domuser );
+ map_username( mapped_username );
+
+ p = strchr_m( mapped_username, *lp_winbind_separator() );
+
+ /* code for a DOMAIN\user string */
+
+ if ( p ) {
+ pw = Get_Pwnam( domuser );
+ if ( pw ) {
+ /* make sure we get the case of the username correct */
+ /* work around 'winbind use default domain = yes' */
- pw = Get_Pwnam( domuser );
- if ( pw )
- return pw;
-
- /* fallback to looking up just the username */
+ if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
+ char *domain;
+
+ domain = mapped_username;
+ *p = '\0';
+ fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
+ }
+ else
+ fstrcpy( save_username, pw->pw_name );
- p = strchr( domuser, *lp_winbind_separator() );
+ /* whew -- done! */
+ return pw;
+ }
- if ( p ) {
- p += 1;
+ /* setup for lookup of just the username */
+ p++;
fstrcpy( mapped_username, p );
- map_username( mapped_username );
+
+ }
+
+ /* just lookup a plain username */
+
+ pw = Get_Pwnam(mapped_username);
+
+ /* Create local user if requested. */
+
+ if ( !pw && create ) {
+ /* Don't add a machine account. */
+ if (mapped_username[strlen(mapped_username)-1] == '$')
+ return NULL;
+
+ auth_add_user_script(NULL, mapped_username);
pw = Get_Pwnam(mapped_username);
- if (!pw) {
- /* Don't add a machine account. */
- if (mapped_username[strlen(mapped_username)-1] == '$')
- return NULL;
-
- /* Create local user if requested. */
- p = strchr( mapped_username, *lp_winbind_separator() );
- if (p)
- p += 1;
- else
- p = mapped_username;
- auth_add_user_script(NULL, p);
- return Get_Pwnam(p);
- }
}
+
+ /* one last check for a valid passwd struct */
+
+ if ( pw )
+ fstrcpy( save_username, pw->pw_name );
return pw;
}
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index c42a35e809c..d91aa947286 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -143,7 +143,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
DATA_BLOB ticket;
char *client, *p, *domain;
fstring netbios_domain_name;
- const struct passwd *pw;
+ struct passwd *pw;
char *user;
int sess_vuid;
NTSTATUS ret;
@@ -154,6 +154,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
uint8 tok_id[2];
BOOL foreign = False;
DATA_BLOB nullblob = data_blob(NULL, 0);
+ fstring real_username;
ZERO_STRUCT(ticket);
ZERO_STRUCT(auth_data);
@@ -239,7 +240,9 @@ static int reply_spnego_kerberos(connection_struct *conn,
asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client);
- pw = smb_getpwnam( user );
+ /* lookup the passwd struct, create a new user if necessary */
+
+ pw = smb_getpwnam( user, real_username, True );
if (!pw) {
DEBUG(1,("Username %s is invalid on this system\n",user));
@@ -251,10 +254,11 @@ static int reply_spnego_kerberos(connection_struct *conn,
/* setup the string used by %U */
- sub_set_smb_name(pw->pw_name);
+ sub_set_smb_name( real_username );
reload_services(True);
- if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) {
+ if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw)))
+ {
DEBUG(1,("make_server_info_from_pw failed!\n"));
SAFE_FREE(user);
SAFE_FREE(client);