1967c32b9a16d694f15404a3377ce11e8fc77be9
[samba.git] / source3 / auth / auth_util.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Authentication utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6    Copyright (C) Andrew Bartlett 2001
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 /* Data to do lanman1/2 password challenge. */
27 static unsigned char saved_challenge[8];
28 static BOOL challenge_sent=False;
29
30 /*******************************************************************
31 Get the next challenge value - no repeats.
32 ********************************************************************/
33 void generate_next_challenge(char *challenge)
34 {
35         unsigned char buf[8];
36
37         generate_random_buffer(buf,8,False);
38         memcpy(saved_challenge, buf, 8);
39         memcpy(challenge,buf,8);
40         challenge_sent = True;
41 }
42
43 /*******************************************************************
44 set the last challenge sent, usually from a password server
45 ********************************************************************/
46 BOOL set_challenge(unsigned char *challenge)
47 {
48         memcpy(saved_challenge,challenge,8);
49         challenge_sent = True;
50         return(True);
51 }
52
53 /*******************************************************************
54 get the last challenge sent
55 ********************************************************************/
56 BOOL last_challenge(unsigned char *challenge)
57 {
58         if (!challenge_sent) return(False);
59         memcpy(challenge,saved_challenge,8);
60         return(True);
61 }
62
63
64 /****************************************************************************
65  Create a UNIX user on demand.
66 ****************************************************************************/
67
68 static int smb_create_user(char *unix_user, char *homedir)
69 {
70         pstring add_script;
71         int ret;
72
73         pstrcpy(add_script, lp_adduser_script());
74         if (! *add_script) return -1;
75         all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
76         if (homedir)
77                 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
78         ret = smbrun(add_script,NULL);
79         DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
80         return ret;
81 }
82
83 /****************************************************************************
84  Delete a UNIX user on demand.
85 ****************************************************************************/
86
87 static int smb_delete_user(char *unix_user)
88 {
89         pstring del_script;
90         int ret;
91
92         pstrcpy(del_script, lp_deluser_script());
93         if (! *del_script) return -1;
94         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
95         ret = smbrun(del_script,NULL);
96         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
97         return ret;
98 }
99
100 /****************************************************************************
101  Add and Delete UNIX users on demand, based on NTSTATUS codes.
102 ****************************************************************************/
103
104 void smb_user_control(char *unix_user, NTSTATUS nt_status) 
105 {
106         struct passwd *pwd=NULL;
107
108         if (NT_STATUS_IS_OK(nt_status)) {
109                 /*
110                  * User validated ok against Domain controller.
111                  * If the admin wants us to try and create a UNIX
112                  * user on the fly, do so.
113                  */
114                 if(lp_adduser_script() && !(pwd = smb_getpwnam(unix_user,True)))
115                         smb_create_user(unix_user, NULL);
116
117                 if(lp_adduser_script() && pwd) {
118                         SMB_STRUCT_STAT st;
119
120                         /*
121                          * Also call smb_create_user if the users home directory
122                          * doesn't exist. Used with winbindd to allow the script to
123                          * create the home directory for a user mapped with winbindd.
124                          */
125
126                         if (pwd->pw_dir && (sys_stat(pwd->pw_dir, &st) == -1) && (errno == ENOENT))
127                                 smb_create_user(unix_user, pwd->pw_dir);
128                 }
129
130         } else if (NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_NO_SUCH_USER)) {
131                 /*
132                  * User failed to validate ok against Domain controller.
133                  * If the failure was "user doesn't exist" and admin 
134                  * wants us to try and delete that UNIX user on the fly,
135                  * do so.
136                  */
137                 if(lp_deluser_script() && smb_getpwnam(unix_user,True))
138                         smb_delete_user(unix_user);
139         }
140 }