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