mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
765daab643
1. Fix a crash bug which should have reared its ugly head ages ago, but for
some reason, remained dormant until recently. The bug pertained to
libsmbclient doing a structure assignment of a cli after having opened a
pipe. The pipe open code makes a copy of the cli pointer that was passed
to it. If the cli is later copied (and that cli pointer that was saved
is no longer valid), the pipe code will cause a crash during shutdown or
when the copied cli is closed.
2. The 'type' field in enumerated shares was not being set correctly with
the new RPC-based mechanism for enumerating shares.
(This used to be commit 62a02b8f2a
)
215 lines
5.0 KiB
C
215 lines
5.0 KiB
C
/*
|
|
* Alternate testbrowse utility provided by Mikhail Kshevetskiy.
|
|
* This version tests use of multiple contexts.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
#include <libsmbclient.h>
|
|
|
|
int debuglevel = 0;
|
|
char *workgroup = "NT";
|
|
char *username = "guest";
|
|
char *password = "";
|
|
|
|
typedef struct smbitem smbitem;
|
|
typedef int(*qsort_cmp)(const void *, const void *);
|
|
|
|
struct smbitem{
|
|
smbitem *next;
|
|
int type;
|
|
char name[1];
|
|
};
|
|
|
|
int smbitem_cmp(smbitem *elem1, smbitem *elem2){
|
|
return strcmp(elem1->name, elem2->name);
|
|
}
|
|
|
|
int smbitem_list_count(smbitem *list){
|
|
int count = 0;
|
|
|
|
while(list != NULL){
|
|
list = list->next;
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
void smbitem_list_delete(smbitem *list){
|
|
smbitem *elem;
|
|
|
|
while(list != NULL){
|
|
elem = list;
|
|
list = list->next;
|
|
free(elem);
|
|
}
|
|
}
|
|
|
|
smbitem* smbitem_list_sort(smbitem *list){
|
|
smbitem *item, **array;
|
|
int count, i;
|
|
|
|
if ((count = smbitem_list_count(list)) == 0) return NULL;
|
|
if ((array = malloc(count * sizeof(smbitem*))) == NULL){
|
|
smbitem_list_delete(list);
|
|
return NULL;
|
|
}
|
|
|
|
for(i = 0; i < count; i++){
|
|
array[i] = list;
|
|
list = list->next;
|
|
}
|
|
qsort(array, count, sizeof(smbitem*), (qsort_cmp)smbitem_cmp);
|
|
|
|
for(i = 0; i < count - 1; i++) array[i]->next = array[i + 1];
|
|
array[count - 1]->next = NULL;
|
|
|
|
list = array[0];
|
|
free(array);
|
|
return list;
|
|
}
|
|
|
|
void smbc_auth_fn(
|
|
const char *server,
|
|
const char *share,
|
|
char *wrkgrp, int wrkgrplen,
|
|
char *user, int userlen,
|
|
char *passwd, int passwdlen){
|
|
|
|
(void) server;
|
|
(void) share;
|
|
(void) wrkgrp;
|
|
(void) wrkgrplen;
|
|
|
|
strncpy(wrkgrp, workgroup, wrkgrplen - 1); wrkgrp[wrkgrplen - 1] = 0;
|
|
strncpy(user, username, userlen - 1); user[userlen - 1] = 0;
|
|
strncpy(passwd, password, passwdlen - 1); passwd[passwdlen - 1] = 0;
|
|
}
|
|
|
|
SMBCCTX* create_smbctx(){
|
|
SMBCCTX *ctx;
|
|
|
|
if ((ctx = smbc_new_context()) == NULL) return NULL;
|
|
|
|
ctx->debug = debuglevel;
|
|
ctx->callbacks.auth_fn = smbc_auth_fn;
|
|
|
|
if (smbc_init_context(ctx) == NULL){
|
|
smbc_free_context(ctx, 1);
|
|
return NULL;
|
|
}
|
|
|
|
return ctx;
|
|
}
|
|
|
|
void delete_smbctx(SMBCCTX* ctx){
|
|
ctx->callbacks.purge_cached_fn(ctx);
|
|
smbc_free_context(ctx, 1);
|
|
}
|
|
|
|
smbitem* get_smbitem_list(SMBCCTX *ctx, char *smb_path){
|
|
SMBCFILE *fd;
|
|
struct smbc_dirent *dirent;
|
|
smbitem *list = NULL, *item;
|
|
|
|
if ((fd = ctx->opendir(ctx, smb_path)) == NULL) return NULL;
|
|
while((dirent = ctx->readdir(ctx, fd)) != NULL){
|
|
if (strcmp(dirent->name, "") == 0) continue;
|
|
if (strcmp(dirent->name, ".") == 0) continue;
|
|
if (strcmp(dirent->name, "..") == 0) continue;
|
|
|
|
if ((item = malloc(sizeof(smbitem) + strlen(dirent->name))) == NULL)
|
|
continue;
|
|
|
|
item->next = list;
|
|
item->type = dirent->smbc_type;
|
|
strcpy(item->name, dirent->name);
|
|
list = item;
|
|
}
|
|
ctx->close_fn(ctx, fd);
|
|
return /* smbitem_list_sort */ (list);
|
|
|
|
}
|
|
|
|
void print_smb_path(char *group, char *path){
|
|
if ((strlen(group) == 0) && (strlen(path) == 0)) printf("/\n");
|
|
else if (strlen(path) == 0) printf("/%s\n", group);
|
|
else{
|
|
if (strlen(group) == 0) group = "(unknown_group)";
|
|
printf("/%s/%s\n", group, path);
|
|
}
|
|
}
|
|
|
|
void recurse(SMBCCTX *ctx, char *smb_group, char *smb_path, int maxlen){
|
|
int len;
|
|
smbitem *list, *item;
|
|
SMBCCTX *ctx1;
|
|
|
|
len = strlen(smb_path);
|
|
|
|
list = get_smbitem_list(ctx, smb_path);
|
|
while(list != NULL){
|
|
switch(list->type){
|
|
case SMBC_WORKGROUP:
|
|
case SMBC_SERVER:
|
|
if (list->type == SMBC_WORKGROUP){
|
|
print_smb_path(list->name, "");
|
|
smb_group = list->name;
|
|
}
|
|
else print_smb_path(smb_group, list->name);
|
|
|
|
if (maxlen < 7 + strlen(list->name)) break;
|
|
strcpy(smb_path + 6, list->name);
|
|
if ((ctx1 = create_smbctx()) != NULL){
|
|
recurse(ctx1, smb_group, smb_path, maxlen);
|
|
delete_smbctx(ctx1);
|
|
}else{
|
|
recurse(ctx, smb_group, smb_path, maxlen);
|
|
ctx->callbacks.purge_cached_fn(ctx);
|
|
}
|
|
break;
|
|
case SMBC_FILE_SHARE:
|
|
case SMBC_DIR:
|
|
case SMBC_FILE:
|
|
if (maxlen < len + strlen(list->name) + 2) break;
|
|
|
|
smb_path[len] = '/';
|
|
strcpy(smb_path + len + 1, list->name);
|
|
print_smb_path(smb_group, smb_path + 6);
|
|
if (list->type != SMBC_FILE){
|
|
recurse(ctx, smb_group, smb_path, maxlen);
|
|
if (list->type == SMBC_FILE_SHARE)
|
|
ctx->callbacks.purge_cached_fn(ctx);
|
|
}
|
|
break;
|
|
}
|
|
item = list;
|
|
list = list->next;
|
|
free(item);
|
|
}
|
|
smb_path[len] = '\0';
|
|
}
|
|
|
|
int main(int argc, char *argv[]){
|
|
int i;
|
|
SMBCCTX *ctx;
|
|
char smb_path[32768] = "smb://";
|
|
|
|
if ((ctx = create_smbctx()) == NULL){
|
|
perror("Cant create samba context.");
|
|
return 1;
|
|
}
|
|
|
|
if (argc == 1) recurse(ctx, "", smb_path, sizeof(smb_path));
|
|
else for(i = 1; i < argc; i++){
|
|
strncpy(smb_path + 6, argv[i], sizeof(smb_path) - 7);
|
|
smb_path[sizeof(smb_path) - 1] = '\0';
|
|
recurse(ctx, "", smb_path, sizeof(smb_path));
|
|
}
|
|
|
|
delete_smbctx(ctx);
|
|
return 0;
|
|
}
|