1 /* Copyright 2003-2008 Wang, Chun-Pin All rights reserved. */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <syslog.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <strings.h>
9 
10 #include "smbftpd.h"
11 
12 static smbftpd_text_user_t usercache;
13 static char *confpath;
14 
15 /**
16  * Parse config file. Do nothing here
17  *
18  * @param path
19  *
20  * @return 0: Success
21  *         -1: Failed
22  */
auth_text_config_parse(const char * path)23 int auth_text_config_parse(const char *path)
24 {
25 	if (!path) {
26 		return -1;
27 	}
28 	confpath = strdup(path);
29 	if (!confpath) {
30 		return -1;
31 	}
32 
33 	return 0;
34 }
35 
36 
37 /**
38  * Perform authentication by getting user and password from the text use
39  * file.
40  *
41  * It will:
42  * 1. Get password from text user file according to given username.
43  * 3. Encrypt the password and compare with password in text file.
44  * 4. Cache the user's group and home directory
45  *
46  * @param user     The login user
47  * @param password The login password
48  *
49  * @return 0: Authentication success.
50  *         -1: Failed to auth
51  */
auth_text_check(const char * user,const char * password)52 int auth_text_check(const char *user, const char *password)
53 {
54 	char *crypted = NULL;
55 	int error = -1;
56 
57 	smbftpd_text_user_free(&usercache);
58 
59 	if (0 != smbftpd_text_user_get(confpath, user, &usercache)) {
60 		return -1;
61 	}
62 
63 	crypted = crypt(password, usercache.password);
64 	if (!crypted) {
65 		goto Error;
66 	}
67 
68 	if (strcmp(crypted, usercache.password) != 0) {
69 		goto Error;
70 	}
71 
72 	error = 0;
73 Error:
74 	if (usercache.password) {
75 		/* Remove password from cache for security */
76 		free(usercache.password);
77 		usercache.password = NULL;
78 	}
79 	return error;
80 }
81 
82 /**
83  * Free config path and user cache
84  */
auth_text_config_free()85 void auth_text_config_free()
86 {
87 	if (confpath) {
88 		free(confpath);
89 		confpath = NULL;
90 	}
91 	smbftpd_text_user_free(&usercache);
92 }
93 
94 /**
95  * Check whether user belongs to given group.
96  *
97  * We support only 1 group per user.
98  *
99  * We will check the user in cache, if given user is the same with
100  * the user in cache, we will compare the group with cached group.
101  *
102  * If user is not in cache, we will query file to get the group.
103  *
104  * @param user   User to check
105  * @param group  Group name to check
106  *
107  * @return 1: Yes, user belongs to the group
108  *         0: No, user does not belongs to the group or failed to query database
109  */
auth_text_is_user_in_group(const char * user,const char * group)110 int auth_text_is_user_in_group(const char *user, const char *group)
111 {
112 	smbftpd_text_user_t smbftpd_user;
113 	int error = 0;
114 
115 	if (!group || !user) {
116 		return 0;
117 	}
118 
119 	if (usercache.user && usercache.group) {
120 		if (strcmp(user, usercache.user) == 0) {
121 			if (strcmp(group, usercache.group) == 0) {
122 				return 1;
123 			} else {
124 				return 0;
125 			}
126 		}
127 	}
128 
129 	bzero(&smbftpd_user, sizeof(smbftpd_user));
130 	if (0 != smbftpd_text_user_get(confpath, user, &smbftpd_user)) {
131 		return 0;
132 	}
133 	if (strcmp(smbftpd_user.group, group) == 0) {
134 		error = 1;
135 	}
136 
137 	smbftpd_text_user_free(&smbftpd_user);
138 
139 	return error;
140 }
141 
142 /**
143  * Get user's home directory. If user is current logged in user, we will
144  * return the home directory in cache. If user is not current logged in
145  * user, we will get text file for the user's home.
146  *
147  * Caller should call free() to free the point.
148  *
149  * @param user   User name
150  *
151  * @return A pointer to the string if user found. If not found, return NULL.
152  *         Caller should call free() to free the point.
153  */
auth_text_get_home(const char * user)154 char *auth_text_get_home(const char *user)
155 {
156 	smbftpd_text_user_t smbftpd_user;
157 	char *home = NULL;
158 
159 	if (!user) {
160 		return NULL;
161 	}
162 
163 	if (usercache.user && usercache.home) {
164 		if (strcmp(user, usercache.user) == 0) {
165 			return strdup(usercache.home);
166 		}
167 	}
168 
169 	bzero(&smbftpd_user, sizeof(smbftpd_user));
170 	if (0 != smbftpd_text_user_get(confpath, user, &smbftpd_user)) {
171 		return NULL;
172 	}
173 
174 	home = strdup(smbftpd_user.home);
175 
176 	smbftpd_text_user_free(&smbftpd_user);
177 
178 	return home;
179 }
180