diff options
Diffstat (limited to 'source4')
24 files changed, 1284 insertions, 1718 deletions
diff --git a/source4/Makefile b/source4/Makefile index 7bc48b9fe4..2a3ad2def1 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -58,6 +58,7 @@ clustersrcdir := cluster libnetsrcdir := libnet authsrcdir := auth nsswitchsrcdir := ../nsswitch +libwbclientsrcdir := ../nsswitch/libwbclient libsrcdir := lib libsocketsrcdir := lib/socket libcharsetsrcdir := ../lib/util/charset diff --git a/source4/client/smbmnt.c b/source4/client/smbmnt.c deleted file mode 100644 index 0d619a88fe..0000000000 --- a/source4/client/smbmnt.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * smbmnt.c - * - * Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke - * extensively modified by Tridge - * - */ - -#include "includes.h" - -#include <mntent.h> -#include <sys/utsname.h> - -#include <asm/types.h> -#include <asm/posix_types.h> -#include <linux/smb.h> -#include <linux/smb_mount.h> -#include <asm/unistd.h> - -#ifndef MS_MGC_VAL -/* This may look strange but MS_MGC_VAL is what we are looking for and - is what we need from <linux/fs.h> under libc systems and is - provided in standard includes on glibc systems. So... We - switch on what we need... */ -#include <linux/fs.h> -#endif - -static uid_t mount_uid; -static gid_t mount_gid; -static int mount_ro; -static uint_t mount_fmask; -static uint_t mount_dmask; -static int user_mount; -static char *options; - -static void -help(void) -{ - printf("\n"); - printf("Usage: smbmnt mount-point [options]\n"); - printf("Version %s\n\n",VERSION); - printf("-s share share name on server\n" - "-r mount read-only\n" - "-u uid mount as uid\n" - "-g gid mount as gid\n" - "-f mask permission mask for files\n" - "-d mask permission mask for directories\n" - "-o options name=value, list of options\n" - "-h print this help text\n"); -} - -static int -parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share) -{ - int opt; - - while ((opt = getopt (argc, argv, "s:u:g:rf:d:o:")) != EOF) - { - switch (opt) - { - case 's': - *share = optarg; - break; - case 'u': - if (!user_mount) { - mount_uid = strtol(optarg, NULL, 0); - } - break; - case 'g': - if (!user_mount) { - mount_gid = strtol(optarg, NULL, 0); - } - break; - case 'r': - mount_ro = 1; - break; - case 'f': - mount_fmask = strtol(optarg, NULL, 8); - break; - case 'd': - mount_dmask = strtol(optarg, NULL, 8); - break; - case 'o': - options = optarg; - break; - default: - return -1; - } - } - return 0; - -} - -static char * -fullpath(const char *p) -{ - char path[MAXPATHLEN]; - - if (strlen(p) > MAXPATHLEN-1) { - return NULL; - } - - if (realpath(p, path) == NULL) { - fprintf(stderr,"Failed to find real path for mount point\n"); - exit(1); - } - return strdup(path); -} - -/* Check whether user is allowed to mount on the specified mount point. If it's - OK then we change into that directory - this prevents race conditions */ -static int mount_ok(char *mount_point) -{ - struct stat st; - - if (chdir(mount_point) != 0) { - return -1; - } - - if (stat(".", &st) != 0) { - return -1; - } - - if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - return -1; - } - - if ((getuid() != 0) && - ((getuid() != st.st_uid) || - ((st.st_mode & S_IRWXU) != S_IRWXU))) { - errno = EPERM; - return -1; - } - - return 0; -} - -/* Tries to mount using the appropriate format. For 2.2 the struct, - for 2.4 the ascii version. */ -static int -do_mount(char *share_name, uint_t flags, struct smb_mount_data *data) -{ - pstring opts; - struct utsname uts; - char *release, *major, *minor; - char *data1, *data2; - - uname(&uts); - release = uts.release; - major = strtok(release, "."); - minor = strtok(NULL, "."); - if (major && minor && atoi(major) == 2 && atoi(minor) < 4) { - /* < 2.4, assume struct */ - data1 = (char *) data; - data2 = opts; - } else { - /* >= 2.4, assume ascii but fall back on struct */ - data1 = opts; - data2 = (char *) data; - } - - slprintf(opts, sizeof(opts)-1, - "version=7,uid=%d,gid=%d,file_mode=0%o,dir_mode=0%o,%s", - data->uid, data->gid, data->file_mode, data->dir_mode,options); - if (mount(share_name, ".", "smbfs", flags, data1) == 0) - return 0; - return mount(share_name, ".", "smbfs", flags, data2); -} - - int main(int argc, char *argv[]) -{ - char *mount_point, *share_name = NULL; - FILE *mtab; - int fd; - uint_t flags; - struct smb_mount_data data; - struct mntent ment; - - memset(&data, 0, sizeof(struct smb_mount_data)); - - if (argc < 2) { - help(); - exit(1); - } - - if (argv[1][0] == '-') { - help(); - exit(1); - } - - if (getuid() != 0) { - user_mount = 1; - } - - if (geteuid() != 0) { - fprintf(stderr, "smbmnt must be installed suid root for direct user mounts (%d,%d)\n", getuid(), geteuid()); - exit(1); - } - - mount_uid = getuid(); - mount_gid = getgid(); - mount_fmask = umask(0); - umask(mount_fmask); - mount_fmask = ~mount_fmask; - - mount_point = fullpath(argv[1]); - - argv += 1; - argc -= 1; - - if (mount_ok(mount_point) != 0) { - fprintf(stderr, "cannot mount on %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - - data.version = SMB_MOUNT_VERSION; - - /* getuid() gives us the real uid, who may umount the fs */ - data.mounted_uid = getuid(); - - if (parse_args(argc, argv, &data, &share_name) != 0) { - help(); - return -1; - } - - data.uid = mount_uid; - data.gid = mount_gid; - data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_fmask; - data.dir_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_dmask; - - if (mount_dmask == 0) { - data.dir_mode = data.file_mode; - if ((data.dir_mode & S_IRUSR) != 0) - data.dir_mode |= S_IXUSR; - if ((data.dir_mode & S_IRGRP) != 0) - data.dir_mode |= S_IXGRP; - if ((data.dir_mode & S_IROTH) != 0) - data.dir_mode |= S_IXOTH; - } - - flags = MS_MGC_VAL; - - if (mount_ro) flags |= MS_RDONLY; - - if (do_mount(share_name, flags, &data) < 0) { - switch (errno) { - case ENODEV: - fprintf(stderr, "ERROR: smbfs filesystem not supported by the kernel\n"); - break; - default: - perror("mount error"); - } - fprintf(stderr, "Please refer to the smbmnt(8) manual page\n"); - return -1; - } - - ment.mnt_fsname = share_name ? share_name : "none"; - ment.mnt_dir = mount_point; - ment.mnt_type = "smbfs"; - ment.mnt_opts = ""; - ment.mnt_freq = 0; - ment.mnt_passno= 0; - - mount_point = ment.mnt_dir; - - if (mount_point == NULL) - { - fprintf(stderr, "Mount point too long\n"); - return -1; - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) - { - fprintf(stderr, "Can't get "MOUNTED"~ lock file"); - return 1; - } - close(fd); - - if ((mtab = setmntent(MOUNTED, "a+")) == NULL) - { - fprintf(stderr, "Can't open " MOUNTED); - return 1; - } - - if (addmntent(mtab, &ment) == 1) - { - fprintf(stderr, "Can't write mount entry"); - return 1; - } - if (fchmod(fileno(mtab), 0644) == -1) - { - fprintf(stderr, "Can't set perms on "MOUNTED); - return 1; - } - endmntent(mtab); - - if (unlink(MOUNTED"~") == -1) - { - fprintf(stderr, "Can't remove "MOUNTED"~"); - return 1; - } - - return 0; -} diff --git a/source4/client/smbmount.c b/source4/client/smbmount.c deleted file mode 100644 index c219a42f3a..0000000000 --- a/source4/client/smbmount.c +++ /dev/null @@ -1,942 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMBFS mount program - Copyright (C) Andrew Tridgell 1999 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "system/passwd.h" - -#include <mntent.h> -#include <asm/types.h> -#include <linux/smb_fs.h> - -#define pstrcpy(d,s) safe_strcpy((d),(s),sizeof(pstring)-1) -#define pstrcat(d,s) safe_strcat((d),(s),sizeof(pstring)-1) - -static pstring credentials; -static pstring my_netbios_name; -static pstring password; -static pstring username; -static pstring workgroup; -static pstring mpoint; -static pstring service; -static pstring options; - -static struct in_addr dest_ip; -static bool have_ip; -static int smb_port = 0; -static bool got_user; -static bool got_pass; -static uid_t mount_uid; -static gid_t mount_gid; -static int mount_ro; -static uint_t mount_fmask; -static uint_t mount_dmask; -static bool use_kerberos; -/* TODO: Add code to detect smbfs version in kernel */ -static bool status32_smbfs = false; - -static void usage(void); - -static void exit_parent(int sig) -{ - /* parent simply exits when child says go... */ - exit(0); -} - -static void daemonize(void) -{ - int j, status; - pid_t child_pid; - - signal( SIGTERM, exit_parent ); - - if ((child_pid = sys_fork()) < 0) { - DEBUG(0,("could not fork\n")); - } - - if (child_pid > 0) { - while( 1 ) { - j = waitpid( child_pid, &status, 0 ); - if( j < 0 ) { - if( EINTR == errno ) { - continue; - } - status = errno; - } - break; - } - - /* If we get here - the child exited with some error status */ - if (WIFSIGNALED(status)) - exit(128 + WTERMSIG(status)); - else - exit(WEXITSTATUS(status)); - } - - signal( SIGTERM, SIG_DFL ); - chdir("/"); -} - -static void close_our_files(int client_fd) -{ - int i; - struct rlimit limits; - - getrlimit(RLIMIT_NOFILE,&limits); - for (i = 0; i< limits.rlim_max; i++) { - if (i == client_fd) - continue; - close(i); - } -} - -static void usr1_handler(int x) -{ - return; -} - - -/***************************************************** -return a connection to a server -*******************************************************/ -static struct smbcli_state *do_connection(const char *the_service, bool unicode, int maxprotocol, - struct smbcli_session_options session_options) -{ - struct smbcli_state *c; - struct nmb_name called, calling; - char *server_n; - struct in_addr ip; - pstring server; - char *share; - - if (the_service[0] != '\\' || the_service[1] != '\\') { - usage(); - exit(1); - } - - pstrcpy(server, the_service+2); - share = strchr_m(server,'\\'); - if (!share) { - usage(); - exit(1); - } - *share = 0; - share++; - - server_n = server; - - make_nmb_name(&calling, my_netbios_name, 0x0); - choose_called_name(&called, server, 0x20); - - again: - zero_ip(&ip); - if (have_ip) ip = dest_ip; - - /* have to open a new connection */ - if (!(c=smbcli_initialise(NULL)) || (smbcli_set_port(c, smb_port) != smb_port) || - !smbcli_connect(c, server_n, &ip)) { - DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n)); - if (c) { - talloc_free(c); - } - return NULL; - } - - /* SPNEGO doesn't work till we get NTSTATUS error support */ - /* But it is REQUIRED for kerberos authentication */ - if(!use_kerberos) c->use_spnego = false; - - /* The kernel doesn't yet know how to sign it's packets */ - c->sign_info.allow_smb_signing = false; - - /* Use kerberos authentication if specified */ - c->use_kerberos = use_kerberos; - - if (!smbcli_session_request(c, &calling, &called)) { - char *p; - DEBUG(0,("%d: session request to %s failed (%s)\n", - sys_getpid(), called.name, smbcli_errstr(c))); - talloc_free(c); - if ((p=strchr_m(called.name, '.'))) { - *p = 0; - goto again; - } - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } - return NULL; - } - - DEBUG(4,("%d: session request ok\n", sys_getpid())); - - if (!smbcli_negprot(c, unicode, maxprotocol)) { - DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid())); - talloc_free(c); - return NULL; - } - - if (!got_pass) { - char *pass = getpass("Password: "); - if (pass) { - pstrcpy(password, pass); - } - } - - /* This should be right for current smbfs. Future versions will support - large files as well as unicode and oplocks. */ - if (status32_smbfs) { - c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS | - CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS); - } - else { - c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS | - CAP_NT_FIND | CAP_STATUS32 | - CAP_LEVEL_II_OPLOCKS); - c->force_dos_errors = true; - } - - if (!smbcli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - workgroup, session_options)) { - /* if a password was not supplied then try again with a - null username */ - if (password[0] || !username[0] || - !smbcli_session_setup(c, "", "", 0, "", 0, workgroup, - session_options)) { - DEBUG(0,("%d: session setup failed: %s\n", - sys_getpid(), smbcli_errstr(c))); - talloc_free(c); - return NULL; - } - DEBUG(0,("Anonymous login successful\n")); - } - - DEBUG(4,("%d: session setup ok\n", sys_getpid())); - - if (!smbcli_tconX(c, share, "?????", password, strlen(password)+1)) { - DEBUG(0,("%d: tree connect failed: %s\n", - sys_getpid(), smbcli_errstr(c))); - talloc_free(c); - return NULL; - } - - DEBUG(4,("%d: tconx ok\n", sys_getpid())); - - got_pass = true; - - return c; -} - - -/**************************************************************************** -unmount smbfs (this is a bailout routine to clean up if a reconnect fails) - Code blatently stolen from smbumount.c - -mhw- -****************************************************************************/ -static void smb_umount(const char *mount_point) -{ - int fd; - struct mntent *mnt; - FILE* mtab; - FILE* new_mtab; - - /* Programmers Note: - This routine only gets called to the scene of a disaster - to shoot the survivors... A connection that was working - has now apparently failed. We have an active mount point - (presumably) that we need to dump. If we get errors along - the way - make some noise, but we are already turning out - the lights to exit anyways... - */ - if (umount(mount_point) != 0) { - DEBUG(0,("%d: Could not umount %s: %s\n", - sys_getpid(), mount_point, strerror(errno))); - return; - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) { - DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid())); - return; - } - - close(fd); - - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { - DEBUG(0,("%d: Can't open " MOUNTED ": %s\n", - sys_getpid(), strerror(errno))); - return; - } - -#define MOUNTED_TMP MOUNTED".tmp" - - if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { - DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n", - sys_getpid(), strerror(errno))); - endmntent(mtab); - return; - } - - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) != 0) { - addmntent(new_mtab, mnt); - } - } - - endmntent(mtab); - - if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { - DEBUG(0,("%d: Error changing mode of %s: %s\n", - sys_getpid(), MOUNTED_TMP, strerror(errno))); - return; - } - - endmntent(new_mtab); - - if (rename(MOUNTED_TMP, MOUNTED) < 0) { - DEBUG(0,("%d: Cannot rename %s to %s: %s\n", - sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno))); - return; - } - - if (unlink(MOUNTED"~") == -1) { - DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid())); - return; - } -} - - -/* - * Call the smbfs ioctl to install a connection socket, - * then wait for a signal to reconnect. Note that we do - * not exit after open_sockets() or send_login() errors, - * as the smbfs mount would then have no way to recover. - */ -static void send_fs_socket(struct loadparm_context *lp_ctx, - const char *the_service, const char *mount_point, struct smbcli_state *c) -{ - int fd, closed = 0, res = 1; - pid_t parentpid = getppid(); - struct smb_conn_opt conn_options; - struct smbcli_session_options session_options; - - lp_smbcli_session_options(lp_ctx, &session_options); - - memset(&conn_options, 0, sizeof(conn_options)); - - while (1) { - if ((fd = open(mount_point, O_RDONLY)) < 0) { - DEBUG(0,("mount.smbfs[%d]: can't open %s\n", - sys_getpid(), mount_point)); - break; - } - - conn_options.fd = c->fd; - conn_options.protocol = c->protocol; - conn_options.case_handling = SMB_CASE_DEFAULT; - conn_options.max_xmit = c->max_xmit; - conn_options.server_uid = c->vuid; - conn_options.tid = c->cnum; - conn_options.secmode = c->sec_mode; - conn_options.rawmode = 0; - conn_options.sesskey = c->sesskey; - conn_options.maxraw = 0; - conn_options.capabilities = c->capabilities; - conn_options.serverzone = c->serverzone/60; - - res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options); - if (res != 0) { - DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n", - sys_getpid(), res)); - close(fd); - break; - } - - if (parentpid) { - /* Ok... We are going to kill the parent. Now - is the time to break the process group... */ - setsid(); - /* Send a signal to the parent to terminate */ - kill(parentpid, SIGTERM); - parentpid = 0; - } - - close(fd); - - /* This looks wierd but we are only closing the userspace - side, the connection has already been passed to smbfs and - it has increased the usage count on the socket. - - If we don't do this we will "leak" sockets and memory on - each reconnection we have to make. */ - talloc_free(c); - c = NULL; - - if (!closed) { - /* redirect stdout & stderr since we can't know that - the library functions we use are using DEBUG. */ - if ( (fd = open("/dev/null", O_WRONLY)) < 0) - DEBUG(2,("mount.smbfs: can't open /dev/null\n")); - close_our_files(fd); - if (fd >= 0) { - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - close(fd); - } - - /* here we are no longer interactive */ - set_remote_machine_name("smbmount"); /* sneaky ... */ - setup_logging("mount.smbfs", DEBUG_STDERR); - reopen_logs(); - DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid())); - - closed = 1; - } - - /* Wait for a signal from smbfs ... but don't continue - until we actually get a new connection. */ - while (!c) { - CatchSignal(SIGUSR1, &usr1_handler); - pause(); - DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid())); - c = do_connection(the_service, - lp_unicode(lp_ctx), - lp_cli_maxprotocol(lp_ctx), - session_options); - } - } - - smb_umount(mount_point); - DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid())); - exit(1); -} - - -/** - * Mount a smbfs - **/ -static void init_mount(struct loadparm_context *lp_ctx) -{ - char mount_point[MAXPATHLEN+1]; - pstring tmp; - pstring svc2; - struct smbcli_state *c; - char *args[20]; - int i, status; - struct smbcli_session_options session_options; - - if (realpath(mpoint, mount_point) == NULL) { - fprintf(stderr, "Could not resolve mount point %s\n", mpoint); - return; - } - - lp_smbcli_session_options(lp_ctx, &session_options); - - c = do_connection(service, lp_unicode(lp_ctx), lp_cli_maxprotocol(lp_ctx), - session_options); - if (!c) { - fprintf(stderr,"SMB connection failed\n"); - exit(1); - } - - /* - Set up to return as a daemon child and wait in the parent - until the child say it's ready... - */ - daemonize(); - - pstrcpy(svc2, service); - string_replace(svc2, '\\','/'); - string_replace(svc2, ' ','_'); - - memset(args, 0, sizeof(args[0])*20); - - i=0; - args[i++] = "smbmnt"; - - args[i++] = mount_point; - args[i++] = "-s"; - args[i++] = svc2; - - if (mount_ro) { - args[i++] = "-r"; - } - if (mount_uid) { - slprintf(tmp, sizeof(tmp)-1, "%d", mount_uid); - args[i++] = "-u"; - args[i++] = smb_xstrdup(tmp); - } - if (mount_gid) { - slprintf(tmp, sizeof(tmp)-1, "%d", mount_gid); - args[i++] = "-g"; - args[i++] = smb_xstrdup(tmp); - } - if (mount_fmask) { - slprintf(tmp, sizeof(tmp)-1, "0%o", mount_fmask); - args[i++] = "-f"; - args[i++] = smb_xstrdup(tmp); - } - if (mount_dmask) { - slprintf(tmp, sizeof(tmp)-1, "0%o", mount_dmask); - args[i++] = "-d"; - args[i++] = smb_xstrdup(tmp); - } - if (options) { - args[i++] = "-o"; - args[i++] = options; - } - - if (sys_fork() == 0) { - char *smbmnt_path; - - asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR); - - if (file_exist(smbmnt_path)) { - execv(smbmnt_path, args); - fprintf(stderr, - "smbfs/init_mount: execv of %s failed. Error was %s.", - smbmnt_path, strerror(errno)); - } else { - execvp("smbmnt", args); - fprintf(stderr, - "smbfs/init_mount: execv of %s failed. Error was %s.", - "smbmnt", strerror(errno)); - } - free(smbmnt_path); - exit(1); - } - - if (waitpid(-1, &status, 0) == -1) { - fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) ); - /* FIXME: do some proper error handling */ - exit(1); - } - - if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { - fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status)); - /* FIXME: do some proper error handling */ - exit(1); - } else if (WIFSIGNALED(status)) { - fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status)); - exit(1); - } - - /* Ok... This is the rubicon for that mount point... At any point - after this, if the connections fail and can not be reconstructed - for any reason, we will have to unmount the mount point. There - is no exit from the next call... - */ - send_fs_socket(lp_ctx, service, mount_point, c); -} - - -/**************************************************************************** -get a password from a a file or file descriptor -exit on failure (from smbclient, move to libsmb or shared .c file?) -****************************************************************************/ -static void get_password_file(void) -{ - int fd = -1; - char *p; - bool close_it = false; - pstring spec; - char pass[128]; - - if ((p = getenv("PASSWD_FD")) != NULL) { - pstrcpy(spec, "descriptor "); - pstrcat(spec, p); - sscanf(p, "%d", &fd); - close_it = false; - } else if ((p = getenv("PASSWD_FILE")) != NULL) { - fd = open(p, O_RDONLY, 0); - pstrcpy(spec, p); - if (fd < 0) { - fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n", - spec, strerror(errno)); - exit(1); - } - close_it = true; - } - - for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */ - p && p - pass < sizeof(pass);) { - switch (read(fd, p, 1)) { - case 1: - if (*p != '\n' && *p != '\0') { - *++p = '\0'; /* advance p, and null-terminate pass */ - break; - } - case 0: - if (p - pass) { - *p = '\0'; /* null-terminate it, just in case... */ - p = NULL; /* then force the loop condition to become false */ - break; - } else { - fprintf(stderr, "Error reading password from file %s: %s\n", - spec, "empty password\n"); - exit(1); - } - - default: - fprintf(stderr, "Error reading password from file %s: %s\n", - spec, strerror(errno)); - exit(1); - } - } - pstrcpy(password, pass); - if (close_it) - close(fd); -} - -/**************************************************************************** -get username and password from a credentials file -exit on failure (from smbclient, move to libsmb or shared .c file?) -****************************************************************************/ -static void read_credentials_file(char *filename) -{ - FILE *auth; - fstring buf; - uint16_t len = 0; - char *ptr, *val, *param; - - if ((auth=sys_fopen(filename, "r")) == NULL) - { - /* fail if we can't open the credentials file */ - DEBUG(0,("ERROR: Unable to open credentials file!\n")); - exit (-1); - } - - while (!feof(auth)) - { - /* get a line from the file */ - if (!fgets (buf, sizeof(buf), auth)) - continue; - len = strlen(buf); - - if ((len) && (buf[len-1]=='\n')) - { - buf[len-1] = '\0'; - len--; - } - if (len == 0) - continue; - - /* break up the line into parameter & value. - will need to eat a little whitespace possibly */ - param = buf; - if (!(ptr = strchr (buf, '='))) - continue; - val = ptr+1; - *ptr = '\0'; - - /* eat leading white space */ - while ((*val!='\0') && ((*val==' ') || (*val=='\t'))) - val++; - - if (strwicmp("password", param) == 0) - { - pstrcpy(password, val); - got_pass = true; - } - else if (strwicmp("username", param) == 0) { - pstrcpy(username, val); - } - - memset(buf, 0, sizeof(buf)); - } - fclose(auth); -} - - -/**************************************************************************** -usage on the program -****************************************************************************/ -static void usage(void) -{ - printf("Usage: mount.smbfs service mountpoint [-o options,...]\n"); - - printf("Version %s\n\n",VERSION); - - printf( -"Options:\n\ - username=<arg> SMB username\n\ - password=<arg> SMB password\n\ - credentials=<filename> file with username/password\n\ - krb use kerberos (active directory)\n\ - netbiosname=<arg> source NetBIOS name\n\ - uid=<arg> mount uid or username\n\ - gid=<arg> mount gid or groupname\n\ - port=<arg> remote SMB port number\n\ - fmask=<arg> file umask\n\ - dmask=<arg> directory umask\n\ - debug=<arg> debug level\n\ - ip=<arg> destination host or IP address\n\ - workgroup=<arg> workgroup on destination\n\ - sockopt=<arg> TCP socket options\n\ - scope=<arg> NetBIOS scope\n\ - iocharset=<arg> Linux charset (iso8859-1, utf8)\n\ - codepage=<arg> server codepage (cp850)\n\ - ttl=<arg> dircache time to live\n\ - guest don't prompt for a password\n\ - ro mount read-only\n\ - rw mount read-write\n\ -\n\ -This command is designed to be run from within /bin/mount by giving\n\ -the option '-t smbfs'. For example:\n\ - mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\ -"); -} - - -/**************************************************************************** - Argument parsing for mount.smbfs interface - mount will call us like this: - mount.smbfs device mountpoint -o <options> - - <options> is never empty, containing at least rw or ro - ****************************************************************************/ -static void parse_mount_smb(int argc, char **argv) -{ - int opt; - char *opts; - char *opteq; - extern char *optarg; - int val; - char *p; - - /* FIXME: This function can silently fail if the arguments are - * not in the expected order. - - > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable) - > requires that one gives "-o" before further options like username=... - > . Without -o, the username=.. setting is *silently* ignored. I've - > spent about an hour trying to find out why I couldn't log in now.. - - */ - - - if (argc < 2 || argv[1][0] == '-') { - usage(); - exit(1); - } - - pstrcpy(service, argv[1]); - pstrcpy(mpoint, argv[2]); - - /* Convert any '/' characters in the service name to - '\' characters */ - string_replace(service, '/','\\'); - argc -= 2; - argv += 2; - - opt = getopt(argc, argv, "o:"); - if(opt != 'o') { - return; - } - - options[0] = 0; - p = options; - - /* - * option parsing from nfsmount.c (util-linux-2.9u) - */ - for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) { - DEBUG(3, ("opts: %s\n", opts)); - if ((opteq = strchr_m(opts, '='))) { - val = atoi(opteq + 1); - *opteq = '\0'; - - if (!strcmp(opts, "username") || - !strcmp(opts, "logon")) { - char *lp; - got_user = true; - pstrcpy(username,opteq+1); - if ((lp=strchr_m(username,'%'))) { - *lp = 0; - pstrcpy(password,lp+1); - got_pass = true; - memset(strchr_m(opteq+1,'%')+1,'X',strlen(password)); - } - if ((lp=strchr_m(username,'/'))) { - *lp = 0; - pstrcpy(workgroup,lp+1); - } - } else if(!strcmp(opts, "passwd") || - !strcmp(opts, "password")) { - pstrcpy(password,opteq+1); - got_pass = true; - memset(opteq+1,'X',strlen(password)); - } else if(!strcmp(opts, "credentials")) { - pstrcpy(credentials,opteq+1); - } else if(!strcmp(opts, "netbiosname")) { - pstrcpy(my_netbios_name,opteq+1); - } else if(!strcmp(opts, "uid")) { - mount_uid = nametouid(opteq+1); - } else if(!strcmp(opts, "gid")) { - mount_gid = nametogid(opteq+1); - } else if(!strcmp(opts, "port")) { - smb_port = val; - } else if(!strcmp(opts, "fmask")) { - mount_fmask = strtol(opteq+1, NULL, 8); - } else if(!strcmp(opts, "dmask")) { - mount_dmask = strtol(opteq+1, NULL, 8); - } else if(!strcmp(opts, "debug")) { - DEBUGLEVEL = val; - } else if(!strcmp(opts, "ip")) { - dest_ip = interpret_addr2(opteq+1); - if (is_zero_ip_v4(dest_ip)) { - fprintf(stderr,"Can't resolve address %s\n", opteq+1); - exit(1); - } - have_ip = true; - } else if(!strcmp(opts, "workgroup")) { - pstrcpy(workgroup,opteq+1); - } else if(!strcmp(opts, "sockopt")) { - lp_set_cmdline("socket options", opteq+1); - } else if(!strcmp(opts, "scope")) { - lp_set_cmdline("netbios scope", opteq+1); - } else { - slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1); - p += strlen(p); - } - } else { - val = 1; - if(!strcmp(opts, "nocaps")) { - fprintf(stderr, "Unhandled option: %s\n", opteq+1); - exit(1); - } else if(!strcmp(opts, "guest")) { - *password = '\0'; - got_pass = true; - } else if(!strcmp(opts, "krb")) { -#ifdef HAVE_KRB5 - - use_kerberos = true; - if(!status32_smbfs) - fprintf(stderr, "Warning: kerberos support will only work for samba servers\n"); -#else - fprintf(stderr,"No kerberos support compiled in\n"); - exit(1); -#endif - } else if(!strcmp(opts, "rw")) { - mount_ro = 0; - } else if(!strcmp(opts, "ro")) { - mount_ro = 1; - } else { - strncpy(p, opts, sizeof(pstring) - (p - options) - 1); - p += strlen(opts); - *p++ = ','; - *p = 0; - } - } - } - - if (!*service) { - usage(); - exit(1); - } - - if (p != options) { - *(p-1) = 0; /* remove trailing , */ - DEBUG(3,("passthrough options '%s'\n", options)); - } -} - -/**************************************************************************** - main program -****************************************************************************/ - int main(int argc,char *argv[]) -{ - extern char *optarg; - extern int optind; - char *p; - struct loadparm_context *lp_ctx; - - DEBUGLEVEL = 1; - - /* here we are interactive, even if run from autofs */ - setup_logging("mount.smbfs",DEBUG_STDERR); - -#if 0 /* JRA - Urban says not needed ? */ - /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default - is to not announce any unicode capabilities as current smbfs does - not support it. */ - p = getenv("CLI_FORCE_ASCII"); - if (p && !strcmp(p, "false")) - unsetenv("CLI_FORCE_ASCII"); - else - setenv("CLI_FORCE_ASCII", "true", 1); -#endif - - if (getenv("USER")) { - pstrcpy(username,getenv("USER")); - - if ((p=strchr_m(username,'%'))) { - *p = 0; - pstrcpy(password,p+1); - got_pass = true; - memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password)); - } - strupper(username); - } - - if (getenv("PASSWD")) { - pstrcpy(password, getenv("PASSWD")); - got_pass = true; - } - - if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) { - get_password_file(); - got_pass = true; - } - - if (*username == 0 && getenv("LOGNAME")) { - pstrcpy(username,getenv("LOGNAME")); - } - - lp_ctx = loadparm_init(talloc_autofree_context()); - - if (!lp_load(lp_ctx, dyn_CONFIGFILE)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", - lp_config_file()); - } - - parse_mount_smb(argc, argv); - - if (use_kerberos && !got_user) { - got_pass = true; - } - - if (*credentials != 0) { - read_credentials_file(credentials); - } - - DEBUG(3,("mount.smbfs started (version %s)\n", VERSION)); - - if (*workgroup == 0) { - pstrcpy(workgroup, lp_workgroup()); - } - - if (!*my_netbios_name) { - pstrcpy(my_netbios_name, myhostname()); - } - strupper(my_netbios_name); - - init_mount(lp_ctx); - return 0; -} diff --git a/source4/client/smbumount.c b/source4/client/smbumount.c deleted file mode 100644 index 9ea3083a6f..0000000000 --- a/source4/client/smbumount.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * smbumount.c - * - * Copyright (C) 1995-1998 by Volker Lendecke - * - */ - -#include "includes.h" - -#include <mntent.h> - -#include <asm/types.h> -#include <asm/posix_types.h> -#include <linux/smb.h> -#include <linux/smb_mount.h> -#include <linux/smb_fs.h> - -/* This is a (hopefully) temporary hack due to the fact that - sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc. - This may change in the future and smb.h may get fixed in the - future. In the mean time, it's ugly hack time - get over it. -*/ -#undef SMB_IOC_GETMOUNTUID -#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t) - -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0400000 -#endif - -static void -usage(void) -{ - printf("usage: smbumount mountpoint\n"); -} - -static int -umount_ok(const char *mount_point) -{ - /* we set O_NOFOLLOW to prevent users playing games with symlinks to - umount filesystems they don't own */ - int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0); - __kernel_uid_t mount_uid; - - if (fid == -1) { - fprintf(stderr, "Could not open %s: %s\n", - mount_point, strerror(errno)); - return -1; - } - - if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) { - fprintf(stderr, "%s probably not smb-filesystem\n", - mount_point); - return -1; - } - - if ((getuid() != 0) - && (mount_uid != getuid())) { - fprintf(stderr, "You are not allowed to umount %s\n", - mount_point); - return -1; - } - - close(fid); - return 0; -} - -/* Make a canonical pathname from PATH. Returns a freshly malloced string. - It is up the *caller* to ensure that the PATH is sensible. i.e. - canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.'' - is not a legal pathname for ``/dev/fd0'' Anything we cannot parse - we return unmodified. */ -static char * -canonicalize (char *path) -{ - char *canonical = malloc (PATH_MAX + 1); - - if (!canonical) { - fprintf(stderr, "Error! Not enough memory!\n"); - return NULL; - } - - if (strlen(path) > PATH_MAX) { - fprintf(stderr, "Mount point string too long\n"); - return NULL; - } - - if (path == NULL) - return NULL; - - if (realpath (path, canonical)) - return canonical; - - strncpy (canonical, path, PATH_MAX); - canonical[PATH_MAX] = '\0'; - return canonical; -} - - -int -main(int argc, char *argv[]) -{ - int fd; - char* mount_point; - struct mntent *mnt; - FILE* mtab; - FILE* new_mtab; - - if (argc != 2) { - usage(); - exit(1); - } - - if (geteuid() != 0) { - fprintf(stderr, "smbumount must be installed suid root\n"); - exit(1); - } - - mount_point = canonicalize(argv[1]); - - if (mount_point == NULL) - { - exit(1); - } - - if (umount_ok(mount_point) != 0) { - exit(1); - } - - if (umount(mount_point) != 0) { - fprintf(stderr, "Could not umount %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) - { - fprintf(stderr, "Can't get "MOUNTED"~ lock file"); - return 1; - } - close(fd); - - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { - fprintf(stderr, "Can't open " MOUNTED ": %s\n", - strerror(errno)); - return 1; - } - -#define MOUNTED_TMP MOUNTED".tmp" - - if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { - fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", - strerror(errno)); - endmntent(mtab); - return 1; - } - - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) != 0) { - addmntent(new_mtab, mnt); - } - } - - endmntent(mtab); - - if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { - fprintf(stderr, "Error changing mode of %s: %s\n", - MOUNTED_TMP, strerror(errno)); - exit(1); - } - - endmntent(new_mtab); - - if (rename(MOUNTED_TMP, MOUNTED) < 0) { - fprintf(stderr, "Cannot rename %s to %s: %s\n", - MOUNTED, MOUNTED_TMP, strerror(errno)); - exit(1); - } - - if (unlink(MOUNTED"~") == -1) - { - fprintf(stderr, "Can't remove "MOUNTED"~"); - return 1; - } - - return 0; -} diff --git a/source4/configure.ac b/source4/configure.ac index 82dd1346da..943a7c4345 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -99,6 +99,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = LDB_REQUIRED_VERSION, SMB_INCLUDE_MK(lib/ldb/python.mk) m4_include(lib/tls/config.m4) +m4_include(torture/libnetapi/config.m4) dnl m4_include(auth/kerberos/config.m4) m4_include(auth/gensec/config.m4) diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index a924024160..38858efc7c 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -6,17 +6,17 @@ Copyright (C) Andrew Tridgell 2005 Copyright (C) Volker Lendecke 2004 Copyright (C) Stefan Metzmacher 2004 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -77,20 +77,20 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, ldapsrv_terminate_connection(conn, "no memory"); return; } - + call->request = talloc_steal(call, msg); call->conn = conn; call->replies = NULL; call->send_callback = NULL; call->send_private = NULL; - + /* make the call */ status = ldapsrv_do_call(call); if (!NT_STATUS_IS_OK(status)) { talloc_free(call); return; } - + blob = data_blob(NULL, 0); if (call->replies == NULL) { @@ -210,7 +210,7 @@ static void ldapsrv_send(struct stream_connection *c, uint16_t flags) { struct ldapsrv_connection *conn = talloc_get_type(c->private_data, struct ldapsrv_connection); - + packet_queue_run(conn->packet); } @@ -294,7 +294,7 @@ static int ldapsrv_load_limits(struct ldapsrv_connection *conn) s = sscanf((const char *)el->values[i].data, "%255[^=]=%d", policy_name, &policy_value); if (ret != 2 || policy_value == 0) continue; - + if (strcasecmp("InitRecvTimeout", policy_name) == 0) { conn->limits.initial_timeout = policy_value; continue; @@ -390,7 +390,7 @@ static void ldapsrv_accept(struct stream_connection *c) if (conn->sockets.tls) { packet_set_unreliable_select(conn->packet); } - + /* Ensure we don't get packets until the database is ready below */ packet_recv_disable(conn->packet); @@ -399,7 +399,7 @@ static void ldapsrv_accept(struct stream_connection *c) stream_terminate_connection(c, "Failed to init server credentials\n"); return; } - + cli_credentials_set_conf(server_credentials, conn->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx); if (!NT_STATUS_IS_OK(status)) { @@ -483,7 +483,7 @@ static NTSTATUS add_socket(struct tevent_context *event_context, if (!ldb) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - + if (samdb_is_gc(ldb)) { port = 3268; status = stream_setup_socket(event_context, lp_ctx, diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c index a8d893f085..39bdf047ac 100644 --- a/source4/libcli/security/sddl.c +++ b/source4/libcli/security/sddl.c @@ -80,11 +80,34 @@ static const struct { { "CO", SID_CREATOR_OWNER }, { "CG", SID_CREATOR_GROUP }, + { "AN", SID_NT_ANONYMOUS }, + { "BG", SID_BUILTIN_GUESTS }, + { "BO", SID_BUILTIN_BACKUP_OPERATORS }, + { "BU", SID_BUILTIN_USERS }, + { "IU", SID_NT_INTERACTIVE }, + { "LS", SID_NT_LOCAL_SERVICE }, + { "NO", SID_BUILTIN_NETWORK_CONF_OPERATORS }, + { "NS", SID_NT_NETWORK_SERVICE }, + { "NU", SID_NT_NETWORK }, + { "PU", SID_BUILTIN_POWER_USERS }, + { "RC", SID_NT_RESTRICTED }, + { "RD", SID_BUILTIN_REMOTE_DESKTOP_USERS }, + { "RE", SID_BUILTIN_REPLICATOR }, + { "SO", SID_BUILTIN_ACCOUNT_OPERATORS }, + { "SU", SID_NT_SERVICE }, + { "DA", NULL, DOMAIN_RID_ADMINS }, { "EA", NULL, DOMAIN_RID_ENTERPRISE_ADMINS }, { "DD", NULL, DOMAIN_RID_DCS }, { "DU", NULL, DOMAIN_RID_USERS }, { "CA", NULL, DOMAIN_RID_CERT_ADMINS }, + + { "DC", NULL, DOMAIN_RID_DOMAIN_MEMBERS }, + { "DG", NULL, DOMAIN_RID_GUESTS }, + { "LA", NULL, DOMAIN_RID_ADMINISTRATOR }, + { "LG", NULL, DOMAIN_RID_GUEST }, + { "PA", NULL, DOMAIN_RID_POLICY_ADMINS }, + { "SA", NULL, DOMAIN_RID_SCHEMA_ADMINS }, }; /* diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk index 00df5dbb22..af4d3eff82 100644 --- a/source4/libcli/wbclient/config.mk +++ b/source4/libcli/wbclient/config.mk @@ -1,5 +1,5 @@ -[SUBSYSTEM::LIBWBCLIENT] +[SUBSYSTEM::LIBWBCLIENT_OLD] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING -LIBWBCLIENT_OBJ_FILES = $(libclisrcdir)/wbclient/wbclient.o +LIBWBCLIENT_OLD_OBJ_FILES = $(libclisrcdir)/wbclient/wbclient.o diff --git a/source4/main.mk b/source4/main.mk index 2e74ba9a5b..b4a82017c8 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -7,6 +7,7 @@ mkinclude smbd/process_model.mk mkinclude libnet/config.mk mkinclude auth/config.mk mkinclude ../nsswitch/config.mk +mkinclude ../nsswitch/libwbclient/config.mk mkinclude lib/samba3/config.mk mkinclude lib/socket/config.mk mkinclude ../lib/util/charset/config.mk diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 1d7949214a..1aaef3f1d4 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -42,7 +42,7 @@ OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init #PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING \ - LIBWBCLIENT pvfs_acl pvfs_aio + LIBWBCLIENT_OLD pvfs_acl pvfs_aio # End MODULE ntvfs_posix ################################################ diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index dfc3d17bed..f3dc074125 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -85,7 +85,7 @@ PRIVATE_DEPENDENCIES = \ SAMDB \ NDR_UNIXINFO \ NSS_WRAPPER \ - LIBWBCLIENT + LIBWBCLIENT_OLD # End MODULE dcerpc_unixinfo ################################################ diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index fabc88d02d..03acf97cab 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -1213,6 +1213,9 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL if (d_state->builtin) { DEBUG(5, ("Cannot create a user in the BUILTIN domain")); return NT_STATUS_ACCESS_DENIED; + } else if (r->in.acct_flags == ACB_DOMTRUST) { + /* Domain trust accounts must be created by the LSA calls */ + return NT_STATUS_ACCESS_DENIED; } account_name = r->in.account_name->string; @@ -1220,6 +1223,11 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL return NT_STATUS_INVALID_PARAMETER; } + /* + * Start a transaction, so we can query and do a subsequent atomic + * modify + */ + ret = ldb_transaction_start(d_state->sam_ctx); if (ret != 0) { DEBUG(0,("Failed to start a transaction for user creation: %s\n", @@ -1258,6 +1266,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL } else if (r->in.acct_flags == ACB_WSTRUST) { if (cn_name[cn_name_len - 1] != '$') { + ldb_transaction_cancel(d_state->sam_ctx); return NT_STATUS_FOOBAR; } cn_name[cn_name_len - 1] = '\0'; @@ -1267,17 +1276,13 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL } else if (r->in.acct_flags == ACB_SVRTRUST) { if (cn_name[cn_name_len - 1] != '$') { + ldb_transaction_cancel(d_state->sam_ctx); return NT_STATUS_FOOBAR; } cn_name[cn_name_len - 1] = '\0'; container = "OU=Domain Controllers"; obj_class = "computer"; samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, "primaryGroupID", DOMAIN_RID_DCS); - - } else if (r->in.acct_flags == ACB_DOMTRUST) { - container = "CN=Users"; - obj_class = "user"; - } else { ldb_transaction_cancel(d_state->sam_ctx); return NT_STATUS_INVALID_PARAMETER; @@ -1292,9 +1297,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", account_name); samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", obj_class); - - /* Start a transaction, so we can query and do a subsequent atomic modify */ - + /* create the user */ ret = ldb_add(d_state->sam_ctx, msg); switch (ret) { diff --git a/source4/selftest/tests.sh b/source4/selftest/tests.sh index 79199bc2c0..58cdc0898b 100755 --- a/source4/selftest/tests.sh +++ b/source4/selftest/tests.sh @@ -117,7 +117,7 @@ plantest "ldb" none TEST_DATA_PREFIX=\$PREFIX $LDBDIR/tests/test-tdb.sh ncacn_np_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-SAMSYNC RPC-SAMBA3SESSIONKEY RPC-SAMBA3-GETUSERNAME RPC-SAMBA3-LSA RPC-BINDSAMBA3 RPC-NETLOGSAMBA3 RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT" ncalrpc_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-DRSUAPI RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT" ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-DSSYNC RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT RPC-OBJECTUUID" -slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS" +slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-USERS-PRIVILEGES RPC-SAMR-PASSWORDS RPC-SAMR-PASSWORDS-PWDLASTSET" slow_ncalrpc_tests="RPC-SAMR RPC-SAMR-PASSWORDS" slow_ncacn_ip_tcp_tests="RPC-SAMR RPC-SAMR-PASSWORDS RPC-CRACKNAMES" diff --git a/source4/setup/provision_configuration.ldif b/source4/setup/provision_configuration.ldif index 63b807ba4a..fff380505f 100644 --- a/source4/setup/provision_configuration.ldif +++ b/source4/setup/provision_configuration.ldif @@ -96,21 +96,15 @@ dn: CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: container cn: Extended-Rights -instanceType: 4 -showInAdvancedViewOnly: TRUE systemFlags: -2147483648 -objectCategory: CN=Container,CN=Schema,${CONFIGDN} dn: CN=Change-Rid-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-Rid-Master -instanceType: 4 displayName: Change Rid Master -showInAdvancedViewOnly: TRUE rightsGuid: d58d5f36-0a98-11d1-adbb-00c04fd8d5cd appliesTo: 6617188d-8f3c-11d0-afda-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 29 validAccesses: 256 @@ -118,12 +112,9 @@ dn: CN=Do-Garbage-Collection,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Do-Garbage-Collection -instanceType: 4 displayName: Do Garbage Collection -showInAdvancedViewOnly: TRUE rightsGuid: fec364e0-0a98-11d1-adbb-00c04fd8d5cd appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 31 validAccesses: 256 @@ -131,12 +122,9 @@ dn: CN=Recalculate-Hierarchy,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Recalculate-Hierarchy -instanceType: 4 displayName: Recalculate Hierarchy -showInAdvancedViewOnly: TRUE rightsGuid: 0bc1554e-0a99-11d1-adbb-00c04fd8d5cd appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 32 validAccesses: 256 @@ -144,12 +132,9 @@ dn: CN=Allocate-Rids,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Allocate-Rids -instanceType: 4 displayName: Allocate Rids -showInAdvancedViewOnly: TRUE rightsGuid: 1abd7cf8-0a99-11d1-adbb-00c04fd8d5cd appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 33 validAccesses: 256 @@ -157,12 +142,9 @@ dn: CN=Change-PDC,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-PDC -instanceType: 4 displayName: Change PDC -showInAdvancedViewOnly: TRUE rightsGuid: bae50096-4752-11d1-9052-00c04fc2d4cf appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 34 validAccesses: 256 @@ -170,12 +152,9 @@ dn: CN=Add-GUID,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Add-GUID -instanceType: 4 displayName: Add GUID -showInAdvancedViewOnly: TRUE rightsGuid: 440820ad-65b4-11d1-a3da-0000f875ae0d appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 35 validAccesses: 256 @@ -183,12 +162,9 @@ dn: CN=Change-Domain-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-Domain-Master -instanceType: 4 displayName: Change Domain Master -showInAdvancedViewOnly: TRUE rightsGuid: 014bf69c-7b3b-11d1-85f6-08002be74fab appliesTo: ef9e60e0-56f7-11d1-a9c6-0000f80367c1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 36 validAccesses: 256 @@ -196,14 +172,11 @@ dn: CN=Public-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Public-Information -instanceType: 4 displayName: Public Information -showInAdvancedViewOnly: TRUE rightsGuid: e48d0154-bcf8-11d1-8702-00c04fb96050 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 37 validAccesses: 48 @@ -211,12 +184,9 @@ dn: CN=msmq-Receive-Dead-Letter,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Receive-Dead-Letter -instanceType: 4 displayName: Receive Dead Letter -showInAdvancedViewOnly: TRUE rightsGuid: 4b6e08c0-df3c-11d1-9c86-006008764d0e appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 38 validAccesses: 256 @@ -224,12 +194,9 @@ dn: CN=msmq-Peek-Dead-Letter,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Peek-Dead-Letter -instanceType: 4 displayName: Peek Dead Letter -showInAdvancedViewOnly: TRUE rightsGuid: 4b6e08c1-df3c-11d1-9c86-006008764d0e appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 39 validAccesses: 256 @@ -237,12 +204,9 @@ dn: CN=msmq-Receive-computer-Journal,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Receive-computer-Journal -instanceType: 4 displayName: Receive Computer Journal -showInAdvancedViewOnly: TRUE rightsGuid: 4b6e08c2-df3c-11d1-9c86-006008764d0e appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 40 validAccesses: 256 @@ -250,12 +214,9 @@ dn: CN=msmq-Peek-computer-Journal,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Peek-computer-Journal -instanceType: 4 displayName: Peek Computer Journal -showInAdvancedViewOnly: TRUE rightsGuid: 4b6e08c3-df3c-11d1-9c86-006008764d0e appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 41 validAccesses: 256 @@ -263,12 +224,9 @@ dn: CN=msmq-Receive,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Receive -instanceType: 4 displayName: Receive Message -showInAdvancedViewOnly: TRUE rightsGuid: 06bd3200-df3e-11d1-9c86-006008764d0e appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 42 validAccesses: 256 @@ -276,12 +234,9 @@ dn: CN=msmq-Peek,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Peek -instanceType: 4 displayName: Peek Message -showInAdvancedViewOnly: TRUE rightsGuid: 06bd3201-df3e-11d1-9c86-006008764d0e appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 43 validAccesses: 256 @@ -289,13 +244,10 @@ dn: CN=msmq-Send,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Send -instanceType: 4 displayName: Send Message -showInAdvancedViewOnly: TRUE rightsGuid: 06bd3202-df3e-11d1-9c86-006008764d0e appliesTo: 46b27aac-aafa-4ffb-b773-e5bf621ee87b appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 44 validAccesses: 256 @@ -303,12 +255,9 @@ dn: CN=msmq-Receive-journal,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Receive-journal -instanceType: 4 displayName: Receive Journal -showInAdvancedViewOnly: TRUE rightsGuid: 06bd3203-df3e-11d1-9c86-006008764d0e appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 45 validAccesses: 256 @@ -316,12 +265,9 @@ dn: CN=msmq-Open-Connector,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: msmq-Open-Connector -instanceType: 4 displayName: Open Connector Queue -showInAdvancedViewOnly: TRUE rightsGuid: b4e60130-df3f-11d1-9c86-006008764d0e appliesTo: bf967ab3-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 46 validAccesses: 256 @@ -329,12 +275,9 @@ dn: CN=Apply-Group-Policy,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Apply-Group-Policy -instanceType: 4 displayName: Apply Group Policy -showInAdvancedViewOnly: TRUE rightsGuid: edacfd8f-ffb3-11d1-b41d-00a0c968f939 appliesTo: f30e3bc2-9ff0-11d1-b603-0000f80367c1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 47 validAccesses: 256 @@ -342,13 +285,10 @@ dn: CN=RAS-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: RAS-Information -instanceType: 4 displayName: Remote Access Information -showInAdvancedViewOnly: TRUE rightsGuid: 037088f8-0ae1-11d2-b422-00a0c968f939 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 48 validAccesses: 48 @@ -356,12 +296,9 @@ dn: CN=DS-Install-Replica,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Install-Replica -instanceType: 4 displayName: Add/Remove Replica In Domain -showInAdvancedViewOnly: TRUE rightsGuid: 9923a32a-3607-11d2-b9be-0000f87a36b2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 49 validAccesses: 256 @@ -369,12 +306,9 @@ dn: CN=Change-Infrastructure-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-Infrastructure-Master -instanceType: 4 displayName: Change Infrastructure Master -showInAdvancedViewOnly: TRUE rightsGuid: cc17b1fb-33d9-11d2-97d4-00c04fd8d5cd appliesTo: 2df90d89-009f-11d2-aa4c-00c04fd7d83a -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 50 validAccesses: 256 @@ -382,12 +316,9 @@ dn: CN=Update-Schema-Cache,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Update-Schema-Cache -instanceType: 4 displayName: Update Schema Cache -showInAdvancedViewOnly: TRUE rightsGuid: be2bb760-7f46-11d2-b9ad-00c04f79f805 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 51 validAccesses: 256 @@ -395,12 +326,9 @@ dn: CN=Recalculate-Security-Inheritance,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Recalculate-Security-Inheritance -instanceType: 4 displayName: Recalculate Security Inheritance -showInAdvancedViewOnly: TRUE rightsGuid: 62dd28a8-7f46-11d2-b9ad-00c04f79f805 appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 52 validAccesses: 256 @@ -408,12 +336,9 @@ dn: CN=DS-Check-Stale-Phantoms,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Check-Stale-Phantoms -instanceType: 4 displayName: Check Stale Phantoms -showInAdvancedViewOnly: TRUE rightsGuid: 69ae6200-7f46-11d2-b9ad-00c04f79f805 appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 53 validAccesses: 256 @@ -421,12 +346,9 @@ dn: CN=Certificate-Enrollment,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Certificate-Enrollment -instanceType: 4 displayName: Enroll -showInAdvancedViewOnly: TRUE rightsGuid: 0e10c968-78fb-11d2-90d4-00c04f79dc55 appliesTo: e5209ca2-3bba-11d2-90cc-00c04fd91ab1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 54 validAccesses: 256 @@ -434,12 +356,9 @@ dn: CN=Self-Membership,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Self-Membership -instanceType: 4 displayName: Add/Remove self as member -showInAdvancedViewOnly: TRUE rightsGuid: bf9679c0-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 12 validAccesses: 8 @@ -447,12 +366,9 @@ dn: CN=Validated-DNS-Host-Name,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Validated-DNS-Host-Name -instanceType: 4 displayName: Validated write to DNS host name -showInAdvancedViewOnly: TRUE rightsGuid: 72e39547-7b18-11d1-adef-00c04fd8d5cd appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 13 validAccesses: 8 @@ -460,12 +376,9 @@ dn: CN=Validated-SPN,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Validated-SPN -instanceType: 4 displayName: Validated write to service principal name -showInAdvancedViewOnly: TRUE rightsGuid: f3a64788-5306-11d1-a9c5-0000f80367c1 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 14 validAccesses: 8 @@ -473,13 +386,10 @@ dn: CN=Generate-RSoP-Planning,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Generate-RSoP-Planning -instanceType: 4 displayName: Generate Resultant Set of Policy (Planning) -showInAdvancedViewOnly: TRUE rightsGuid: b7b1b3dd-ab09-4242-9e30-9980e5d322f7 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 appliesTo: bf967aa5-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 55 validAccesses: 256 @@ -487,12 +397,9 @@ dn: CN=Refresh-Group-Cache,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Refresh-Group-Cache -instanceType: 4 displayName: Refresh Group Cache for Logons -showInAdvancedViewOnly: TRUE rightsGuid: 9432c620-033c-4db7-8b58-14ef6d0bf477 appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 56 validAccesses: 256 @@ -500,12 +407,9 @@ dn: CN=SAM-Enumerate-Entire-Domain,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: SAM-Enumerate-Entire-Domain -instanceType: 4 displayName: Enumerate Entire SAM Domain -showInAdvancedViewOnly: TRUE rightsGuid: 91d67418-0135-4acc-8d79-c08e857cfbec appliesTo: bf967aad-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 57 validAccesses: 256 @@ -513,13 +417,10 @@ dn: CN=Generate-RSoP-Logging,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Generate-RSoP-Logging -instanceType: 4 displayName: Generate Resultant Set of Policy (Logging) -showInAdvancedViewOnly: TRUE rightsGuid: b7b1b3de-ab09-4242-9e30-9980e5d322f7 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 appliesTo: bf967aa5-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 58 validAccesses: 256 @@ -527,12 +428,9 @@ dn: CN=Domain-Other-Parameters,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Domain-Other-Parameters -instanceType: 4 displayName: Other Domain Parameters (for use by SAM) -showInAdvancedViewOnly: TRUE rightsGuid: b8119fd0-04f6-4762-ab7a-4986c76b3f9a appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 59 validAccesses: 48 @@ -540,12 +438,9 @@ dn: CN=DNS-Host-Name-Attributes,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DNS-Host-Name-Attributes -instanceType: 4 displayName: DNS Host Name Attributes -showInAdvancedViewOnly: TRUE rightsGuid: 72e39547-7b18-11d1-adef-00c04fd8d5cd appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 60 validAccesses: 48 @@ -553,12 +448,9 @@ dn: CN=Create-Inbound-Forest-Trust,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Create-Inbound-Forest-Trust -instanceType: 4 displayName: Create Inbound Forest Trust -showInAdvancedViewOnly: TRUE rightsGuid: e2a36dc9-ae17-47c3-b58b-be34c55ba633 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 61 validAccesses: 256 @@ -566,14 +458,11 @@ dn: CN=DS-Replication-Get-Changes-All,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Get-Changes-All -instanceType: 4 displayName: Replicating Directory Changes All -showInAdvancedViewOnly: TRUE rightsGuid: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 62 validAccesses: 256 @@ -581,12 +470,9 @@ dn: CN=Migrate-SID-History,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Migrate-SID-History -instanceType: 4 displayName: Migrate SID History -showInAdvancedViewOnly: TRUE rightsGuid: BA33815A-4F93-4c76-87F3-57574BFF8109 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 63 validAccesses: 256 @@ -594,14 +480,11 @@ dn: CN=Reanimate-Tombstones,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Reanimate-Tombstones -instanceType: 4 displayName: Reanimate Tombstones -showInAdvancedViewOnly: TRUE rightsGuid: 45EC5156-DB7E-47bb-B53F-DBEB2D03C40F appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 64 validAccesses: 256 @@ -609,14 +492,11 @@ dn: CN=Allowed-To-Authenticate,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Allowed-To-Authenticate -instanceType: 4 displayName: Allowed to Authenticate -showInAdvancedViewOnly: TRUE rightsGuid: 68B1D179-0D15-4d4f-AB71-46152E79A7BC appliesTo: 4828cc14-1437-45bc-9b07-ad6f015e5f28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 65 validAccesses: 256 @@ -624,12 +504,9 @@ dn: CN=DS-Execute-Intentions-Script,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Execute-Intentions-Script -instanceType: 4 displayName: Execute Forest Update Script -showInAdvancedViewOnly: TRUE rightsGuid: 2f16c4a5-b98e-432c-952a-cb388ba33f2e appliesTo: ef9e60e0-56f7-11d1-a9c6-0000f80367c1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 66 validAccesses: 256 @@ -637,14 +514,11 @@ dn: CN=DS-Replication-Monitor-Topology,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Monitor-Topology -instanceType: 4 displayName: Monitor Active Directory Replication -showInAdvancedViewOnly: TRUE rightsGuid: f98340fb-7c5b-4cdb-a00b-2ebdfa115a96 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 67 validAccesses: 256 @@ -652,12 +526,9 @@ dn: CN=Update-Password-Not-Required-Bit,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Update-Password-Not-Required-Bit -instanceType: 4 displayName: Update Password Not Required Bit -showInAdvancedViewOnly: TRUE rightsGuid: 280f369c-67c7-438e-ae98-1d46f3c6f541 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 68 validAccesses: 256 @@ -665,12 +536,9 @@ dn: CN=Unexpire-Password,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Unexpire-Password -instanceType: 4 displayName: Unexpire Password -showInAdvancedViewOnly: TRUE rightsGuid: ccc2dc7d-a6ad-4a7a-8846-c04e3cc53501 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 69 validAccesses: 256 @@ -678,12 +546,9 @@ dn: CN=Enable-Per-User-Reversibly-Encrypted-Password,CN=Extended-Rights,${CONFIG objectClass: top objectClass: controlAccessRight cn: Enable-Per-User-Reversibly-Encrypted-Password -instanceType: 4 displayName: Enable Per User Reversibly Encrypted Password -showInAdvancedViewOnly: TRUE rightsGuid: 05c74c5e-4deb-43b4-bd9f-86664c2a7fd5 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 70 validAccesses: 256 @@ -691,12 +556,9 @@ dn: CN=DS-Query-Self-Quota,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Query-Self-Quota -instanceType: 4 displayName: Query Self Quota -showInAdvancedViewOnly: TRUE rightsGuid: 4ecc03fe-ffc0-4947-b630-eb672a8a9dbc appliesTo: da83fc4f-076f-4aea-b4dc-8f4dab9b5993 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 71 validAccesses: 256 @@ -704,12 +566,9 @@ dn: CN=Domain-Administer-Server,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Domain-Administer-Server -instanceType: 4 displayName: Domain Administer Server -showInAdvancedViewOnly: TRUE rightsGuid: ab721a52-1e2f-11d0-9819-00aa0040529b appliesTo: bf967aad-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 1 validAccesses: 256 @@ -717,14 +576,11 @@ dn: CN=User-Change-Password,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: User-Change-Password -instanceType: 4 displayName: Change Password -showInAdvancedViewOnly: TRUE rightsGuid: ab721a53-1e2f-11d0-9819-00aa0040529b appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 2 validAccesses: 256 @@ -732,14 +588,11 @@ dn: CN=User-Force-Change-Password,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: User-Force-Change-Password -instanceType: 4 displayName: Reset Password -showInAdvancedViewOnly: TRUE rightsGuid: 00299570-246d-11d0-a768-00aa006e0529 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 3 validAccesses: 256 @@ -747,14 +600,11 @@ dn: CN=Send-As,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Send-As -instanceType: 4 displayName: Send As -showInAdvancedViewOnly: TRUE rightsGuid: ab721a54-1e2f-11d0-9819-00aa0040529b appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 4 validAccesses: 256 @@ -762,14 +612,11 @@ dn: CN=Receive-As,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Receive-As -instanceType: 4 displayName: Receive As -showInAdvancedViewOnly: TRUE rightsGuid: ab721a56-1e2f-11d0-9819-00aa0040529b appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 5 validAccesses: 256 @@ -777,12 +624,9 @@ dn: CN=Send-To,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Send-To -instanceType: 4 displayName: Send To -showInAdvancedViewOnly: TRUE rightsGuid: ab721a55-1e2f-11d0-9819-00aa0040529b appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 6 validAccesses: 256 @@ -790,13 +634,10 @@ dn: CN=Domain-Password,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Domain-Password -instanceType: 4 displayName: Domain Password & Lockout Policies -showInAdvancedViewOnly: TRUE rightsGuid: c7407360-20bf-11d0-a768-00aa006e0529 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 appliesTo: 19195a5a-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 7 validAccesses: 48 @@ -804,13 +645,10 @@ dn: CN=General-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: General-Information -instanceType: 4 displayName: General Information -showInAdvancedViewOnly: TRUE rightsGuid: 59ba2f42-79a2-11d0-9020-00c04fc2d3cf appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 8 validAccesses: 48 @@ -818,14 +656,11 @@ dn: CN=User-Account-Restrictions,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: User-Account-Restrictions -instanceType: 4 displayName: Account Restrictions -showInAdvancedViewOnly: TRUE rightsGuid: 4c164200-20c0-11d0-a768-00aa006e0529 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 9 validAccesses: 48 @@ -833,13 +668,10 @@ dn: CN=User-Logon,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: User-Logon -instanceType: 4 displayName: Logon Information -showInAdvancedViewOnly: TRUE rightsGuid: 5f202010-79a5-11d0-9020-00c04fc2d4cf appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 10 validAccesses: 48 @@ -847,13 +679,10 @@ dn: CN=Membership,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Membership -instanceType: 4 displayName: Group Membership -showInAdvancedViewOnly: TRUE rightsGuid: bc0ac240-79a9-11d0-9020-00c04fc2d4cf appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 11 validAccesses: 48 @@ -861,12 +690,9 @@ dn: CN=Open-Address-Book,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Open-Address-Book -instanceType: 4 displayName: Open Address List -showInAdvancedViewOnly: TRUE rightsGuid: a1990816-4298-11d1-ade2-00c04fd8d5cd appliesTo: 3e74f60f-3e73-11d1-a9c0-0000f80367c1 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 21 validAccesses: 256 @@ -874,15 +700,12 @@ dn: CN=Personal-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Personal-Information -instanceType: 4 displayName: Personal Information -showInAdvancedViewOnly: TRUE rightsGuid: 77B5B886-944A-11d1-AEBD-0000F80367C1 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2 appliesTo: 5cb41ed0-0e4c-11d0-a286-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 23 validAccesses: 48 @@ -890,14 +713,11 @@ dn: CN=Email-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Email-Information -instanceType: 4 displayName: Phone and Mail Options -showInAdvancedViewOnly: TRUE rightsGuid: E45795B2-9455-11d1-AEBD-0000F80367C1 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 22 validAccesses: 48 @@ -905,14 +725,11 @@ dn: CN=Web-Information,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Web-Information -instanceType: 4 displayName: Web Information -showInAdvancedViewOnly: TRUE rightsGuid: E45795B3-9455-11d1-AEBD-0000F80367C1 appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28 appliesTo: 5cb41ed0-0e4c-11d0-a286-00aa003049e2 appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 24 validAccesses: 48 @@ -920,14 +737,11 @@ dn: CN=DS-Replication-Get-Changes,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Get-Changes -instanceType: 4 displayName: Replicating Directory Changes -showInAdvancedViewOnly: TRUE rightsGuid: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 25 validAccesses: 256 @@ -935,14 +749,11 @@ dn: CN=DS-Replication-Synchronize,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Synchronize -instanceType: 4 displayName: Replication Synchronization -showInAdvancedViewOnly: TRUE rightsGuid: 1131f6ab-9c07-11d1-f79f-00c04fc2dcd2 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 26 validAccesses: 256 @@ -950,14 +761,11 @@ dn: CN=DS-Replication-Manage-Topology,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: DS-Replication-Manage-Topology -instanceType: 4 displayName: Manage Replication Topology -showInAdvancedViewOnly: TRUE rightsGuid: 1131f6ac-9c07-11d1-f79f-00c04fc2dcd2 appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2 appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 27 validAccesses: 256 @@ -965,11 +773,8 @@ dn: CN=Change-Schema-Master,CN=Extended-Rights,${CONFIGDN} objectClass: top objectClass: controlAccessRight cn: Change-Schema-Master -instanceType: 4 displayName: Change Schema Master -showInAdvancedViewOnly: TRUE rightsGuid: e12b56b6-0a95-11d1-adbb-00c04fd8d5cd appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2 -objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN} localizationDisplayId: 28 validAccesses: 256 diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 72747a7886..dd1d5ea817 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -89,6 +89,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/raw/proto.h,$(TORTURE_RAW_O mkinclude smb2/config.mk mkinclude winbind/config.mk +mkinclude libnetapi/config.mk [SUBSYSTEM::TORTURE_NDR] PRIVATE_DEPENDENCIES = torture SERVICE_SMB diff --git a/source4/torture/libnetapi/config.m4 b/source4/torture/libnetapi/config.m4 new file mode 100644 index 0000000000..43724908ca --- /dev/null +++ b/source4/torture/libnetapi/config.m4 @@ -0,0 +1,28 @@ +############################### +# start SMB_EXT_LIB_NETAPI +# check for netapi.h and -lnetapi + +use_netapi=auto +AC_ARG_ENABLE(netapi, +AS_HELP_STRING([--enable-netapi],[Turn on netapi support (default=yes)]), + [if test x$enable_netapi = xno; then + use_netapi=no + fi]) + + +#if test x$use_netapi = xauto && pkg-config --exists netapi; then +# SMB_EXT_LIB_FROM_PKGCONFIG(NETAPI, netapi < 0.1, +# [use_netapi=yes], +# [use_netapi=no]) +#fi + +if test x$use_netapi = xauto; then + AC_CHECK_HEADERS(netapi.h) + AC_CHECK_LIB_EXT(netapi, NETAPI_LIBS, libnetapi_init) + if test x"$ac_cv_header_netapi_h" = x"yes" -a x"$ac_cv_lib_ext_netapi_libnetapi_init" = x"yes";then + SMB_ENABLE(NETAPI,YES) + else + SMB_ENABLE(TORTURE_LIBNETAPI,NO) + fi + SMB_EXT_LIB(NETAPI, $NETAPI_LIBS) +fi diff --git a/source4/torture/libnetapi/config.mk b/source4/torture/libnetapi/config.mk new file mode 100644 index 0000000000..2ac506e1b2 --- /dev/null +++ b/source4/torture/libnetapi/config.mk @@ -0,0 +1,17 @@ +################################# +# Start SUBSYSTEM TORTURE_LIBNETAPI +[MODULE::TORTURE_LIBNETAPI] +SUBSYSTEM = smbtorture +OUTPUT_TYPE = MERGED_OBJ +INIT_FUNCTION = torture_libnetapi_init +PRIVATE_DEPENDENCIES = \ + POPT_CREDENTIALS \ + NETAPI +# End SUBSYSTEM TORTURE_LIBNETAPI +################################# + +TORTURE_LIBNETAPI_OBJ_FILES = $(addprefix $(torturesrcdir)/libnetapi/, libnetapi.o \ + libnetapi_user.o \ + libnetapi_group.o) + +$(eval $(call proto_header_template,$(torturesrcdir)/libnetapi/proto.h,$(TORTURE_LIBNETAPI_OBJ_FILES:.o=.c))) diff --git a/source4/torture/libnetapi/libnetapi.c b/source4/torture/libnetapi/libnetapi.c new file mode 100644 index 0000000000..c3a27eba0c --- /dev/null +++ b/source4/torture/libnetapi/libnetapi.c @@ -0,0 +1,80 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Guenther Deschner 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "torture/smbtorture.h" +#include "auth/credentials/credentials.h" +#include "lib/cmdline/popt_common.h" +#include <netapi.h> +#include "torture/libnetapi/proto.h" + +bool torture_libnetapi_init_context(struct torture_context *tctx, + struct libnetapi_ctx **ctx_p) +{ + NET_API_STATUS status; + struct libnetapi_ctx *ctx; + + status = libnetapi_init(&ctx); + if (status != 0) { + return false; + } + + libnetapi_set_debuglevel(ctx, + talloc_asprintf(ctx, "%d", DEBUGLEVEL)); + libnetapi_set_username(ctx, + cli_credentials_get_username(cmdline_credentials)); + libnetapi_set_password(ctx, + cli_credentials_get_password(cmdline_credentials)); + + *ctx_p = ctx; + + return true; +} + +static bool torture_libnetapi_initialize(struct torture_context *tctx) +{ + NET_API_STATUS status; + struct libnetapi_ctx *ctx; + + status = libnetapi_init(&ctx); + if (status != 0) { + return false; + } + + libnetapi_free(ctx); + + return true; +} + +NTSTATUS torture_libnetapi_init(void) +{ + struct torture_suite *suite; + + suite = torture_suite_create(talloc_autofree_context(), "NETAPI"); + + torture_suite_add_simple_test(suite, "GROUP", torture_libnetapi_group); + torture_suite_add_simple_test(suite, "USER", torture_libnetapi_user); + torture_suite_add_simple_test(suite, "INITIALIZE", torture_libnetapi_initialize); + + suite->description = talloc_strdup(suite, "libnetapi convenience interface tests"); + + torture_register_suite(suite); + + return NT_STATUS_OK; +} diff --git a/source4/torture/libnetapi/libnetapi_group.c b/source4/torture/libnetapi/libnetapi_group.c new file mode 100644 index 0000000000..e8e5ad931a --- /dev/null +++ b/source4/torture/libnetapi/libnetapi_group.c @@ -0,0 +1,520 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Guenther Deschner 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "torture/smbtorture.h" +#include <netapi.h> +#include "torture/libnetapi/proto.h" + +#define TORTURE_TEST_USER "testuser" + +#define NETAPI_STATUS(tctx, x,y,fn) \ + torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \ + __LINE__, fn, libnetapi_get_error_string(x,y), y); + +#define NETAPI_STATUS_MSG(tctx, x,y,fn,z) \ + torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d), %s\n", \ + __LINE__, fn, libnetapi_get_error_string(x,y), y, z); + +static NET_API_STATUS test_netgroupenum(struct torture_context *tctx, + const char *hostname, + uint32_t level, + const char *groupname) +{ + NET_API_STATUS status; + uint32_t entries_read = 0; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + int found_group = 0; + const char *current_name = NULL; + uint8_t *buffer = NULL; + int i; + + struct GROUP_INFO_0 *info0 = NULL; + struct GROUP_INFO_1 *info1 = NULL; + struct GROUP_INFO_2 *info2 = NULL; + struct GROUP_INFO_3 *info3 = NULL; + + torture_comment(tctx, "testing NetGroupEnum level %d\n", level); + + do { + status = NetGroupEnum(hostname, + level, + &buffer, + (uint32_t)-1, + &entries_read, + &total_entries, + &resume_handle); + if (status == 0 || status == ERROR_MORE_DATA) { + switch (level) { + case 0: + info0 = (struct GROUP_INFO_0 *)buffer; + break; + case 1: + info1 = (struct GROUP_INFO_1 *)buffer; + break; + case 2: + info2 = (struct GROUP_INFO_2 *)buffer; + break; + case 3: + info3 = (struct GROUP_INFO_3 *)buffer; + break; + default: + return -1; + } + + for (i=0; i<entries_read; i++) { + + switch (level) { + case 0: + current_name = info0->grpi0_name; + break; + case 1: + current_name = info1->grpi1_name; + break; + case 2: + current_name = info2->grpi2_name; + break; + case 3: + current_name = info3->grpi3_name; + break; + default: + break; + } + + if (strcasecmp(current_name, groupname) == 0) { + found_group = 1; + } + + switch (level) { + case 0: + info0++; + break; + case 1: + info1++; + break; + case 2: + info2++; + break; + case 3: + info3++; + break; + } + } + NetApiBufferFree(buffer); + } + } while (status == ERROR_MORE_DATA); + + if (status) { + return status; + } + + if (!found_group) { + torture_comment(tctx, "failed to get group\n"); + return -1; + } + + return 0; +} + +static NET_API_STATUS test_netgroupgetusers(struct torture_context *tctx, + const char *hostname, + uint32_t level, + const char *groupname, + const char *username) +{ + NET_API_STATUS status; + uint32_t entries_read = 0; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + int found_user = 0; + const char *current_name = NULL; + uint8_t *buffer = NULL; + int i; + + struct GROUP_USERS_INFO_0 *info0 = NULL; + struct GROUP_USERS_INFO_1 *info1 = NULL; + + torture_comment(tctx, "testing NetGroupGetUsers level %d\n", level); + + do { + status = NetGroupGetUsers(hostname, + groupname, + level, + &buffer, + (uint32_t)-1, + &entries_read, + &total_entries, + &resume_handle); + if (status == 0 || status == ERROR_MORE_DATA) { + + switch (level) { + case 0: + info0 = (struct GROUP_USERS_INFO_0 *)buffer; + break; + case 1: + info1 = (struct GROUP_USERS_INFO_1 *)buffer; + break; + default: + break; + } + for (i=0; i<entries_read; i++) { + switch (level) { + case 0: + current_name = info0->grui0_name; + break; + case 1: + current_name = info1->grui1_name; + break; + default: + break; + } + + if (username && strcasecmp(current_name, username) == 0) { + found_user = 1; + } + + switch (level) { + case 0: + info0++; + break; + case 1: + info1++; + break; + } + } + NetApiBufferFree(buffer); + } + } while (status == ERROR_MORE_DATA); + + if (status) { + return status; + } + + if (username && !found_user) { + torture_comment(tctx, "failed to get user\n"); + return -1; + } + + return 0; +} + +static NET_API_STATUS test_netgroupsetusers(struct torture_context *tctx, + const char *hostname, + const char *groupname, + uint32_t level, + size_t num_entries, + const char **names) +{ + NET_API_STATUS status; + uint8_t *buffer = NULL; + int i = 0; + size_t buf_size = 0; + + struct GROUP_USERS_INFO_0 *g0 = NULL; + struct GROUP_USERS_INFO_1 *g1 = NULL; + + torture_comment(tctx, "testing NetGroupSetUsers level %d\n", level); + + switch (level) { + case 0: + buf_size = sizeof(struct GROUP_USERS_INFO_0) * num_entries; + + status = NetApiBufferAllocate(buf_size, (void **)&g0); + if (status) { + goto out; + } + + for (i=0; i<num_entries; i++) { + g0[i].grui0_name = names[i]; + } + + buffer = (uint8_t *)g0; + break; + case 1: + buf_size = sizeof(struct GROUP_USERS_INFO_1) * num_entries; + + status = NetApiBufferAllocate(buf_size, (void **)&g1); + if (status) { + goto out; + } + + for (i=0; i<num_entries; i++) { + g1[i].grui1_name = names[i]; + } + + buffer = (uint8_t *)g1; + break; + default: + break; + } + + /* NetGroupSetUsers */ + + status = NetGroupSetUsers(hostname, + groupname, + level, + buffer, + num_entries); + if (status) { + goto out; + } + + out: + NetApiBufferFree(buffer); + return status; +} + +bool torture_libnetapi_group(struct torture_context *tctx) +{ + NET_API_STATUS status = 0; + const char *username, *groupname, *groupname2; + uint8_t *buffer = NULL; + struct GROUP_INFO_0 g0; + uint32_t parm_err = 0; + uint32_t levels[] = { 0, 1, 2, 3}; + uint32_t enum_levels[] = { 0, 1, 2, 3}; + uint32_t getmem_levels[] = { 0, 1}; + int i; + const char *hostname = torture_setting_string(tctx, "host", NULL); + struct libnetapi_ctx *ctx; + + torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx), + "failed to initialize libnetapi"); + + torture_comment(tctx, "NetGroup tests\n"); + + username = "torture_test_user"; + groupname = "torture_test_group"; + groupname2 = "torture_test_group2"; + + /* cleanup */ + NetGroupDel(hostname, groupname); + NetGroupDel(hostname, groupname2); + NetUserDel(hostname, username); + + /* add a group */ + + g0.grpi0_name = groupname; + + torture_comment(tctx, "testing NetGroupAdd\n"); + + status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupAdd"); + goto out; + } + + /* 2nd add must fail */ + + status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err); + if (status == 0) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupAdd"); + status = -1; + goto out; + } + + /* test enum */ + + for (i=0; i<ARRAY_SIZE(enum_levels); i++) { + + status = test_netgroupenum(tctx, hostname, enum_levels[i], groupname); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupEnum"); + goto out; + } + } + + /* basic queries */ + + for (i=0; i<ARRAY_SIZE(levels); i++) { + + torture_comment(tctx, "testing NetGroupGetInfo level %d\n", levels[i]); + + status = NetGroupGetInfo(hostname, groupname, levels[i], &buffer); + if (status && status != 124) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupGetInfo"); + goto out; + } + } + + /* group rename */ + + g0.grpi0_name = groupname2; + + torture_comment(tctx, "testing NetGroupSetInfo level 0\n"); + + status = NetGroupSetInfo(hostname, groupname, 0, (uint8_t *)&g0, &parm_err); + switch (status) { + case 0: + break; + case 50: /* not supported */ + case 124: /* not implemented */ + groupname2 = groupname; + goto skip_rename; + default: + NETAPI_STATUS(tctx, ctx, status, "NetGroupSetInfo"); + goto out; + } + + /* should not exist anymore */ + + status = NetGroupDel(hostname, groupname); + if (status == 0) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupDel"); + goto out; + } + + skip_rename: + /* query info */ + + for (i=0; i<ARRAY_SIZE(levels); i++) { + + status = NetGroupGetInfo(hostname, groupname2, levels[i], &buffer); + if (status && status != 124) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupGetInfo"); + goto out; + } + } + + /* add user to group */ + + status = test_netuseradd(tctx, hostname, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserAdd"); + goto out; + } + + /* should not be member */ + + for (i=0; i<ARRAY_SIZE(getmem_levels); i++) { + + status = test_netgroupgetusers(tctx, hostname, getmem_levels[i], groupname2, NULL); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers"); + goto out; + } + } + + torture_comment(tctx, "testing NetGroupAddUser\n"); + + status = NetGroupAddUser(hostname, groupname2, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupAddUser"); + goto out; + } + + /* should be member */ + + for (i=0; i<ARRAY_SIZE(getmem_levels); i++) { + + status = test_netgroupgetusers(tctx, hostname, getmem_levels[i], groupname2, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers"); + goto out; + } + } + + torture_comment(tctx, "testing NetGroupDelUser\n"); + + status = NetGroupDelUser(hostname, groupname2, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupDelUser"); + goto out; + } + + /* should not be member */ + + status = test_netgroupgetusers(tctx, hostname, 0, groupname2, NULL); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers"); + goto out; + } + + /* set it again via exlicit member set */ + + status = test_netgroupsetusers(tctx, hostname, groupname2, 0, 1, &username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupSetUsers"); + goto out; + } + + /* should be member */ + + status = test_netgroupgetusers(tctx, hostname, 0, groupname2, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers"); + goto out; + } +#if 0 + /* wipe out member list */ + + status = test_netgroupsetusers(hostname, groupname2, 0, 0, NULL); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupSetUsers"); + goto out; + } + + /* should not be member */ + + status = test_netgroupgetusers(hostname, 0, groupname2, NULL); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers"); + goto out; + } +#endif + status = NetUserDel(hostname, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserDel"); + goto out; + } + + /* delete */ + + torture_comment(tctx, "testing NetGroupDel\n"); + + status = NetGroupDel(hostname, groupname2); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetGroupDel"); + goto out; + }; + + /* should not exist anymore */ + + status = NetGroupGetInfo(hostname, groupname2, 0, &buffer); + if (status == 0) { + NETAPI_STATUS_MSG(tctx, ctx, status, "NetGroupGetInfo", "expected failure and error code"); + status = -1; + goto out; + }; + + status = 0; + + torture_comment(tctx, "NetGroup tests succeeded\n"); + out: + if (status != 0) { + torture_comment(tctx, "NetGroup testsuite failed with: %s\n", + libnetapi_get_error_string(ctx, status)); + libnetapi_free(ctx); + return false; + } + + libnetapi_free(ctx); + return true; +} diff --git a/source4/torture/libnetapi/libnetapi_user.c b/source4/torture/libnetapi/libnetapi_user.c new file mode 100644 index 0000000000..c6343301e3 --- /dev/null +++ b/source4/torture/libnetapi/libnetapi_user.c @@ -0,0 +1,476 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Guenther Deschner 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "torture/smbtorture.h" +#include <netapi.h> +#include "torture/libnetapi/proto.h" + +#define TORTURE_TEST_USER "testuser" + +#define NETAPI_STATUS(tctx, x,y,fn) \ + torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \ + __LINE__, fn, libnetapi_get_error_string(x,y), y); + +static NET_API_STATUS test_netuserenum(struct torture_context *tctx, + const char *hostname, + uint32_t level, + const char *username) +{ + NET_API_STATUS status; + uint32_t entries_read = 0; + uint32_t total_entries = 0; + uint32_t resume_handle = 0; + const char *current_name = NULL; + int found_user = 0; + uint8_t *buffer = NULL; + int i; + + struct USER_INFO_0 *info0 = NULL; + struct USER_INFO_1 *info1 = NULL; + struct USER_INFO_2 *info2 = NULL; + struct USER_INFO_3 *info3 = NULL; + struct USER_INFO_4 *info4 = NULL; + struct USER_INFO_10 *info10 = NULL; + struct USER_INFO_11 *info11 = NULL; + struct USER_INFO_20 *info20 = NULL; + struct USER_INFO_23 *info23 = NULL; + + torture_comment(tctx, "testing NetUserEnum level %d\n", level); + + do { + status = NetUserEnum(hostname, + level, + FILTER_NORMAL_ACCOUNT, + &buffer, + (uint32_t)-1, + &entries_read, + &total_entries, + &resume_handle); + if (status == 0 || status == ERROR_MORE_DATA) { + switch (level) { + case 0: + info0 = (struct USER_INFO_0 *)buffer; + break; + case 1: + info1 = (struct USER_INFO_1 *)buffer; + break; + case 2: + info2 = (struct USER_INFO_2 *)buffer; + break; + case 3: + info3 = (struct USER_INFO_3 *)buffer; + break; + case 4: + info4 = (struct USER_INFO_4 *)buffer; + break; + case 10: + info10 = (struct USER_INFO_10 *)buffer; + break; + case 11: + info11 = (struct USER_INFO_11 *)buffer; + break; + case 20: + info20 = (struct USER_INFO_20 *)buffer; + break; + case 23: + info23 = (struct USER_INFO_23 *)buffer; + break; + default: + return -1; + } + + for (i=0; i<entries_read; i++) { + + switch (level) { + case 0: + current_name = info0->usri0_name; + break; + case 1: + current_name = info1->usri1_name; + break; + case 2: + current_name = info2->usri2_name; + break; + case 3: + current_name = info3->usri3_name; + break; + case 4: + current_name = info4->usri4_name; + break; + case 10: + current_name = info10->usri10_name; + break; + case 11: + current_name = info11->usri11_name; + break; + case 20: + current_name = info20->usri20_name; + break; + case 23: + current_name = info23->usri23_name; + break; + default: + return -1; + } + + if (strcasecmp(current_name, username) == 0) { + found_user = 1; + } + + switch (level) { + case 0: + info0++; + break; + case 1: + info1++; + break; + case 2: + info2++; + break; + case 3: + info3++; + break; + case 4: + info4++; + break; + case 10: + info10++; + break; + case 11: + info11++; + break; + case 20: + info20++; + break; + case 23: + info23++; + break; + default: + break; + } + } + NetApiBufferFree(buffer); + } + } while (status == ERROR_MORE_DATA); + + if (status) { + return status; + } + + if (!found_user) { + torture_comment(tctx, "failed to get user\n"); + return -1; + } + + return 0; +} + +NET_API_STATUS test_netuseradd(struct torture_context *tctx, + const char *hostname, + const char *username) +{ + struct USER_INFO_1 u1; + uint32_t parm_err = 0; + + ZERO_STRUCT(u1); + + torture_comment(tctx, "testing NetUserAdd\n"); + + u1.usri1_name = username; + u1.usri1_password = "W297!832jD8J"; + u1.usri1_password_age = 0; + u1.usri1_priv = 0; + u1.usri1_home_dir = NULL; + u1.usri1_comment = "User created using Samba NetApi Example code"; + u1.usri1_flags = 0; + u1.usri1_script_path = NULL; + + return NetUserAdd(hostname, 1, (uint8_t *)&u1, &parm_err); +} + +static NET_API_STATUS test_netusermodals(struct torture_context *tctx, + struct libnetapi_ctx *ctx, + const char *hostname) +{ + NET_API_STATUS status; + struct USER_MODALS_INFO_0 *u0 = NULL; + struct USER_MODALS_INFO_0 *_u0 = NULL; + uint8_t *buffer = NULL; + uint32_t parm_err = 0; + uint32_t levels[] = { 0, 1, 2, 3 }; + int i = 0; + + for (i=0; i<ARRAY_SIZE(levels); i++) { + + torture_comment(tctx, "testing NetUserModalsGet level %d\n", levels[i]); + + status = NetUserModalsGet(hostname, levels[i], &buffer); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet"); + return status; + } + } + + status = NetUserModalsGet(hostname, 0, (uint8_t **)&u0); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet"); + return status; + } + + torture_comment(tctx, "testing NetUserModalsSet\n"); + + status = NetUserModalsSet(hostname, 0, (uint8_t *)u0, &parm_err); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserModalsSet"); + return status; + } + + status = NetUserModalsGet(hostname, 0, (uint8_t **)&_u0); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet"); + return status; + } + + if (memcmp(u0, _u0, sizeof(u0) != 0)) { + torture_comment(tctx, "USER_MODALS_INFO_0 struct has changed!!!!\n"); + return -1; + } + + return 0; +} + +static NET_API_STATUS test_netusergetgroups(struct torture_context *tctx, + const char *hostname, + uint32_t level, + const char *username, + const char *groupname) +{ + NET_API_STATUS status; + uint32_t entries_read = 0; + uint32_t total_entries = 0; + const char *current_name; + int found_group = 0; + uint8_t *buffer = NULL; + int i; + + struct GROUP_USERS_INFO_0 *i0; + struct GROUP_USERS_INFO_1 *i1; + + torture_comment(tctx, "testing NetUserGetGroups level %d\n", level); + + do { + status = NetUserGetGroups(hostname, + username, + level, + &buffer, + (uint32_t)-1, + &entries_read, + &total_entries); + if (status == 0 || status == ERROR_MORE_DATA) { + switch (level) { + case 0: + i0 = (struct GROUP_USERS_INFO_0 *)buffer; + break; + case 1: + i1 = (struct GROUP_USERS_INFO_1 *)buffer; + break; + default: + return -1; + } + + for (i=0; i<entries_read; i++) { + + switch (level) { + case 0: + current_name = i0->grui0_name; + break; + case 1: + current_name = i1->grui1_name; + break; + default: + return -1; + } + + if (groupname && strcasecmp(current_name, groupname) == 0) { + found_group = 1; + } + + switch (level) { + case 0: + i0++; + break; + case 1: + i1++; + break; + default: + break; + } + } + NetApiBufferFree(buffer); + } + } while (status == ERROR_MORE_DATA); + + if (status) { + return status; + } + + if (groupname && !found_group) { + torture_comment(tctx, "failed to get membership\n"); + return -1; + } + + return 0; +} + +bool torture_libnetapi_user(struct torture_context *tctx) +{ + NET_API_STATUS status = 0; + const char *username, *username2; + uint8_t *buffer = NULL; + uint32_t levels[] = { 0, 1, 2, 3, 4, 10, 11, 20, 23 }; + uint32_t enum_levels[] = { 0, 1, 2, 3, 4, 10, 11, 20, 23 }; + uint32_t getgr_levels[] = { 0, 1 }; + int i; + + struct USER_INFO_1007 u1007; + uint32_t parm_err = 0; + + const char *hostname = torture_setting_string(tctx, "host", NULL); + struct libnetapi_ctx *ctx; + + torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx), + "failed to initialize libnetapi"); + + torture_comment(tctx, "NetUser tests\n"); + + username = "torture_test_user"; + username2 = "torture_test_user2"; + + /* cleanup */ + NetUserDel(hostname, username); + NetUserDel(hostname, username2); + + /* add a user */ + + status = test_netuseradd(tctx, hostname, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserAdd"); + goto out; + } + + /* enum the new user */ + + for (i=0; i<ARRAY_SIZE(enum_levels); i++) { + + status = test_netuserenum(tctx, hostname, enum_levels[i], username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserEnum"); + goto out; + } + } + + /* basic queries */ + + for (i=0; i<ARRAY_SIZE(levels); i++) { + + torture_comment(tctx, "testing NetUserGetInfo level %d\n", levels[i]); + + status = NetUserGetInfo(hostname, username, levels[i], &buffer); + if (status && status != 124) { + NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo"); + goto out; + } + } + + /* testing getgroups */ + + for (i=0; i<ARRAY_SIZE(getgr_levels); i++) { + + status = test_netusergetgroups(tctx, hostname, getgr_levels[i], username, NULL); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserGetGroups"); + goto out; + } + } + + /* modify description */ + + torture_comment(tctx, "testing NetUserSetInfo level %d\n", 1007); + + u1007.usri1007_comment = "NetApi modified user"; + + status = NetUserSetInfo(hostname, username, 1007, (uint8_t *)&u1007, &parm_err); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserSetInfo"); + goto out; + } + + /* query info */ + + for (i=0; i<ARRAY_SIZE(levels); i++) { + status = NetUserGetInfo(hostname, username, levels[i], &buffer); + if (status && status != 124) { + NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo"); + goto out; + } + } + + /* delete */ + + torture_comment(tctx, "testing NetUserDel\n"); + + status = NetUserDel(hostname, username); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetUserDel"); + goto out; + } + + /* should not exist anymore */ + + status = NetUserGetInfo(hostname, username, 0, &buffer); + if (status == 0) { + NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo"); + status = -1; + goto out; + } + + status = test_netusermodals(tctx, ctx, hostname); + if (status) { + goto out; + } + + status = 0; + + torture_comment(tctx, "NetUser tests succeeded\n"); + out: + /* cleanup */ + NetUserDel(hostname, username); + NetUserDel(hostname, username2); + + if (status != 0) { + torture_comment(tctx, "NetUser testsuite failed with: %s\n", + libnetapi_get_error_string(ctx, status)); + libnetapi_free(ctx); + return false; + } + + libnetapi_free(ctx); + return true; +} diff --git a/source4/torture/local/config.mk b/source4/torture/local/config.mk index 5c8c1d5762..28599e4bda 100644 --- a/source4/torture/local/config.mk +++ b/source4/torture/local/config.mk @@ -17,7 +17,8 @@ PRIVATE_DEPENDENCIES = \ TORTURE_LIBCRYPTO \ share \ torture_registry \ - PROVISION + PROVISION \ + NSS_WRAPPER # End SUBSYSTEM TORTURE_LOCAL ################################# @@ -34,6 +35,7 @@ TORTURE_LOCAL_OBJ_FILES = \ $(torturesrcdir)/../../lib/util/tests/idtree.o \ $(torturesrcdir)/../lib/socket/testsuite.o \ $(torturesrcdir)/../../lib/socket_wrapper/testsuite.o \ + $(torturesrcdir)/../../lib/nss_wrapper/testsuite.o \ $(torturesrcdir)/../libcli/resolve/testsuite.o \ $(torturesrcdir)/../../lib/util/tests/strlist.o \ $(torturesrcdir)/../../lib/util/tests/str.o \ diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c index a1b100edb8..73ee366dcd 100644 --- a/source4/torture/local/local.c +++ b/source4/torture/local/local.c @@ -43,6 +43,7 @@ torture_local_iconv, torture_local_socket, torture_local_socket_wrapper, + torture_local_nss_wrapper, torture_pac, torture_local_resolve, torture_local_sddl, diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 92ce66fef2..30e7e0889c 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -2673,21 +2673,20 @@ static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p, return true; } -static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx, - struct cli_credentials *machine_credentials, - struct cli_credentials *test_credentials, - struct netlogon_creds_CredentialState *creds, - NTSTATUS expected_result) +static bool test_SamLogon(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct cli_credentials *test_credentials, + NTSTATUS expected_result) { NTSTATUS status; - struct netr_LogonSamLogon r; - struct netr_Authenticator auth, auth2; + struct netr_LogonSamLogonEx r; union netr_LogonLevel logon; union netr_Validation validation; uint8_t authoritative; struct netr_NetworkInfo ninfo; DATA_BLOB names_blob, chal, lm_resp, nt_resp; int flags = CLI_CRED_NTLM_AUTH; + uint32_t samlogon_flags = 0; if (lp_client_lanman_auth(tctx->lp_ctx)) { flags |= CLI_CRED_LANMAN_AUTH; @@ -2706,8 +2705,8 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t chal = data_blob_const(ninfo.challenge, sizeof(ninfo.challenge)); - names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials), - cli_credentials_get_domain(machine_credentials)); + names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials), + cli_credentials_get_domain(test_credentials)); status = cli_credentials_get_ntlm_response(test_credentials, tctx, &flags, @@ -2728,56 +2727,38 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT; ninfo.identity_info.logon_id_low = 0; ninfo.identity_info.logon_id_high = 0; - ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials); + ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials); logon.network = &ninfo; r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); - r.in.computer_name = cli_credentials_get_workstation(machine_credentials); - r.in.credential = &auth; - r.in.return_authenticator = &auth2; - r.in.logon_level = 2; + r.in.computer_name = cli_credentials_get_workstation(test_credentials); + r.in.logon_level = NetlogonNetworkInformation; r.in.logon = &logon; + r.in.flags = &samlogon_flags; + r.out.flags = &samlogon_flags; r.out.validation = &validation; r.out.authoritative = &authoritative; d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string); - ZERO_STRUCT(auth2); - netlogon_creds_client_authenticator(creds, &auth); - - r.in.validation_level = 2; + r.in.validation_level = 6; - status = dcerpc_netr_LogonSamLogon(p, tctx, &r); + status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r); + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) { + r.in.validation_level = 3; + status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r); + } if (!NT_STATUS_IS_OK(status)) { - torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed"); + torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed"); return true; } else { - torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed"); + torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed"); } - torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred), - "Credential chaining failed"); - return true; } -static bool test_SamLogon(struct torture_context *tctx, - struct dcerpc_pipe *p, - struct cli_credentials *machine_credentials, - struct cli_credentials *test_credentials, - NTSTATUS expected_result) -{ - struct netlogon_creds_CredentialState *creds; - - if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) { - return false; - } - - return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials, - creds, expected_result); -} - static bool test_SamLogon_with_creds(struct torture_context *tctx, struct dcerpc_pipe *p, struct cli_credentials *machine_creds, @@ -2791,19 +2772,18 @@ static bool test_SamLogon_with_creds(struct torture_context *tctx, test_credentials = cli_credentials_init(tctx); cli_credentials_set_workstation(test_credentials, - TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED); + cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED); cli_credentials_set_domain(test_credentials, - lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED); + cli_credentials_get_domain(machine_creds), CRED_SPECIFIED); cli_credentials_set_username(test_credentials, acct_name, CRED_SPECIFIED); cli_credentials_set_password(test_credentials, password, CRED_SPECIFIED); - cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC); - printf("testing samlogon as %s@%s password: %s\n", - acct_name, TEST_ACCOUNT_NAME_PWD, password); + printf("testing samlogon as %s password: %s\n", + acct_name, password); - if (!test_SamLogon(tctx, p, machine_creds, test_credentials, + if (!test_SamLogon(tctx, p, test_credentials, expected_samlogon_result)) { torture_warning(tctx, "new password did not work\n"); ret = false; @@ -2886,11 +2866,12 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p, struct cli_credentials *machine_credentials) { int s = 0, q = 0, f = 0, l = 0, z = 0; + struct dcerpc_binding *b; bool ret = true; - int delay = 500000; + int delay = 50000; bool set_levels[] = { false, true }; bool query_levels[] = { false, true }; - uint32_t levels[] = { 18, 21, 23, 24, 25, 26 }; + uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */ uint32_t nonzeros[] = { 1, 24 }; uint32_t fields_present[] = { 0, @@ -2915,19 +2896,41 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p, delay); } - status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon); + status = torture_rpc_binding(tctx, &b); if (!NT_STATUS_IS_OK(status)) { - return false; + ret = false; + return ret; + } + + /* We have to use schannel, otherwise the SamLogonEx fails + * with INTERNAL_ERROR */ + + b->flags &= ~DCERPC_AUTH_OPTIONS; + b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128; + + status = dcerpc_pipe_connect_b(tctx, &np, b, + &ndr_table_netlogon, + machine_credentials, tctx->ev, tctx->lp_ctx); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status)); + ret = false; + return ret; } /* set to 1 to enable testing for all possible opcode (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2) combinations */ #if 0 +#define TEST_ALL_LEVELS 1 #define TEST_SET_LEVELS 1 #define TEST_QUERY_LEVELS 1 #endif +#ifdef TEST_ALL_LEVELS for (l=0; l<ARRAY_SIZE(levels); l++) { +#else + for (l=0; l<(ARRAY_SIZE(levels))/2; l++) { +#endif for (z=0; z<ARRAY_SIZE(nonzeros); z++) { for (f=0; f<ARRAY_SIZE(fields_present); f++) { #ifdef TEST_SET_LEVELS @@ -4373,7 +4376,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx { ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK }, { ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER }, { ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER }, - { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK }, + { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED }, { ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER }, { ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER }, { 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER }, @@ -6177,6 +6180,8 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, NTSTATUS status; uint32_t i; + struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total); + /* query */ { @@ -6209,29 +6214,25 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, for (i=0; i < num_total; i++) { - struct policy_handle handle; const char *name = NULL; - ZERO_STRUCT(handle); - switch (which_ops) { case TORTURE_SAMR_MANY_ACCOUNTS: name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i); - ret &= test_CreateUser(p, tctx, domain_handle, name, &handle, domain_sid, 0, NULL, false); + ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false); break; case TORTURE_SAMR_MANY_GROUPS: name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i); - ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handle, domain_sid, false); + ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false); break; case TORTURE_SAMR_MANY_ALIASES: name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i); - ret &= test_CreateAlias(p, tctx, domain_handle, name, &handle, domain_sid, false); + ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false); break; default: return false; } - if (!policy_handle_empty(&handle)) { - ret &= test_samr_handle_Close(p, tctx, &handle); + if (!policy_handle_empty(&handles[i])) { num_created++; } } @@ -6252,9 +6253,6 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, return false; } - torture_assert_int_equal(tctx, num_enum, num_anounced + num_created, - "unexpected number of results returned in enum call"); -#if 0 /* TODO: dispinfo */ switch (which_ops) { @@ -6268,9 +6266,38 @@ static bool test_ManyObjects(struct dcerpc_pipe *p, return false; } + + /* delete */ + + for (i=0; i < num_total; i++) { + + if (policy_handle_empty(&handles[i])) { + continue; + } + + switch (which_ops) { + case TORTURE_SAMR_MANY_ACCOUNTS: + ret &= test_DeleteUser(p, tctx, &handles[i]); + break; + case TORTURE_SAMR_MANY_GROUPS: + ret &= test_DeleteDomainGroup(p, tctx, &handles[i]); + break; + case TORTURE_SAMR_MANY_ALIASES: + ret &= test_DeleteAlias(p, tctx, &handles[i]); + break; + default: + return false; + } + } + + talloc_free(handles); + +#if 0 torture_assert_int_equal(tctx, num_disp, num_anounced + num_created, "unexpected number of results returned in dispinfo call"); #endif + torture_assert_int_equal(tctx, num_enum, num_anounced + num_created, + "unexpected number of results returned in enum call"); return ret; } @@ -6310,9 +6337,14 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx, ret &= test_samr_handle_Close(p, tctx, handle); switch (which_ops) { - case TORTURE_SAMR_USER_ATTRIBUTES: - case TORTURE_SAMR_USER_PRIVILEGES: case TORTURE_SAMR_PASSWORDS: + case TORTURE_SAMR_USER_PRIVILEGES: + if (!torture_setting_bool(tctx, "samba3", false)) { + ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL); + } + ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true); + break; + case TORTURE_SAMR_USER_ATTRIBUTES: if (!torture_setting_bool(tctx, "samba3", false)) { ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL); } diff --git a/source4/torture/torture.c b/source4/torture/torture.c index a9ec325dd6..d80acffa0d 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -45,6 +45,12 @@ bool torture_register_suite(struct torture_suite *suite) return torture_suite_add_suite(torture_root, suite); } +#ifndef HAVE_NETAPI_H +NTSTATUS torture_libnetapi_init(void) +{ + return NT_STATUS_OK; +} +#endif _PUBLIC_ int torture_init(void) { @@ -57,6 +63,9 @@ _PUBLIC_ int torture_init(void) extern NTSTATUS torture_rpc_init(void); extern NTSTATUS torture_smb2_init(void); extern NTSTATUS torture_net_init(void); +#ifdef HAVE_NETAPI_H + extern NTSTATUS torture_libnetapi_init(void); +#endif extern NTSTATUS torture_raw_init(void); extern NTSTATUS torture_unix_init(void); extern NTSTATUS torture_winbind_init(void); |