11 #include <sys/socket.h>
28 #define MAP_ANONYMOUS MAP_ANON
31 #define SMB_CONN_PROCESS_STATE_UNKNOWN -1
32 #define SMB_CONN_PROCESS_STATE_ALIVE 0
33 #define SMB_CONN_PROCESS_STATE_DIED 1
83 if (count < 0)
return 0;
84 DPRINTF(7,
"count=%d\n", count);
94 if (count < 3)
return 0;
95 DPRINTF(7,
"count=%d\n", count);
105 if (timeout < 10)
return 0;
106 DPRINTF(7,
"timeout=%d\n", timeout);
143 if ((ssize_t) shmem_size < getpagesize())
return -1;
146 pthread_mutex_init(&
ctx->
mutex, NULL);
152 PROT_READ | PROT_WRITE,
173 if (result == 0) pthread_mutex_destroy(&
ctx->
mutex);
178 const char *user,
const char *password){
184 if ((ctx == NULL) || (ctx->
conn_fd == -1))
return -1;
186 iov[0].iov_base = &header;
187 iov[0].iov_len =
sizeof(header);
188 iov[1].iov_base = &data;
189 iov[1].iov_len =
sizeof(data);
190 iov[2].iov_base = (
char*) domain;
191 iov[2].iov_len = strlen(domain) + 1;
192 iov[3].iov_base = (
char*) user;
193 iov[3].iov_len = strlen(user) + 1;
194 iov[4].iov_base = (
char*) password;
195 iov[4].iov_len = strlen(password) + 1;
197 header.
query_len = iov[0].iov_len + iov[1].iov_len +
198 iov[2].iov_len + iov[3].iov_len + iov[4].iov_len;
203 data.
password_offs =
sizeof(data) + iov[2].iov_len + iov[3].iov_len;
207 bytes = writev(ctx->
conn_fd, iov, 5);
211 return (bytes == (ssize_t) header.
query_len) ? 0 : -1;
215 const char *server,
const char *share){
217 #ifdef HAVE_LIBSECRET
218 struct libsecret_authinfo *libsecret_info;
221 int config_file_info_suitability;
225 if ((ctx == NULL) || (ctx->
conn_fd == -1))
return -1;
227 memset(workgroup, 0,
sizeof(workgroup));
230 config_file_info_suitability = -1;
232 workgroup, server, share,
233 &config_file_info_suitability);
234 if ((config_file_info != NULL) &&
235 ((config_file_info->
domain == NULL) ||
236 (config_file_info->
user == NULL) ||
237 (config_file_info->
password == NULL))){
239 DPRINTF(0,
"WARNING!!! Damaged authinfo record\n");
241 config_file_info = NULL;
242 config_file_info_suitability = -1;
245 #ifdef HAVE_LIBSECRET
246 libsecret_info = libsecret_get_authinfo(workgroup, server, share);
247 if ((libsecret_info != NULL) &&
248 ((libsecret_info->domain == NULL) ||
249 (libsecret_info->user == NULL) ||
250 (libsecret_info->password == NULL))){
252 DPRINTF(0,
"WARNING!!! Damaged libsecret_info record\n");
253 libsecret_free_authinfo(libsecret_info);
254 libsecret_info = NULL;
257 if (libsecret_info != NULL){
258 if (libsecret_info->suitability >= config_file_info_suitability){
259 if (config_file_info != NULL)
261 config_file_info = NULL;
262 config_file_info_suitability = -1;
263 goto use_libsecret_info;
265 libsecret_free_authinfo(libsecret_info);
266 libsecret_info = NULL;
270 if (config_file_info == NULL)
return -1;
273 config_file_info->
user,
278 #ifdef HAVE_LIBSECRET
281 libsecret_info->domain,
282 libsecret_info->user,
283 libsecret_info->password);
284 libsecret_free_authinfo(libsecret_info);
292 void *query,
size_t query_len,
294 void *reply,
size_t reply_len,
297 int iov_cnt, retval, count;
302 if ((ctx == NULL) || (ctx->
conn_fd == -1) ||
305 ((reply == NULL) && (reply_len != 0)))
return EINVAL;
315 iov[0].iov_base = &query_header;
316 iov[0].iov_len =
sizeof(query_header);
317 iov[1].iov_base = query;
323 str = va_arg(ap,
const char *);
324 if (str == NULL)
break;
325 if (iov_cnt >= (ssize_t) (
sizeof(iov) /
sizeof(
struct iovec))){
330 iov[iov_cnt].iov_base = (
void *) str;
331 iov[iov_cnt].iov_len = strlen(str) + 1;
332 query_header.
query_len += iov[iov_cnt].iov_len;
339 bytes = writev(ctx->
conn_fd, iov, iov_cnt);
340 if (bytes != (ssize_t) query_header.
query_len)
goto error;
344 fd_set readfds, exceptfds;
353 FD_SET(ctx->
conn_fd, &readfds);
356 FD_SET(ctx->
conn_fd, &exceptfds);
359 retval = select(ctx->
conn_fd + 1, &readfds, NULL, &exceptfds, &tv);
360 if ((retval <= 0) || FD_ISSET(ctx->
conn_fd, &exceptfds))
goto error;
368 if ((ssize_t) reply_hdr->
reply_len != bytes)
goto error;
380 if (buf[bytes - 1] !=
'\0' )
goto error;
390 msg = ((
char *) msg_req) + msg_req->
msg_offs;
391 if (bytes != (ssize_t) (strlen(msg) + 1))
goto error;
406 const char *server, *share;
413 if (buf[bytes - 1] !=
'\0' )
goto error;
420 ((ssize_t) passwd_req->
share_offs > bytes - 1))
goto error;
423 server = ((
char *) passwd_req) + passwd_req->
server_offs;
424 share = ((
char *) passwd_req) + passwd_req->
share_offs;
425 if (bytes != (ssize_t) (strlen(server) + strlen(share) + 2))
435 if (reply_hdr->
reply_cmd != query_cmd)
goto error;
455 void *query,
size_t query_len,
477 void *query,
size_t query_len,
484 const char *url = NULL;
487 va_start(ap, reply_len);
488 url = va_arg(ap,
const char *);
500 for(count = 0; ; count++){
503 va_start(ap, reply_len);
531 void *query,
size_t query_len,
532 void *reply,
size_t reply_len){
537 if ((file == NULL) || (file->
url == NULL))
return EINVAL;
539 for(count = 0; ; count++){
542 if (file->
srv_fd == NULL){
552 fd_len =
sizeof(fd_query.open);
554 fd_query.open.url_offs =
sizeof(fd_query.open);
555 fd_query.open.mode = 0664;
556 fd_query.open.flags = file->
reopen_flags & (~(O_CREAT | O_TRUNC));
563 fd_len =
sizeof(fd_query.opendir);
565 fd_query.opendir.url_offs =
sizeof(fd_query.opendir);
577 &fd_reply,
sizeof(fd_reply),
586 *query_fd_ptr = file->
srv_fd;
605 const char *url,
int flags, mode_t mode){
612 file = malloc(
sizeof(
struct smb_conn_file) + strlen(url) + 1);
623 file->
reopen_flags = flags & ~(O_CREAT | O_EXCL | O_TRUNC);
631 pthread_mutex_lock(&ctx->
mutex);
635 &query,
sizeof(query),
636 &reply,
sizeof(reply),
645 pthread_mutex_unlock(&ctx->
mutex);
646 if (error != 0) errno = error;
651 const char *url, mode_t
mode){
658 file = malloc(
sizeof(
struct smb_conn_file) + strlen(url) + 1);
676 pthread_mutex_lock(&ctx->
mutex);
680 &query,
sizeof(query),
681 &reply,
sizeof(reply),
690 pthread_mutex_unlock(&ctx->
mutex);
691 if (error != 0) errno = error;
697 void *buf,
size_t bufsize){
723 &query,
sizeof(query),
724 &reply,
sizeof(reply));
725 if ((error == 0) && (reply.
bufsize <= (ssize_t) bufsize)){
729 if (error == 0) error = EIO;
733 if (error != 0) errno = error;
739 const void *buf,
size_t bufsize){
767 &query,
sizeof(query),
768 &reply,
sizeof(reply));
769 if ((error != 0) || (reply.
bufsize > (ssize_t) bufsize)){
771 if (error == 0) error = EIO;
775 if (error != 0) errno = error;
793 if (file->
srv_fd != NULL){
801 &query,
sizeof(query),
810 pthread_mutex_unlock(&ctx->
mutex);
811 if (error != 0) errno = error;
812 return (error != 0) ? -1 : 0;
821 pthread_mutex_lock(&ctx->
mutex);
825 &query,
sizeof(query),
828 pthread_mutex_unlock(&ctx->
mutex);
843 pthread_mutex_lock(&ctx->
mutex);
847 &query,
sizeof(query),
849 old_url, new_url, NULL);
850 pthread_mutex_unlock(&ctx->
mutex);
866 file = malloc(
sizeof(
struct smb_conn_file) + strlen(url) + 1);
883 pthread_mutex_lock(&ctx->
mutex);
887 &query,
sizeof(query),
888 &reply,
sizeof(reply),
897 pthread_mutex_unlock(&ctx->
mutex);
898 if (error != 0) errno = error;
916 if (file->
srv_fd != NULL){
924 &query,
sizeof(query),
933 pthread_mutex_unlock(&ctx->
mutex);
934 if (error != 0) errno = error;
935 return (error != 0) ? -1 : 0;
952 query.
offset = (off_t) (-1);
975 &query,
sizeof(query),
976 &reply,
sizeof(reply));
985 if (file->
srv_fd == NULL){
994 &query,
sizeof(query),
996 &reply,
sizeof(reply),
1000 if ((error == 0) && (reply.
bufsize <= (ssize_t) bufsize) &&
1006 if (error == 0) error = EIO;
1009 pthread_mutex_unlock(&ctx->
mutex);
1010 if (error != 0) errno = error;
1021 pthread_mutex_lock(&ctx->
mutex);
1025 &query,
sizeof(query),
1028 pthread_mutex_unlock(&ctx->
mutex);
1042 pthread_mutex_lock(&ctx->
mutex);
1046 &query,
sizeof(query),
1049 pthread_mutex_unlock(&ctx->
mutex);
1064 pthread_mutex_lock(&ctx->
mutex);
1068 &query,
sizeof(query),
1069 &reply,
sizeof(reply),
1071 pthread_mutex_unlock(&ctx->
mutex);
1076 memcpy(st, &reply.
stat,
sizeof(
struct stat));
1104 &query,
sizeof(query),
1105 &reply,
sizeof(reply));
1112 memcpy(st, &reply.
stat,
sizeof(
struct stat));
1140 &query,
sizeof(query),
1158 pthread_mutex_lock(&ctx->
mutex);
1162 &query,
sizeof(query),
1165 pthread_mutex_unlock(&ctx->
mutex);
1178 memcpy(&query.
tbuf,
tbuf, 2 *
sizeof(
struct timeval));
1180 pthread_mutex_lock(&ctx->
mutex);
1184 &query,
sizeof(query),
1187 pthread_mutex_unlock(&ctx->
mutex);
1196 const void *value,
size_t size,
int flags){
1211 pthread_mutex_lock(&ctx->
mutex);
1217 &query,
sizeof(query),
1220 pthread_mutex_unlock(&ctx->
mutex);
1229 const char *url,
const char *name,
1230 void *value,
size_t size){
1245 pthread_mutex_lock(&ctx->
mutex);
1249 &query,
sizeof(query),
1250 &reply,
sizeof(reply),
1254 (reply.
bufsize <= (ssize_t) size))
1256 pthread_mutex_unlock(&ctx->
mutex);
1262 ((size > 0) && (reply.
bufsize > (ssize_t) size))){
1271 char *list,
size_t size){
1285 pthread_mutex_lock(&ctx->
mutex);
1289 &query,
sizeof(query),
1290 &reply,
sizeof(reply),
1294 (reply.
bufsize <= (ssize_t) size))
1296 pthread_mutex_unlock(&ctx->
mutex);
1302 ((size > 0) && (reply.
bufsize > (ssize_t) size))){
1310 const char *url,
const char *name){
1318 pthread_mutex_lock(&ctx->
mutex);
1322 &query,
sizeof(query),
1325 pthread_mutex_unlock(&ctx->
mutex);
struct authinfo * auth_get_authinfo(const char *domain, const char *server, const char *share, int *suitability)
void auth_release_authinfo(struct authinfo *info)
#define DEBUG_PRINT(level, fmt, args...)
static int common_get_smbnetfs_debug_level(void)
#define DPRINTF(level, fmt, args...)
static int is_valid_list_elem(LIST *list, LIST *elem)
static void init_list(LIST *list)
static LIST * first_list_elem(LIST *list)
#define list_entry(ptr, type, member)
static int is_list_empty(LIST *list)
static void add_to_list(LIST *list, LIST *elem)
static void remove_from_list(LIST *list, LIST *elem)
int neg_cache_check(const char *url)
int neg_cache_store(const char *url, int errno_value)
void process_kill_by_smb_conn_fd(int fd)
int process_is_smb_conn_alive(int fd)
int process_start_new_smb_conn(char *shmem_ptr, size_t shmem_size)
static int smb_conn_send_password_base(struct smb_conn_ctx *ctx, const char *domain, const char *user, const char *password)
smb_conn_fd smb_conn_creat(struct smb_conn_ctx *ctx, const char *url, mode_t mode)
int smb_conn_closedir(struct smb_conn_ctx *ctx, smb_conn_fd fd)
smb_conn_fd smb_conn_opendir(struct smb_conn_ctx *ctx, const char *url)
#define SMB_CONN_PROCESS_STATE_UNKNOWN
static int smb_conn_get_max_retry_count(void)
ssize_t smb_conn_write(struct smb_conn_ctx *ctx, smb_conn_fd fd, off_t offset, const void *buf, size_t bufsize)
int smb_conn_chmod(struct smb_conn_ctx *ctx, const char *url, mode_t mode)
static int smb_conn_query_result_map(struct smb_conn_query_result *result)
int smb_conn_removexattr(struct smb_conn_ctx *ctx, const char *url, const char *name)
static int smb_conn_process_query_lowlevel(struct smb_conn_ctx *ctx, enum smb_conn_cmd query_cmd, void *query, size_t query_len, struct smb_conn_query_result *result, void *reply, size_t reply_len,...)
static int smb_conn_server_reply_timeout
int smb_conn_fstat(struct smb_conn_ctx *ctx, smb_conn_fd fd, struct stat *st)
int smb_conn_getxattr(struct smb_conn_ctx *ctx, const char *url, const char *name, void *value, size_t size)
int smb_conn_rename(struct smb_conn_ctx *ctx, const char *old_url, const char *new_url)
static int smb_conn_process_query_lowlevel_va(struct smb_conn_ctx *ctx, enum smb_conn_cmd query_cmd, void *query, size_t query_len, struct smb_conn_query_result *result, void *reply, size_t reply_len, va_list ap)
smb_conn_fd smb_conn_open(struct smb_conn_ctx *ctx, const char *url, int flags, mode_t mode)
int smb_conn_close(struct smb_conn_ctx *ctx, smb_conn_fd fd)
int smb_conn_listxattr(struct smb_conn_ctx *ctx, const char *url, char *list, size_t size)
int smb_conn_ctx_destroy(struct smb_conn_ctx *ctx)
static int smb_conn_query_result_check(enum smb_conn_cmd query_cmd, struct smb_conn_query_result *result)
int smb_conn_ftruncate(struct smb_conn_ctx *ctx, smb_conn_fd fd, off_t size)
#define SMB_CONN_PROCESS_STATE_DIED
int smb_conn_ctx_init(struct smb_conn_ctx *ctx, size_t shmem_size)
static int smb_conn_max_retry_count
static void smb_conn_connection_close(struct smb_conn_ctx *ctx)
static int smb_conn_get_server_reply_timeout(void)
static int smb_conn_max_passwd_query_count
ssize_t smb_conn_read(struct smb_conn_ctx *ctx, smb_conn_fd fd, off_t offset, void *buf, size_t bufsize)
static int smb_conn_up_if_broken(struct smb_conn_ctx *ctx)
static int smb_conn_process_fd_query(struct smb_conn_ctx *ctx, enum smb_conn_cmd query_cmd, struct smb_conn_file *file, smb_conn_srv_fd *query_fd_ptr, void *query, size_t query_len, void *reply, size_t reply_len)
ssize_t smb_conn_readdir(struct smb_conn_ctx *ctx, smb_conn_fd fd, void *buf, size_t bufsize)
int smb_conn_set_max_passwd_query_count(int count)
static int smb_conn_is_neg_cache_candidate(enum smb_conn_cmd query_cmd, struct smb_conn_query_result *result)
static int smb_conn_get_max_passwd_query_count(void)
static int smb_conn_send_password(struct smb_conn_ctx *ctx, const char *server, const char *share)
static int smb_conn_process_query(struct smb_conn_ctx *ctx, enum smb_conn_cmd query_cmd, void *query, size_t query_len, void *reply, size_t reply_len,...)
int smb_conn_stat(struct smb_conn_ctx *ctx, const char *url, struct stat *st)
int smb_conn_unlink(struct smb_conn_ctx *ctx, const char *url)
int smb_conn_utimes(struct smb_conn_ctx *ctx, const char *url, struct timeval *tbuf)
int smb_conn_mkdir(struct smb_conn_ctx *ctx, const char *url, mode_t mode)
int smb_conn_rmdir(struct smb_conn_ctx *ctx, const char *url)
int smb_conn_set_max_retry_count(int count)
int smb_conn_set_server_reply_timeout(int timeout)
#define SMB_CONN_PROCESS_STATE_ALIVE
int smb_conn_setxattr(struct smb_conn_ctx *ctx, const char *url, const char *name, const void *value, size_t size, int flags)
int smbitem_get_group(const char *host, char *buf, size_t size)
struct smb_conn_ctx * ctx
enum smb_conn_cmd reopen_cmd
enum smb_conn_cmd query_cmd
enum smb_conn_cmd reply_cmd