#include "includes.h" #include "smb.h" #include #include #include #include #include #include //#include #include "include/client.h" //#include "libsmb/proto.h" //#include "include/popt_common.h" //#include "../librpc/gen_ndr/ndr_lsa_c.h" //#include "rpc_client/cli_pipe.h" //#include "rpc_client/cli_lsarpc.h" #include #include #include #include #include "include/libsmbclient.h" #include "../include/egn_error.h" #include "include/popt_common.h" pthread_mutex_t mutex_smbc = PTHREAD_MUTEX_INITIALIZER; const char *my_name = "localhost"; static int init_auth_info(TALLOC_CTX *mem_ctx,const char *username,const char *domain,const char *password,struct user_auth_info **p_user_auth_info); static void set_auth_info(struct user_auth_info *auth_info); static void cleanmem(TALLOC_CTX *mem_ctx,struct user_auth_info *p_user_auth_info); typedef struct { char *username; char *domain_name; char *password; char *srvr; char *share; }auth_cred; extern FILE *fd_log; extern int g_enable_debug_msg; #define CANNOT_INIT_CTX 50 static void ctx_authenticate(SMBCCTX *c,const char *srv,const char *shr,char *wg,int wglen,char *un,int unlen,char *pw,int pwlen); //! Callback from Samba used to get CIFS credentials // // void ctx_authenticate(SMBCCTX *c, const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen) { void* ptr = smbc_getOptionUserData(c); auth_cred *creds = (auth_cred*)ptr; // Ignore the srv and shr names and use the same authentication information for all servers and shares strncpy(wg, creds->domain_name, wglen-1); strncpy(un, creds->username, unlen-1); strncpy(pw, creds->password, pwlen-1); LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_DEBUG,"[%lu] %s: domain=%s username=%s password=****** ctx=%p creds=%p\n",pthread_self(),__func__,creds->domain_name,creds->username,c,ptr); } int ctx_create_new_smbc_context(TALLOC_CTX* mem_ctx,struct user_auth_info **p_user_auth_info,SMBCCTX** smb_ctxt,const char* username,const char*domain_name,const char *password,const char* srvr,const char *share) { auth_cred *creds = NULL; *smb_ctxt = NULL; int err = 0; char *temp = NULL; if(!username || !domain_name || !password || !srvr || !share || !smb_ctxt) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: invalid arguments\n",pthread_self(),__func__); err = CANNOT_INIT_CTX; } creds = malloc(sizeof(auth_cred)); if(!creds) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: unable to allocate memory for creds\n",pthread_self(),__func__); err= CANNOT_INIT_CTX; } else { creds->username = malloc(strlen(username)+1); creds->domain_name = malloc(strlen(domain_name)+1); creds->password = malloc(strlen(password)+1); creds->srvr = malloc(strlen(srvr)+1); creds->share = malloc(strlen(share)+1); if(!creds->username || !creds->domain_name || !creds->password || !creds->srvr || !creds->share) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: unable to allocate memory for cred members\n",pthread_self(),__func__); err= CANNOT_INIT_CTX; goto done; } memcpy(creds->username,username,strlen(username)); memcpy(creds->domain_name,domain_name,strlen(domain_name)); memcpy(creds->password,password,strlen(password)); memcpy(creds->srvr,srvr,strlen(srvr)); memcpy(creds->share,share,strlen(share)); } err = init_auth_info(mem_ctx,username,domain_name,password,p_user_auth_info); if(err) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: unable to allocate memory for cred members\n",pthread_self(),__func__); err= CANNOT_INIT_CTX; goto done; } set_auth_info(*p_user_auth_info); *smb_ctxt = smbc_new_context(); if(!*smb_ctxt ) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: unable to create new smb context\n",pthread_self(),__func__); err= CANNOT_INIT_CTX; goto done; } // Configure the Samba context set_global_myname(my_name); smbc_setOptionUserData(*smb_ctxt, creds); smbc_setFunctionAuthDataWithContext(*smb_ctxt, ctx_authenticate); smbc_setOptionDebugToStderr(*smb_ctxt, 1); //netbios_name = (char *)SMB_MALLOC(17); temp = talloc_asprintf(temp,"%s",my_name); smbc_setNetbiosName(*smb_ctxt,temp); //temp = talloc_asprintf(temp,"TEST_%lu",pthread_self()); //smbc_option_set(*smb_ctxt, temp, 1); // Use a new CIFS connection for every share on a server smbc_setOptionOneSharePerServer(*smb_ctxt, true); // URL encode read-dir entries // This causes issues such as bug# ECC-303 //smbc_setOptionUrlEncodeReaddirEntries(m_smb_ctxt, CONFIG.cifs.urlencode_path); // Initialize with the configured options if (!smbc_init_context(*smb_ctxt)) { // Failed to initialize context smbc_free_context(*smb_ctxt, 0); *smb_ctxt =NULL; LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: unable to initialize new smb context\n",pthread_self(),__func__); err = CANNOT_INIT_CTX; goto done; } LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_DEBUG,"[%lu] %s: domain=%s username=%s password=****** ctx=%p creds=%p\n",pthread_self(),__func__,creds->domain_name,creds->username,*smb_ctxt,creds); done: if(err) { if(creds->username) free(creds->username); if(creds->domain_name) free(creds->domain_name); if(creds->password) free(creds->password); if(creds) free(creds); } TALLOC_FREE(temp); return err; } void ctx_cleanup_context(TALLOC_CTX *mem_ctx,struct user_auth_info *p_user_auth_info,SMBCCTX* smb_ctxt) { if(smb_ctxt) { void* ptr = smbc_getOptionUserData(smb_ctxt); auth_cred *creds = (auth_cred*)ptr; free(creds->password); free(creds->domain_name); free(creds->username); free(creds); smbc_setOptionUserData(smb_ctxt, NULL); smbc_setNetbiosName(smb_ctxt,NULL); smbc_free_context(smb_ctxt, 1); smb_ctxt = NULL; cleanmem(mem_ctx,p_user_auth_info); } } const char* ctx_get_username(SMBCCTX* smb_ctxt) { void* ptr = smbc_getOptionUserData(smb_ctxt); auth_cred *creds = (auth_cred*)ptr; return creds->username; } const char* ctx_get_domain(SMBCCTX* smb_ctxt) { void* ptr = smbc_getOptionUserData(smb_ctxt); auth_cred *creds = (auth_cred*)ptr; return creds->domain_name; } const char* ctx_get_password(SMBCCTX* smb_ctxt) { void* ptr = smbc_getOptionUserData(smb_ctxt); auth_cred *creds = (auth_cred*)ptr; return creds->password; } int ctx_stat(SMBCCTX* smb_ctxt,const char* smburl, struct stat *st) { int res = smbc_getFunctionStat(smb_ctxt)(smb_ctxt,smburl,st); return res; } int ctx_mkdir(SMBCCTX* smb_ctxt,const char *smburl, mode_t mode) { int res = smbc_getFunctionMkdir(smb_ctxt)(smb_ctxt, smburl, mode); return res; } int ctx_rmdir(SMBCCTX* smb_ctxt,const char *smburl) { int res = smbc_getFunctionRmdir(smb_ctxt)(smb_ctxt, smburl); return res; } int ctx_unlink(SMBCCTX* smb_ctxt,const char *smburl) { int res = smbc_getFunctionUnlink(smb_ctxt)(smb_ctxt, smburl); return res; } int ctx_rename(SMBCCTX* smb_ctxt,const char *source, const char *target) { int res = smbc_getFunctionRename(smb_ctxt)(smb_ctxt, source, smb_ctxt, target); return res; } SMBCFILE* ctx_opendir(SMBCCTX* smb_ctxt,const char *smburl) { SMBCFILE* pSMBCFILE = smbc_getFunctionOpendir(smb_ctxt)(smb_ctxt, smburl); return pSMBCFILE; } int ctx_closedir(SMBCCTX* smb_ctxt,SMBCFILE* const pdir) { int res = smbc_getFunctionClosedir(smb_ctxt)(smb_ctxt, pdir); return res; } int ctx_getdents(SMBCCTX* smb_ctxt,SMBCFILE* const pdir,struct smbc_dirent* const dirents,const int count) { int res = smbc_getFunctionGetdents(smb_ctxt)(smb_ctxt, pdir, dirents, count); return res; } struct smbc_dirent* ctx_readdir(SMBCCTX* smb_ctxt,SMBCFILE* const pdir) { struct smbc_dirent* pdirent = smbc_getFunctionReaddir(smb_ctxt)(smb_ctxt, pdir); return pdirent; } SMBCFILE* ctx_open(SMBCCTX* smb_ctxt,const char *smburl, int flags, mode_t mode) { SMBCFILE* pSMBCFILE = smbc_getFunctionOpen(smb_ctxt)(smb_ctxt, smburl, flags, mode); return pSMBCFILE; } ssize_t ctx_read(SMBCCTX* smb_ctxt,SMBCFILE* const pfile,void *buf,size_t bufsize) { ssize_t size = smbc_getFunctionRead(smb_ctxt)(smb_ctxt, pfile, buf, bufsize); return size; } ssize_t ctx_write(SMBCCTX* smb_ctxt,SMBCFILE* const pfile,const void *buf,size_t bufsize) { ssize_t size = smbc_getFunctionWrite(smb_ctxt)(smb_ctxt, pfile, buf, bufsize); return size; } int ctx_close(SMBCCTX* smb_ctxt,SMBCFILE* const pfile) { int res = smbc_getFunctionClose(smb_ctxt)(smb_ctxt, pfile); return res; } SMBCFILE* ctx_creat(SMBCCTX* smb_ctxt,const char *smburl,mode_t mode) { SMBCFILE* pSMBCFILE = smbc_getFunctionCreat(smb_ctxt)(smb_ctxt, smburl, mode); return pSMBCFILE; } pthread_mutex_t* ctx_get_smbc_mutex() { return &mutex_smbc; } void set_auth_info(struct user_auth_info *auth_info) { if(!set_cmdline_auth_info_machine_account_creds(auth_info)) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: ERROR cannot set machine account creds\n",pthread_self(),__func__); } } static int init_auth_info(TALLOC_CTX *mem_ctx,const char *username,const char *domain,const char *password,struct user_auth_info **p_user_auth_info) { int err = -1; *p_user_auth_info = NULL; struct user_auth_info *tmp = NULL; LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_DEBUG,"[%lu] %s: entry\n",pthread_self(),__func__); if(!username || !domain || !password) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: ERROR invalid arguments\n",pthread_self(),__func__); goto error_out; } *p_user_auth_info = TALLOC_ZERO_P(mem_ctx, struct user_auth_info); if(!p_user_auth_info) { /*all the printf's will change to egnyte logging macros later*/ LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: ERROR unable to allocate memory\n",pthread_self(),__func__); goto error_out; } tmp = *p_user_auth_info; tmp->username = talloc_strdup(tmp, username); if(!tmp->username) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: ERROR unable to allocate memory for username\n",pthread_self(),__func__); goto error_out; } tmp->password = talloc_strdup(tmp, password); if(!tmp->password) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: ERROR unable to allocate memory for password\n",pthread_self(),__func__); goto error_out; } tmp->domain = talloc_strdup(tmp, domain); if(!tmp->domain) { LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_ERROR,"[%lu] %s: ERROR unable to allocate memory for domain\n",pthread_self(),__func__); goto error_out; } tmp->signing_state = Undefined; err = 0; LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_DEBUG,"[%lu] %s: username=%s password=**** domain=%s\n",pthread_self(),__func__,tmp->username,tmp->domain); error_out: LOGCUSTOMMSG(fd_log,g_enable_debug_msg,EGN_LOG_DEBUG,"[%lu] %s: exit\n",pthread_self(),__func__); return err; } static void cleanmem(TALLOC_CTX *mem_ctx,struct user_auth_info *p_user_auth_info) { if(p_user_auth_info) { TALLOC_FREE(p_user_auth_info->username); TALLOC_FREE(p_user_auth_info->domain); TALLOC_FREE(p_user_auth_info->password); //I leave this as a reminder of what not to do with *p_user_auth_info // TALLOC_FREE(*p_user_auth_info); this is freed when frame is freed so do not free } //free this last as *p_user_auth_info is dependent in this //TALLOC_FREE(mem_ctx); }