s3:utils: let smbstatus report anonymous signing/encryption explicitly
[samba.git] / source3 / libsmb / libsmb_compat.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB client library implementation (Old interface compatibility)
4    Copyright (C) Andrew Tridgell 1998
5    Copyright (C) Richard Sharpe 2000
6    Copyright (C) John Terpstra 2000
7    Copyright (C) Tom Jansen (Ninja ISD) 2002
8    Copyright (C) Derrell Lipman 2003, 2008
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24
25 #include "includes.h"
26 #include "libsmb_internal.h"
27
28 struct smbc_compat_fdlist {
29         SMBCFILE * file;
30         int fd;
31         struct smbc_compat_fdlist *next, *prev;
32 };
33
34 static SMBCCTX * statcont = NULL;
35 static int smbc_compat_initialized = 0;
36 static int smbc_compat_nextfd = 0;
37 static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL;
38 static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL;
39
40 /* Find an fd and return the SMBCFILE * or NULL on failure */
41 static SMBCFILE *
42 find_fd(int fd)
43 {
44         struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
45         while (f) {
46                 if (f->fd == fd)
47                         return f->file;
48                 f = f->next;
49         }
50         return NULL;
51 }
52
53 /* Add an fd, returns 0 on success, -1 on error with errno set */
54 static int
55 add_fd(SMBCFILE * file)
56 {
57         struct smbc_compat_fdlist * f = smbc_compat_fd_avail;
58
59         if (f) {
60                 /* We found one that's available */
61                 DLIST_REMOVE(smbc_compat_fd_avail, f);
62         } else {
63                 /*
64                  * None were available, so allocate one.  Keep the number of
65                  * file descriptors determinate.  This allows the application
66                  * to allocate bitmaps or mapping of file descriptors based on
67                  * a known maximum number of file descriptors that will ever
68                  * be returned.
69                  */
70                 if (smbc_compat_nextfd >= FD_SETSIZE) {
71                         errno = EMFILE;
72                         return -1;
73                 }
74
75                 f = SMB_MALLOC_P(struct smbc_compat_fdlist);
76                 if (!f) {
77                         errno = ENOMEM;
78                         return -1;
79                 }
80
81                 f->fd = SMBC_BASE_FD + smbc_compat_nextfd++;
82         }
83
84         f->file = file;
85         DLIST_ADD(smbc_compat_fd_in_use, f);
86
87         return f->fd;
88 }
89
90
91
92 /* Delete an fd, returns 0 on success */
93 static int
94 del_fd(int fd)
95 {
96         struct smbc_compat_fdlist * f = smbc_compat_fd_in_use;
97
98         while (f) {
99                 if (f->fd == fd)
100                         break;
101                 f = f->next;
102         }
103
104         if (f) {
105                 /* found */
106                 DLIST_REMOVE(smbc_compat_fd_in_use, f);
107                 f->file = NULL;
108                 DLIST_ADD(smbc_compat_fd_avail, f);
109                 return 0;
110         }
111         return 1;
112 }
113
114
115
116 int
117 smbc_init(smbc_get_auth_data_fn fn,
118           int debug)
119 {
120         if (smbc_compat_initialized) {
121                 return 0;
122         }
123
124         statcont = smbc_new_context();
125         if (!statcont)
126                 return -1;
127
128         smbc_setDebug(statcont, debug);
129         smbc_setFunctionAuthData(statcont, fn);
130
131         if (!smbc_init_context(statcont)) {
132                 smbc_free_context(statcont, False);
133                 return -1;
134         }
135
136         smbc_compat_initialized = 1;
137
138         return 0;
139 }
140
141
142 SMBCCTX *
143 smbc_set_context(SMBCCTX * context)
144 {
145         SMBCCTX *old_context = statcont;
146
147         if (context) {
148                 /* Save provided context.  It must have been initialized! */
149                 statcont = context;
150
151                 /* You'd better know what you're doing.  We won't help you. */
152                 smbc_compat_initialized = 1;
153         }
154
155         return old_context;
156 }
157
158
159 int
160 smbc_open(const char *furl,
161           int flags,
162           mode_t mode)
163 {
164         SMBCFILE * file;
165         int fd;
166
167         file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode);
168         if (!file)
169                 return -1;
170
171         fd = add_fd(file);
172         if (fd == -1)
173                 smbc_getFunctionClose(statcont)(statcont, file);
174         return fd;
175 }
176
177
178 int
179 smbc_creat(const char *furl,
180            mode_t mode)
181 {
182         SMBCFILE * file;
183         int fd;
184
185         file = smbc_getFunctionCreat(statcont)(statcont, furl, mode);
186         if (!file)
187                 return -1;
188
189         fd = add_fd(file);
190         if (fd == -1) {
191                 /* Hmm... should we delete the file too ? I guess we could try */
192                 smbc_getFunctionClose(statcont)(statcont, file);
193                 smbc_getFunctionUnlink(statcont)(statcont, furl);
194         }
195         return fd;
196 }
197
198
199 ssize_t
200 smbc_read(int fd,
201           void *buf,
202           size_t bufsize)
203 {
204         SMBCFILE * file = find_fd(fd);
205         return smbc_getFunctionRead(statcont)(statcont, file, buf, bufsize);
206 }
207
208 ssize_t
209 smbc_write(int fd,
210            const void *buf,
211            size_t bufsize)
212 {
213         SMBCFILE * file = find_fd(fd);
214         return smbc_getFunctionWrite(statcont)(statcont, file, buf, bufsize);
215 }
216
217 off_t
218 smbc_lseek(int fd,
219            off_t offset,
220            int whence)
221 {
222         SMBCFILE * file = find_fd(fd);
223         return smbc_getFunctionLseek(statcont)(statcont, file, offset, whence);
224 }
225
226 int
227 smbc_close(int fd)
228 {
229         SMBCFILE * file = find_fd(fd);
230         del_fd(fd);
231         return smbc_getFunctionClose(statcont)(statcont, file);
232 }
233
234 int
235 smbc_unlink(const char *fname)
236 {
237         return smbc_getFunctionUnlink(statcont)(statcont, fname);
238 }
239
240 int
241 smbc_rename(const char *ourl,
242             const char *nurl)
243 {
244         return smbc_getFunctionRename(statcont)(statcont, ourl,
245                                                 statcont, nurl);
246 }
247
248 int
249 smbc_opendir(const char *durl)
250 {
251         SMBCFILE * file;
252         int fd;
253
254         file = smbc_getFunctionOpendir(statcont)(statcont, durl);
255         if (!file)
256                 return -1;
257
258         fd = add_fd(file);
259         if (fd == -1)
260                 smbc_getFunctionClosedir(statcont)(statcont, file);
261
262         return fd;
263 }
264
265 int
266 smbc_closedir(int dh)
267 {
268         SMBCFILE * file = find_fd(dh);
269         del_fd(dh);
270         return smbc_getFunctionClosedir(statcont)(statcont, file);
271 }
272
273 int
274 smbc_getdents(unsigned int dh,
275               struct smbc_dirent *dirp,
276               int count)
277 {
278         SMBCFILE * file = find_fd(dh);
279         return smbc_getFunctionGetdents(statcont)(statcont, file, dirp, count);
280 }
281
282 struct smbc_dirent *
283 smbc_readdir(unsigned int dh)
284 {
285         SMBCFILE * file = find_fd(dh);
286         return smbc_getFunctionReaddir(statcont)(statcont, file);
287 }
288
289 const struct libsmb_file_info *smbc_readdirplus(unsigned int dh)
290 {
291         SMBCFILE * file = find_fd(dh);
292         return smbc_getFunctionReaddirPlus(statcont)(statcont, file);
293 }
294
295 const struct libsmb_file_info *smbc_readdirplus2(unsigned int dh,
296                 struct stat *st)
297 {
298         SMBCFILE *file = find_fd(dh);
299         return smbc_getFunctionReaddirPlus2(statcont)(statcont, file, st);
300 }
301
302 off_t
303 smbc_telldir(int dh)
304 {
305         SMBCFILE * file = find_fd(dh);
306         return smbc_getFunctionTelldir(statcont)(statcont, file);
307 }
308
309 int
310 smbc_lseekdir(int fd,
311               off_t offset)
312 {
313         SMBCFILE * file = find_fd(fd);
314         return smbc_getFunctionLseekdir(statcont)(statcont, file, offset);
315 }
316
317 int
318 smbc_mkdir(const char *durl,
319            mode_t mode)
320 {
321         return smbc_getFunctionMkdir(statcont)(statcont, durl, mode);
322 }
323
324 int
325 smbc_rmdir(const char *durl)
326 {
327         return smbc_getFunctionRmdir(statcont)(statcont, durl);
328 }
329
330 int
331 smbc_notify(int dh, smbc_bool recursive, uint32_t completion_filter,
332             unsigned callback_timeout_ms,
333             smbc_notify_callback_fn cb, void *private_data)
334 {
335         SMBCFILE *dir = find_fd(dh);
336         return smbc_getFunctionNotify(statcont)(
337                 statcont, dir, recursive, completion_filter,
338                 callback_timeout_ms, cb, private_data);
339 }
340
341 int
342 smbc_stat(const char *url,
343           struct stat *st)
344 {
345         return smbc_getFunctionStat(statcont)(statcont, url, st);
346 }
347
348 int
349 smbc_fstat(int fd,
350            struct stat *st)
351 {
352         SMBCFILE * file = find_fd(fd);
353         return smbc_getFunctionFstat(statcont)(statcont, file, st);
354 }
355
356 int
357 smbc_statvfs(char *path,
358              struct statvfs *st)
359 {
360         return smbc_getFunctionStatVFS(statcont)(statcont, path, st);
361 }
362
363 int
364 smbc_fstatvfs(int fd,
365               struct statvfs *st)
366 {
367         SMBCFILE * file = find_fd(fd);
368         return smbc_getFunctionFstatVFS(statcont)(statcont, file, st);
369 }
370
371 int
372 smbc_ftruncate(int fd,
373                off_t size)
374 {
375         SMBCFILE * file = find_fd(fd);
376         return smbc_getFunctionFtruncate(statcont)(statcont, file, size);
377 }
378
379 int
380 smbc_chmod(const char *url,
381            mode_t mode)
382 {
383         return smbc_getFunctionChmod(statcont)(statcont, url, mode);
384 }
385
386 int
387 smbc_utimes(const char *fname,
388             struct timeval *tbuf)
389 {
390         return smbc_getFunctionUtimes(statcont)(statcont, fname, tbuf);
391 }
392
393 #ifdef HAVE_UTIME_H
394 int
395 smbc_utime(const char *fname,
396            struct utimbuf *utbuf)
397 {
398         struct timeval tv[2];
399
400         if (utbuf == NULL)
401                 return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL);
402
403         tv[0].tv_sec = utbuf->actime;
404         tv[1].tv_sec = utbuf->modtime;
405         tv[0].tv_usec = tv[1].tv_usec = 0;
406
407         return smbc_getFunctionUtimes(statcont)(statcont, fname, tv);
408 }
409 #endif
410
411 int
412 smbc_setxattr(const char *fname,
413               const char *name,
414               const void *value,
415               size_t size,
416               int flags)
417 {
418         return smbc_getFunctionSetxattr(statcont)(statcont,
419                                                   fname, name,
420                                                   value, size, flags);
421 }
422
423 int
424 smbc_lsetxattr(const char *fname,
425                const char *name,
426                const void *value,
427                size_t size,
428                int flags)
429 {
430         return smbc_getFunctionSetxattr(statcont)(statcont,
431                                                   fname, name,
432                                                   value, size, flags);
433 }
434
435 int
436 smbc_fsetxattr(int fd,
437                const char *name,
438                const void *value,
439                size_t size,
440                int flags)
441 {
442         SMBCFILE * file = find_fd(fd);
443         if (file == NULL) {
444                 errno = EBADF;
445                 return -1;
446         }
447         return smbc_getFunctionSetxattr(statcont)(statcont,
448                                                   file->fname, name,
449                                                   value, size, flags);
450 }
451
452 int
453 smbc_getxattr(const char *fname,
454               const char *name,
455               const void *value,
456               size_t size)
457 {
458         return smbc_getFunctionGetxattr(statcont)(statcont,
459                                                   fname, name,
460                                                   value, size);
461 }
462
463 int
464 smbc_lgetxattr(const char *fname,
465                const char *name,
466                const void *value,
467                size_t size)
468 {
469         return smbc_getFunctionGetxattr(statcont)(statcont,
470                                                   fname, name,
471                                                   value, size);
472 }
473
474 int
475 smbc_fgetxattr(int fd,
476                const char *name,
477                const void *value,
478                size_t size)
479 {
480         SMBCFILE * file = find_fd(fd);
481         if (file == NULL) {
482                 errno = EBADF;
483                 return -1;
484         }
485         return smbc_getFunctionGetxattr(statcont)(statcont,
486                                                   file->fname, name,
487                                                   value, size);
488 }
489
490 int
491 smbc_removexattr(const char *fname,
492                  const char *name)
493 {
494         return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
495 }
496
497 int
498 smbc_lremovexattr(const char *fname,
499                   const char *name)
500 {
501         return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name);
502 }
503
504 int
505 smbc_fremovexattr(int fd,
506                   const char *name)
507 {
508         SMBCFILE * file = find_fd(fd);
509         if (file == NULL) {
510                 errno = EBADF;
511                 return -1;
512         }
513         return smbc_getFunctionRemovexattr(statcont)(statcont,
514                                                      file->fname, name);
515 }
516
517 int
518 smbc_listxattr(const char *fname,
519                char *list,
520                size_t size)
521 {
522         return smbc_getFunctionListxattr(statcont)(statcont,
523                                                    fname, list, size);
524 }
525
526 int
527 smbc_llistxattr(const char *fname,
528                 char *list,
529                 size_t size)
530 {
531         return smbc_getFunctionListxattr(statcont)(statcont,
532                                                    fname, list, size);
533 }
534
535 int
536 smbc_flistxattr(int fd,
537                 char *list,
538                 size_t size)
539 {
540         SMBCFILE * file = find_fd(fd);
541         if (file == NULL) {
542                 errno = EBADF;
543                 return -1;
544         }
545         return smbc_getFunctionListxattr(statcont)(statcont,
546                                                    file->fname, list, size);
547 }
548
549 int
550 smbc_print_file(const char *fname,
551                 const char *printq)
552 {
553         return smbc_getFunctionPrintFile(statcont)(statcont, fname,
554                                                    statcont, printq);
555 }
556
557 int
558 smbc_open_print_job(const char *fname)
559 {
560         SMBCFILE * file;
561
562         file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname);
563         if (!file) return -1;
564         return file->cli_fd;
565 }
566
567 int
568 smbc_list_print_jobs(const char *purl,
569                      smbc_list_print_job_fn fn)
570 {
571         return smbc_getFunctionListPrintJobs(statcont)(statcont, purl, fn);
572 }
573
574 int
575 smbc_unlink_print_job(const char *purl,
576                       int id)
577 {
578         return smbc_getFunctionUnlinkPrintJob(statcont)(statcont, purl, id);
579 }
580
581