summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-10-11 09:35:01 +0000
committerJeremy Allison <jra@samba.org>2001-10-11 09:35:01 +0000
commitf0b5382869d12249e593ac2f10fc9f1f9d03bae6 (patch)
tree97543b143f7e42dfdfd7e6e46ad22d0fd59bcdab /source
parent8d4870bccd026d059c160de3642bb427338256ec (diff)
downloadsamba-f0b5382869d12249e593ac2f10fc9f1f9d03bae6.tar.gz
Sync-up with SAMBA_2_2 branch.
Jeremy.
Diffstat (limited to 'source')
-rw-r--r--source/auth/pampass.c26
-rw-r--r--source/auth/pass_check.c8
-rw-r--r--source/client/client.c17
-rw-r--r--source/client/clitar.c17
-rw-r--r--source/client/smbmount.c26
-rw-r--r--source/client/smbumount.c5
-rw-r--r--source/groupdb/aliasdb.c14
-rw-r--r--source/groupdb/aliasfile.c23
-rw-r--r--source/groupdb/groupdb.c14
-rw-r--r--source/groupdb/groupfile.c14
-rw-r--r--source/include/hash.h2
-rw-r--r--source/include/includes.h41
-rw-r--r--source/include/msdfs.h34
-rw-r--r--source/include/nterr.h1046
-rw-r--r--source/include/printing.h4
-rw-r--r--source/include/profile.h52
-rw-r--r--source/include/proto.h479
-rw-r--r--source/include/rpc_dfs.h1
-rw-r--r--source/include/rpc_samr.h1
-rw-r--r--source/include/smb.h284
-rw-r--r--source/include/smb_acls.h30
-rw-r--r--source/include/smb_macros.h24
-rw-r--r--source/include/trans2.h41
-rw-r--r--source/include/version.h2
-rw-r--r--source/include/vfs.h4
-rw-r--r--source/lib/debug.c13
-rw-r--r--source/lib/genrand.c4
-rw-r--r--source/lib/hash.c40
-rw-r--r--source/lib/messages.c21
-rw-r--r--source/lib/pidfile.c12
-rw-r--r--source/lib/readline.c18
-rw-r--r--source/lib/sysacls.c170
-rw-r--r--source/lib/talloc.c2
-rw-r--r--source/lib/time.c31
-rw-r--r--source/lib/username.c2
-rw-r--r--source/lib/util.c434
-rw-r--r--source/lib/util_array.c14
-rw-r--r--source/lib/util_file.c47
-rw-r--r--source/lib/util_list.c2
-rw-r--r--source/lib/util_seaccess.c23
-rw-r--r--source/lib/util_sid.c27
-rw-r--r--source/lib/util_sock.c137
-rw-r--r--source/lib/util_str.c21
-rw-r--r--source/libsmb/cli_lsarpc.c18
-rw-r--r--source/libsmb/cli_samr.c372
-rw-r--r--source/libsmb/cli_spoolss.c18
-rw-r--r--source/libsmb/clierror.c2
-rw-r--r--source/libsmb/clifile.c8
-rw-r--r--source/libsmb/clireadwrite.c89
-rw-r--r--source/libsmb/clitrans.c41
-rw-r--r--source/libsmb/credentials.c14
-rw-r--r--source/libsmb/namequery.c276
-rw-r--r--source/libsmb/smbencrypt.c82
-rw-r--r--source/libsmb/smberr.c61
-rw-r--r--source/libsmb/unexpected.c4
-rw-r--r--source/locking/brlock.c105
-rw-r--r--source/locking/locking.c262
-rw-r--r--source/locking/posix.c151
-rw-r--r--source/msdfs/msdfs.c568
-rw-r--r--source/nmbd/nmbd.c9
-rw-r--r--source/nmbd/nmbd_elections.c9
-rw-r--r--source/nmbd/nmbd_incomingdgrams.c68
-rw-r--r--source/nmbd/nmbd_incomingrequests.c45
-rw-r--r--source/nmbd/nmbd_mynames.c4
-rw-r--r--source/nmbd/nmbd_namequery.c8
-rw-r--r--source/nmbd/nmbd_nameregister.c9
-rw-r--r--source/nmbd/nmbd_namerelease.c8
-rw-r--r--source/nmbd/nmbd_nodestatus.c2
-rw-r--r--source/nmbd/nmbd_processlogon.c15
-rw-r--r--source/nmbd/nmbd_synclists.c13
-rw-r--r--source/nsswitch/pam_winbind.c244
-rw-r--r--source/nsswitch/wb_client.c42
-rw-r--r--source/nsswitch/wb_common.c28
-rw-r--r--source/nsswitch/wbinfo.c180
-rw-r--r--source/nsswitch/winbind_nss.c34
-rw-r--r--source/nsswitch/winbind_nss_config.h55
-rw-r--r--source/nsswitch/winbindd.c857
-rw-r--r--source/nsswitch/winbindd.h65
-rw-r--r--source/nsswitch/winbindd_cache.c249
-rw-r--r--source/nsswitch/winbindd_group.c1457
-rw-r--r--source/nsswitch/winbindd_idmap.c84
-rw-r--r--source/nsswitch/winbindd_nss.h9
-rw-r--r--source/nsswitch/winbindd_pam.c106
-rw-r--r--source/nsswitch/winbindd_proto.h98
-rw-r--r--source/nsswitch/winbindd_user.c852
-rw-r--r--source/nsswitch/winbindd_util.c681
-rw-r--r--source/nsswitch/wins.c13
-rw-r--r--source/pam_smbpass/pam_smb_acct.c12
-rw-r--r--source/pam_smbpass/pam_smb_auth.c49
-rw-r--r--source/pam_smbpass/pam_smb_passwd.c49
-rw-r--r--source/pam_smbpass/support.c50
-rw-r--r--source/pam_smbpass/support.h12
-rw-r--r--source/param/loadparm.c271
-rw-r--r--source/param/params.c18
-rw-r--r--source/passdb/pampass.c26
-rw-r--r--source/passdb/pass_check.c8
-rw-r--r--source/passdb/passdb.c2160
-rw-r--r--source/passdb/secrets.c70
-rw-r--r--source/passdb/smbpassfile.c22
-rw-r--r--source/printing/nt_printing.c1238
-rw-r--r--source/printing/pcap.c8
-rw-r--r--source/printing/print_cups.c76
-rw-r--r--source/printing/print_svid.c13
-rw-r--r--source/printing/printing.c28
-rw-r--r--source/profile/profile.c2
-rw-r--r--source/rpc_client/cli_login.c3
-rw-r--r--source/rpc_client/cli_lsarpc.c2
-rw-r--r--source/rpc_client/cli_netlogon.c220
-rw-r--r--source/rpc_parse/parse_creds.c43
-rw-r--r--source/rpc_parse/parse_dfs.c2
-rw-r--r--source/rpc_parse/parse_lsa.c14
-rw-r--r--source/rpc_parse/parse_misc.c1
-rw-r--r--source/rpc_parse/parse_net.c130
-rw-r--r--source/rpc_parse/parse_samr.c159
-rw-r--r--source/rpc_parse/parse_spoolss.c19
-rw-r--r--source/rpc_server/srv_dfs_nt.c45
-rw-r--r--source/rpc_server/srv_lsa_nt.c24
-rw-r--r--source/rpc_server/srv_netlog_nt.c280
-rw-r--r--source/rpc_server/srv_pipe.c51
-rw-r--r--source/rpc_server/srv_pipe_hnd.c11
-rw-r--r--source/rpc_server/srv_reg_nt.c8
-rw-r--r--source/rpc_server/srv_samr_nt.c1109
-rwxr-xr-xsource/rpc_server/srv_spoolss.c2
-rw-r--r--source/rpc_server/srv_spoolss_nt.c701
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c177
-rw-r--r--source/rpc_server/srv_util.c33
-rw-r--r--source/rpc_server/srv_wkssvc_nt.c2
-rw-r--r--source/rpcclient/cmd_lsarpc.c16
-rw-r--r--source/rpcclient/cmd_netlogon.c4
-rw-r--r--source/rpcclient/cmd_samr.c497
-rw-r--r--source/rpcclient/cmd_spoolss.c70
-rw-r--r--source/rpcclient/cmd_srvsvc.c2
-rw-r--r--source/rpcclient/rpcclient.c49
-rw-r--r--source/smbd/blocking.c5
-rw-r--r--source/smbd/chgpasswd.c305
-rw-r--r--source/smbd/close.c5
-rw-r--r--source/smbd/connection.c39
-rw-r--r--source/smbd/error.c162
-rw-r--r--source/smbd/ipc.c5
-rw-r--r--source/smbd/lanman.c217
-rw-r--r--source/smbd/mangle.c4
-rw-r--r--source/smbd/notify.c8
-rw-r--r--source/smbd/notify_kernel.c2
-rw-r--r--source/smbd/nttrans.c208
-rw-r--r--source/smbd/open.c200
-rw-r--r--source/smbd/oplock.c53
-rw-r--r--source/smbd/password.c179
-rw-r--r--source/smbd/posix_acls.c33
-rw-r--r--source/smbd/process.c47
-rw-r--r--source/smbd/quotas.c193
-rw-r--r--source/smbd/reply.c1445
-rw-r--r--source/smbd/sec_ctx.c6
-rw-r--r--source/smbd/server.c20
-rw-r--r--source/smbd/service.c4
-rw-r--r--source/smbd/session.c2
-rw-r--r--source/smbd/ssl.c28
-rw-r--r--source/smbd/statcache.c2
-rw-r--r--source/smbd/trans2.c673
-rw-r--r--source/smbd/uid.c33
-rw-r--r--source/smbd/vfs-wrap.c147
-rw-r--r--source/smbd/vfs.c173
-rw-r--r--source/smbwrapper/smbw.c4
-rw-r--r--source/smbwrapper/wrapped.c2
-rw-r--r--source/tdb/spinlock.c85
-rw-r--r--source/tdb/spinlock.h2
-rw-r--r--source/tdb/tdb.c450
-rw-r--r--source/tdb/tdb.h1
-rw-r--r--source/tdb/tdbtool.c7
-rw-r--r--source/tdb/tdbutil.c7
-rw-r--r--source/tests/crypttest.c778
-rw-r--r--source/utils/make_printerdef.c7
-rw-r--r--source/utils/rpccheck.c2
-rw-r--r--source/utils/smbcacls.c6
-rw-r--r--source/utils/smbcontrol.c16
-rw-r--r--source/utils/smbpasswd.c465
-rw-r--r--source/utils/status.c341
-rw-r--r--source/utils/testparm.c5
-rw-r--r--source/utils/torture.c1729
-rw-r--r--source/web/cgi.c28
-rw-r--r--source/web/statuspage.c88
-rw-r--r--source/web/swat.c2
181 files changed, 16782 insertions, 9769 deletions
diff --git a/source/auth/pampass.c b/source/auth/pampass.c
index fc8e4af47d8..dd9d38f66c3 100644
--- a/source/auth/pampass.c
+++ b/source/auth/pampass.c
@@ -88,7 +88,7 @@ static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error,
if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl))
return True;
- if (*nt_status == NT_STATUS_NOPROBLEMO) {
+ if (*nt_status == NT_STATUS_OK) {
/* Complain LOUDLY */
DEBUG(0, ("smb_pam_nt_status_error_handler: PAM: BUG: PAM and NT_STATUS \
error MISMATCH, forcing to NT_STATUS_LOGON_FAILURE"));
@@ -301,14 +301,13 @@ static int smb_pam_passchange_conv(int num_msg,
case PAM_PROMPT_ECHO_ON:
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: PAM said: %s\n", msg[replies]->msg));
fstrcpy(current_prompt, msg[replies]->msg);
- strlower(current_prompt);
trim_string(current_prompt, " ", " ");
for (t=pw_chat; t; t=t->next) {
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: trying to match |%s| to |%s|\n",
t->prompt, current_prompt ));
- if (ms_fnmatch(t->prompt, current_prompt) == 0) {
+ if (unix_wild_match(t->prompt, current_prompt) == 0) {
fstrcpy(current_reply, t->reply);
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We sent: %s\n", current_reply));
pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
@@ -334,14 +333,13 @@ static int smb_pam_passchange_conv(int num_msg,
case PAM_PROMPT_ECHO_OFF:
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: PAM said: %s\n", msg[replies]->msg));
fstrcpy(current_prompt, msg[replies]->msg);
- strlower(current_prompt);
trim_string(current_prompt, " ", " ");
for (t=pw_chat; t; t=t->next) {
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: trying to match |%s| to |%s|\n",
t->prompt, current_prompt ));
- if (ms_fnmatch(t->prompt, current_prompt) == 0) {
+ if (unix_wild_match(t->prompt, current_prompt) == 0) {
fstrcpy(current_reply, t->reply);
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We sent: %s\n", current_reply));
pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
@@ -535,7 +533,7 @@ static uint32 smb_pam_auth(pam_handle_t *pamh, char *user)
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_auth: PAM: User %s Authenticated OK\n", user));
- nt_status = NT_STATUS_NOPROBLEMO;
+ nt_status = NT_STATUS_OK;
break;
default:
DEBUG(0, ("smb_pam_auth: PAM: UNKNOWN ERROR while authenticating user %s\n", user));
@@ -580,7 +578,7 @@ static uint32 smb_pam_account(pam_handle_t *pamh, char * user)
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_account: PAM: Account OK for User: %s\n", user));
- nt_status = NT_STATUS_NOPROBLEMO;
+ nt_status = NT_STATUS_OK;
break;
default:
nt_status = NT_STATUS_ACCOUNT_DISABLED;
@@ -627,7 +625,7 @@ static uint32 smb_pam_setcred(pam_handle_t *pamh, char * user)
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_setcred: PAM: SetCredentials OK for User: %s\n", user));
- nt_status = NT_STATUS_NOPROBLEMO;
+ nt_status = NT_STATUS_OK;
break;
default:
DEBUG(0, ("smb_pam_setcred: PAM: UNKNOWN PAM ERROR (%d) during SetCredentials for User: %s\n", pam_error, user));
@@ -789,7 +787,7 @@ uint32 smb_pam_accountcheck(char * user)
/* Ignore PAM if told to. */
if (!lp_obey_pam_restrictions())
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
return False;
@@ -797,7 +795,7 @@ uint32 smb_pam_accountcheck(char * user)
if (!smb_pam_start(&pamh, user, NULL, pconv))
return NT_STATUS_ACCOUNT_DISABLED;
- if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_NOPROBLEMO)
+ if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_OK)
DEBUG(0, ("smb_pam_accountcheck: PAM: Account Validation Failed - Rejecting User %s!\n", user));
smb_pam_end(pamh, pconv);
@@ -826,19 +824,19 @@ uint32 smb_pam_passcheck(char * user, char * password)
if (!smb_pam_start(&pamh, user, NULL, pconv))
return NT_STATUS_LOGON_FAILURE;
- if ((nt_status = smb_pam_auth(pamh, user)) != NT_STATUS_NOPROBLEMO) {
+ if ((nt_status = smb_pam_auth(pamh, user)) != NT_STATUS_OK) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_auth failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
}
- if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_NOPROBLEMO) {
+ if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_OK) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_account failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
}
- if ((nt_status = smb_pam_setcred(pamh, user)) != NT_STATUS_NOPROBLEMO) {
+ if ((nt_status = smb_pam_setcred(pamh, user)) != NT_STATUS_OK) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_setcred failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
@@ -878,7 +876,7 @@ BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword)
/* If PAM not used, no PAM restrictions on accounts. */
uint32 smb_pam_accountcheck(char * user)
{
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/* If PAM not used, also no PAM restrictions on sessions. */
diff --git a/source/auth/pass_check.c b/source/auth/pass_check.c
index 9424189b236..b3e762741fc 100644
--- a/source/auth/pass_check.c
+++ b/source/auth/pass_check.c
@@ -27,9 +27,9 @@
extern int DEBUGLEVEL;
/* these are kept here to keep the string_combinations function simple */
-static char this_user[100] = "";
-static char this_salt[100] = "";
-static char this_crypted[100] = "";
+static fstring this_user;
+static fstring this_salt;
+static fstring this_crypted;
#ifdef WITH_AFS
@@ -599,7 +599,7 @@ static BOOL password_check(char *password)
{
#ifdef WITH_PAM
- return (smb_pam_passcheck(this_user, password) == NT_STATUS_NOPROBLEMO);
+ return (smb_pam_passcheck(this_user, password) == NT_STATUS_OK);
#endif /* WITH_PAM */
#ifdef WITH_AFS
diff --git a/source/client/client.c b/source/client/client.c
index 4969156f083..d839155bcfc 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -422,20 +422,21 @@ static void adjust_do_list_queue(void)
static void add_to_do_list_queue(const char* entry)
{
+ char *dlq;
+
long new_end = do_list_queue_end + ((long)strlen(entry)) + 1;
while (new_end > do_list_queue_size)
{
do_list_queue_size *= 2;
DEBUG(4,("enlarging do_list_queue to %d\n",
(int)do_list_queue_size));
- do_list_queue = Realloc(do_list_queue, do_list_queue_size);
- if (! do_list_queue) {
+ dlq = Realloc(do_list_queue, do_list_queue_size);
+ if (!dlq) {
DEBUG(0,("failure enlarging do_list_queue to %d bytes\n",
- (int)do_list_queue_size));
+ (int)do_list_queue_size));
reset_do_list_queue();
- }
- else
- {
+ } else {
+ do_list_queue = dlq;
memset(do_list_queue + do_list_queue_size / 2,
0, do_list_queue_size / 2);
}
@@ -1020,6 +1021,10 @@ static void do_put(char *rname,char *lname)
rname));
buf = (char *)malloc(maxwrite);
+ if (!buf) {
+ DEBUG(0, ("ERROR: Not enough memory!\n"));
+ return;
+ }
while (!feof(f)) {
int n = maxwrite;
int ret;
diff --git a/source/client/clitar.c b/source/client/clitar.c
index f6e04230250..335c92eecf1 100644
--- a/source/client/clitar.c
+++ b/source/client/clitar.c
@@ -1606,14 +1606,15 @@ static int read_inclusion_file(char *filename)
}
if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
+ char *ib;
inclusion_buffer_size *= 2;
- inclusion_buffer = Realloc(inclusion_buffer,inclusion_buffer_size);
- if (! inclusion_buffer) {
- DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
- inclusion_buffer_size));
- error = 1;
- break;
- }
+ ib = Realloc(inclusion_buffer,inclusion_buffer_size);
+ if (! ib) {
+ DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n", inclusion_buffer_size));
+ error = 1;
+ break;
+ } else
+ inclusion_buffer = ib;
}
safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
@@ -1718,7 +1719,7 @@ int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind)
SMB_STRUCT_STAT stbuf;
extern time_t newer_than;
- if (dos_stat(argv[Optind], &stbuf) == 0) {
+ if (sys_stat(dos_to_unix(argv[Optind],False), &stbuf) == 0) {
newer_than = stbuf.st_mtime;
DEBUG(1,("Getting files newer than %s",
asctime(LocalTime(&newer_than))));
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index a121d1fa22d..273a5fa85fd 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -195,11 +195,17 @@ static struct cli_state *do_connection(char *service)
password, strlen(password),
password, strlen(password),
workgroup)) {
- DEBUG(0,("%d: session setup failed: %s\n",
- getpid(), cli_errstr(c)));
- cli_shutdown(c);
- free(c);
- return NULL;
+ /* if a password was not supplied then try again with a
+ null username */
+ if (password[0] || !username[0] ||
+ !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
+ DEBUG(0,("%d: session setup failed: %s\n",
+ getpid(), cli_errstr(c)));
+ cli_shutdown(c);
+ free(c);
+ return NULL;
+ }
+ DEBUG(0,("Anonymous login successful\n"));
}
DEBUG(4,("%d: session setup ok\n", getpid()));
@@ -777,6 +783,7 @@ static void parse_mount_smb(int argc, char **argv)
fprintf(stderr, "Unhandled option: %s\n", opteq+1);
exit(1);
} else if(!strcmp(opts, "guest")) {
+ *password = '\0';
got_pass = True;
} else if(!strcmp(opts, "rw")) {
mount_ro = 0;
@@ -817,6 +824,15 @@ static void parse_mount_smb(int argc, char **argv)
/* here we are interactive, even if run from autofs */
setup_logging("mount.smbfs",True);
+ /* 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);
+
TimeInit();
charset_initialise();
diff --git a/source/client/smbumount.c b/source/client/smbumount.c
index dacf4ab67d0..983ad44fa0f 100644
--- a/source/client/smbumount.c
+++ b/source/client/smbumount.c
@@ -74,6 +74,11 @@ 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;
diff --git a/source/groupdb/aliasdb.c b/source/groupdb/aliasdb.c
index a6876d0afca..536b4576bb1 100644
--- a/source/groupdb/aliasdb.c
+++ b/source/groupdb/aliasdb.c
@@ -140,16 +140,18 @@ LOCAL_GRP *iterate_getaliasnam(char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
*************************************************************************/
BOOL add_domain_alias(LOCAL_GRP **alss, int *num_alss, LOCAL_GRP *als)
{
+ LOCAL_GRP *talss;
+
if (alss == NULL || num_alss == NULL || als == NULL)
- {
return False;
- }
- (*alss) = Realloc((*alss), ((*num_alss)+1) * sizeof(LOCAL_GRP));
- if ((*alss) == NULL)
- {
+ talss = (LOCAL_GRP *)Realloc((*alss), ((*num_alss)+1) * sizeof(LOCAL_GRP));
+ if (talss == NULL) {
+ if (*alss)
+ free(*alss);
return False;
- }
+ } else
+ (*alss) = talss;
DEBUG(10,("adding alias %s(%s)\n", als->name, als->comment));
diff --git a/source/groupdb/aliasfile.c b/source/groupdb/aliasfile.c
index 4b8bbe3079f..2fb5a86a800 100644
--- a/source/groupdb/aliasfile.c
+++ b/source/groupdb/aliasfile.c
@@ -119,32 +119,29 @@ static char *get_alias_members(char *p, int *num_mem, LOCAL_GRP_MEMBER **members
fstring name;
if (num_mem == NULL || members == NULL)
- {
return NULL;
- }
(*num_mem) = 0;
(*members) = NULL;
- while (next_token(&p, name, ",", sizeof(fstring)))
- {
+ while (next_token(&p, name, ",", sizeof(fstring))) {
+ LOCAL_GRP_MEMBER *mbrs;
DOM_SID sid;
uint8 type;
- if (lookup_sid(name, &sid, &type))
- {
- (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(LOCAL_GRP_MEMBER));
+ if (lookup_sid(name, &sid, &type)) {
+ mbrs = Realloc((*members), ((*num_mem)+1) * sizeof(LOCAL_GRP_MEMBER));
(*num_mem)++;
- }
- else
- {
+ } else {
DEBUG(0,("alias database: could not resolve alias named %s\n", name));
continue;
}
- if ((*members) == NULL)
- {
+ if (mbrs == NULL) {
+ if (*members)
+ free(*members);
return NULL;
- }
+ } else
+ (*members) = mbrs;
fstrcpy((*members)[(*num_mem)-1].name, name);
(*members)[(*num_mem)-1].sid_use = type;
sid_copy(&(*members)[(*num_mem)-1].sid, &sid);
diff --git a/source/groupdb/groupdb.c b/source/groupdb/groupdb.c
index 1f773d9f153..15d15667bd6 100644
--- a/source/groupdb/groupdb.c
+++ b/source/groupdb/groupdb.c
@@ -138,16 +138,18 @@ DOMAIN_GRP *iterate_getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_me
*************************************************************************/
BOOL add_domain_group(DOMAIN_GRP **grps, int *num_grps, DOMAIN_GRP *grp)
{
+ DOMAIN_GRP *tgrps;
+
if (grps == NULL || num_grps == NULL || grp == NULL)
- {
return False;
- }
- (*grps) = Realloc((*grps), ((*num_grps)+1) * sizeof(DOMAIN_GRP));
- if ((*grps) == NULL)
- {
+ tgrps = (DOMAIN_GRP *)Realloc((*grps), ((*num_grps)+1) * sizeof(DOMAIN_GRP));
+ if (tgrps == NULL) {
+ if (*grps)
+ free(*grps);
return False;
- }
+ } else
+ (*grps) = tgrps;
DEBUG(10,("adding group %s(%s)\n", grp->name, grp->comment));
diff --git a/source/groupdb/groupfile.c b/source/groupdb/groupfile.c
index 88d362e7d4c..322bbcef7b7 100644
--- a/source/groupdb/groupfile.c
+++ b/source/groupdb/groupfile.c
@@ -128,11 +128,15 @@ static char *get_group_members(char *p, int *num_mem, DOMAIN_GRP_MEMBER **member
while (next_token(&p, name, ",", sizeof(fstring)))
{
- (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(DOMAIN_GRP_MEMBER));
- if ((*members) == NULL)
- {
- return NULL;
- }
+ DOMAIN_GRP_MEMBER *mbrs;
+
+ mbrs = (DOMAIN_GRP_MEMBER *)Realloc((*members), ((*num_mem)+1) * sizeof(DOMAIN_GRP_MEMBER));
+ if (mbrs == NULL) {
+ if (*members)
+ free(*members);
+ return NULL;
+ } else
+ (*members) = mbrs;
fstrcpy((*members)[(*num_mem)].name, name);
(*members)[(*num_mem)].attr = 0x07;
(*num_mem)++;
diff --git a/source/include/hash.h b/source/include/hash.h
index 2de7031855a..80a1aaae50e 100644
--- a/source/include/hash.h
+++ b/source/include/hash.h
@@ -22,7 +22,7 @@
#ifndef _HASH_H_
#define _HASH_H_
-#define MAX_HASH_TABLE_SIZE 32768
+#define MAX_HASH_TABLE_SIZE 16384
#define HASH_TABLE_INCREMENT 2
typedef int (*compare_function)(char *, char *);
diff --git a/source/include/includes.h b/source/include/includes.h
index c5f4720a5af..09e6bcf9eee 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -107,7 +107,7 @@
#include <sys/socket.h>
#endif
-#ifdef HAVE_SYS_UN_H
+#ifdef HAVE_UNIXSOCKET
#include <sys/un.h>
#endif
@@ -701,40 +701,7 @@ typedef struct smb_wpasswd {
#define UNI_XDIGIT 0x8
#define UNI_SPACE 0x10
-#ifdef HAVE_NSS_COMMON_H
-
-/* Sun Solaris */
-
-#include <nss_common.h>
-#include <nss_dbdefs.h>
-#include <nsswitch.h>
-
-typedef nss_status_t NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-#elif HAVE_NSS_H
-
-/* GNU */
-
-#include <nss.h>
-
-typedef enum nss_status NSS_STATUS;
-
-#else /* Nothing's defined. Neither gnu nor sun */
-
-typedef enum
-{
- NSS_STATUS_SUCCESS,
- NSS_STATUS_NOTFOUND,
- NSS_STATUS_UNAVAIL,
- NSS_STATUS_TRYAGAIN
-} NSS_STATUS;
-
-#endif
+#include "nsswitch/nss.h"
/***** automatically generated prototypes *****/
#include "proto.h"
@@ -757,7 +724,7 @@ typedef enum
#endif
#ifndef DEFAULT_PRINTING
-#ifdef HAVE_LIBCUPS
+#ifdef HAVE_CUPS
#define DEFAULT_PRINTING PRINT_CUPS
#define PRINTCAP_NAME "cups"
#elif defined(SYSV)
@@ -781,7 +748,7 @@ typedef enum
#define MAP_FILE 0
#endif
-#if (!defined(WITH_NISPLUS) && !defined(WITH_LDAP) && !defined(WITH_TDBPWD))
+#if (!defined(WITH_NISPLUS) && !defined(WITH_LDAP) && !defined(WITH_TDB_SAM))
#define USE_SMBPASS_DB 1
#endif
diff --git a/source/include/msdfs.h b/source/include/msdfs.h
index 2c0f9a19bac..279f72198a2 100644
--- a/source/include/msdfs.h
+++ b/source/include/msdfs.h
@@ -17,6 +17,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: msdfs.h,v 1.5.6.1 2001/10/11 09:32:20 jra Exp $
*/
#ifndef _MSDFS_H
@@ -53,29 +55,29 @@ struct junction_map
struct dfs_path
{
- pstring hostname;
- pstring servicename;
- pstring volumename;
- pstring restofthepath;
+ pstring hostname;
+ pstring servicename;
+ pstring reqpath;
};
#ifdef WITH_MSDFS
-#define RESOLVE_DFSPATH(name, conn, inbuf, outbuf) \
-{ if(((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES)) && \
- dfs_redirect(name,conn)) \
- return(dfs_path_error(inbuf,outbuf)); }
+#define RESOLVE_DFSPATH(name, conn, inbuf, outbuf) \
+{ if ((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && \
+ lp_host_msdfs() && dfs_redirect(name,conn,False)) \
+ return(dfs_path_error(inbuf,outbuf)); }
#define RESOLVE_FINDFIRST_DFSPATH(name, conn, inbuf, outbuf) \
-{ if((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) || \
- get_remote_arch()==RA_WIN95) \
- if(dfs_findfirst_redirect(directory,conn)) \
- return(dfs_path_error(inbuf,outbuf)); }
+{ if ( (SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) || \
+ ((get_remote_arch() == RA_WIN95) && lp_msdfs_root(SNUM(conn))) )\
+ if (lp_host_msdfs() && dfs_redirect(name,conn,True)) \
+ return(dfs_path_error(inbuf,outbuf)); }
-#define init_dfsroot(conn, inbuf, outbuf) \
-{ if(lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) \
- SSVAL(outbuf, smb_vwv2, SMB_SHARE_IN_DFS | SMB_SUPPORT_SEARCH_BITS); \
-}
+#define init_dfsroot(conn, inbuf, outbuf) \
+{ if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) { \
+ DEBUG(1,("Serving %s as a Dfs root\n", lp_servicename(SNUM(conn)) )); \
+ SSVAL(outbuf, smb_vwv2, SMB_SHARE_IN_DFS | SVAL(outbuf, smb_vwv2)); \
+} }
#else
/* Stub macros */
diff --git a/source/include/nterr.h b/source/include/nterr.h
index 07e874dce01..14f3fc08938 100644
--- a/source/include/nterr.h
+++ b/source/include/nterr.h
@@ -1,518 +1,544 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT error code constants
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) John H Terpstra 1996-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Paul Ashton 1998-2000
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _NTERR_H
+#define _NTERR_H
+
/* Win32 Status codes. */
#define STATUS_BUFFER_OVERFLOW (5)
#define STATUS_MORE_ENTRIES (0x105)
-#define ERROR_INVALID_PARAMETER (87)
-#define ERROR_INSUFFICIENT_BUFFER (122)
-#define STATUS_1804 (1804)
+#define ERROR_INVALID_PARAMETER (87)
+#define ERROR_INSUFFICIENT_BUFFER (122)
+#define STATUS_1804 (1804)
#define STATUS_NOTIFY_ENUM_DIR (0x10C)
+/* Win32 Error codes extracted using a loop in smbclient then printing a
+ netmon sniff to a file. */
-/* these are the NT error codes less than 1000. They are here for when
- we start supporting NT error codes in Samba. They were extracted
- using a loop in smbclient then printing a netmon sniff to a file */
-
-#define NT_STATUS_NOPROBLEMO (0x0)
-#define NT_STATUS_NO_PROBLEMO (0x0)
-#define NT_STATUS_UNSUCCESSFUL (0xC0000000 | 1)
-#define NT_STATUS_NOT_IMPLEMENTED (0xC0000000 | 2)
-#define NT_STATUS_INVALID_INFO_CLASS (0xC0000000 | 3)
-#define NT_STATUS_INFO_LENGTH_MISMATCH (0xC0000000 | 4)
-#define NT_STATUS_ACCESS_VIOLATION (0xC0000000 | 5)
-#define NT_STATUS_IN_PAGE_ERROR (0xC0000000 | 6)
-#define NT_STATUS_PAGEFILE_QUOTA (0xC0000000 | 7)
-#define NT_STATUS_INVALID_HANDLE (0xC0000000 | 8)
-#define NT_STATUS_BAD_INITIAL_STACK (0xC0000000 | 9)
-#define NT_STATUS_BAD_INITIAL_PC (0xC0000000 | 10)
-#define NT_STATUS_INVALID_CID (0xC0000000 | 11)
-#define NT_STATUS_TIMER_NOT_CANCELED (0xC0000000 | 12)
-#define NT_STATUS_INVALID_PARAMETER (0xC0000000 | 13)
-#define NT_STATUS_NO_SUCH_DEVICE (0xC0000000 | 14)
-#define NT_STATUS_NO_SUCH_FILE (0xC0000000 | 15)
-#define NT_STATUS_INVALID_DEVICE_REQUEST (0xC0000000 | 16)
-#define NT_STATUS_END_OF_FILE (0xC0000000 | 17)
-#define NT_STATUS_WRONG_VOLUME (0xC0000000 | 18)
-#define NT_STATUS_NO_MEDIA_IN_DEVICE (0xC0000000 | 19)
-#define NT_STATUS_UNRECOGNIZED_MEDIA (0xC0000000 | 20)
-#define NT_STATUS_NONEXISTENT_SECTOR (0xC0000000 | 21)
-#define NT_STATUS_MORE_PROCESSING_REQUIRED (0xC0000000 | 22)
-#define NT_STATUS_NO_MEMORY (0xC0000000 | 23)
-#define NT_STATUS_CONFLICTING_ADDRESSES (0xC0000000 | 24)
-#define NT_STATUS_NOT_MAPPED_VIEW (0xC0000000 | 25)
-#define NT_STATUS_UNABLE_TO_FREE_VM (0x80000000 | 26)
-#define NT_STATUS_UNABLE_TO_DELETE_SECTION (0xC0000000 | 27)
-#define NT_STATUS_INVALID_SYSTEM_SERVICE (0xC0000000 | 28)
-#define NT_STATUS_ILLEGAL_INSTRUCTION (0xC0000000 | 29)
-#define NT_STATUS_INVALID_LOCK_SEQUENCE (0xC0000000 | 30)
-#define NT_STATUS_INVALID_VIEW_SIZE (0xC0000000 | 31)
-#define NT_STATUS_INVALID_FILE_FOR_SECTION (0xC0000000 | 32)
-#define NT_STATUS_ALREADY_COMMITTED (0xC0000000 | 33)
-#define NT_STATUS_ACCESS_DENIED (0xC0000000 | 34)
-#define NT_STATUS_BUFFER_TOO_SMALL (0xC0000000 | 35)
-#define NT_STATUS_OBJECT_TYPE_MISMATCH (0xC0000000 | 36)
-#define NT_STATUS_NONCONTINUABLE_EXCEPTION (0xC0000000 | 37)
-#define NT_STATUS_INVALID_DISPOSITION (0xC0000000 | 38)
-#define NT_STATUS_UNWIND (0xC0000000 | 39)
-#define NT_STATUS_BAD_STACK (0xC0000000 | 40)
-#define NT_STATUS_INVALID_UNWIND_TARGET (0xC0000000 | 41)
-#define NT_STATUS_NOT_LOCKED (0xC0000000 | 42)
-#define NT_STATUS_PARITY_ERROR (0xC0000000 | 43)
-#define NT_STATUS_UNABLE_TO_DECOMMIT_VM (0xC0000000 | 44)
-#define NT_STATUS_NOT_COMMITTED (0xC0000000 | 45)
-#define NT_STATUS_INVALID_PORT_ATTRIBUTES (0xC0000000 | 46)
-#define NT_STATUS_PORT_MESSAGE_TOO_LONG (0xC0000000 | 47)
-#define NT_STATUS_INVALID_PARAMETER_MIX (0xC0000000 | 48)
-#define NT_STATUS_INVALID_QUOTA_LOWER (0xC0000000 | 49)
-#define NT_STATUS_DISK_CORRUPT_ERROR (0xC0000000 | 50)
-#define NT_STATUS_OBJECT_NAME_INVALID (0xC0000000 | 51)
-#define NT_STATUS_OBJECT_NAME_NOT_FOUND (0xC0000000 | 52)
-#define NT_STATUS_OBJECT_NAME_COLLISION (0xC0000000 | 53)
-#define NT_STATUS_HANDLE_NOT_WAITABLE (0xC0000000 | 54)
-#define NT_STATUS_PORT_DISCONNECTED (0xC0000000 | 55)
-#define NT_STATUS_DEVICE_ALREADY_ATTACHED (0xC0000000 | 56)
-#define NT_STATUS_OBJECT_PATH_INVALID (0xC0000000 | 57)
-#define NT_STATUS_OBJECT_PATH_NOT_FOUND (0xC0000000 | 58)
-#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD (0xC0000000 | 59)
-#define NT_STATUS_DATA_OVERRUN (0xC0000000 | 60)
-#define NT_STATUS_DATA_LATE_ERROR (0xC0000000 | 61)
-#define NT_STATUS_DATA_ERROR (0xC0000000 | 62)
-#define NT_STATUS_CRC_ERROR (0xC0000000 | 63)
-#define NT_STATUS_SECTION_TOO_BIG (0xC0000000 | 64)
-#define NT_STATUS_PORT_CONNECTION_REFUSED (0xC0000000 | 65)
-#define NT_STATUS_INVALID_PORT_HANDLE (0xC0000000 | 66)
-#define NT_STATUS_SHARING_VIOLATION (0xC0000000 | 67)
-#define NT_STATUS_QUOTA_EXCEEDED (0xC0000000 | 68)
-#define NT_STATUS_INVALID_PAGE_PROTECTION (0xC0000000 | 69)
-#define NT_STATUS_MUTANT_NOT_OWNED (0xC0000000 | 70)
-#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED (0xC0000000 | 71)
-#define NT_STATUS_PORT_ALREADY_SET (0xC0000000 | 72)
-#define NT_STATUS_SECTION_NOT_IMAGE (0xC0000000 | 73)
-#define NT_STATUS_SUSPEND_COUNT_EXCEEDED (0xC0000000 | 74)
-#define NT_STATUS_THREAD_IS_TERMINATING (0xC0000000 | 75)
-#define NT_STATUS_BAD_WORKING_SET_LIMIT (0xC0000000 | 76)
-#define NT_STATUS_INCOMPATIBLE_FILE_MAP (0xC0000000 | 77)
-#define NT_STATUS_SECTION_PROTECTION (0xC0000000 | 78)
-#define NT_STATUS_EAS_NOT_SUPPORTED (0xC0000000 | 79)
-#define NT_STATUS_EA_TOO_LARGE (0xC0000000 | 80)
-#define NT_STATUS_NONEXISTENT_EA_ENTRY (0xC0000000 | 81)
-#define NT_STATUS_NO_EAS_ON_FILE (0xC0000000 | 82)
-#define NT_STATUS_EA_CORRUPT_ERROR (0xC0000000 | 83)
-#define NT_STATUS_FILE_LOCK_CONFLICT (0xC0000000 | 84)
-#define NT_STATUS_LOCK_NOT_GRANTED (0xC0000000 | 85)
-#define NT_STATUS_DELETE_PENDING (0xC0000000 | 86)
-#define NT_STATUS_CTL_FILE_NOT_SUPPORTED (0xC0000000 | 87)
-#define NT_STATUS_UNKNOWN_REVISION (0xC0000000 | 88)
-#define NT_STATUS_REVISION_MISMATCH (0xC0000000 | 89)
-#define NT_STATUS_INVALID_OWNER (0xC0000000 | 90)
-#define NT_STATUS_INVALID_PRIMARY_GROUP (0xC0000000 | 91)
-#define NT_STATUS_NO_IMPERSONATION_TOKEN (0xC0000000 | 92)
-#define NT_STATUS_CANT_DISABLE_MANDATORY (0xC0000000 | 93)
-#define NT_STATUS_NO_LOGON_SERVERS (0xC0000000 | 94)
-#define NT_STATUS_NO_SUCH_LOGON_SESSION (0xC0000000 | 95)
-#define NT_STATUS_NO_SUCH_PRIVILEGE (0xC0000000 | 96)
-#define NT_STATUS_PRIVILEGE_NOT_HELD (0xC0000000 | 97)
-#define NT_STATUS_INVALID_ACCOUNT_NAME (0xC0000000 | 98)
-#define NT_STATUS_USER_EXISTS (0xC0000000 | 99)
-#define NT_STATUS_NO_SUCH_USER (0xC0000000 | 100)
-#define NT_STATUS_GROUP_EXISTS (0xC0000000 | 101)
-#define NT_STATUS_NO_SUCH_GROUP (0xC0000000 | 102)
-#define NT_STATUS_MEMBER_IN_GROUP (0xC0000000 | 103)
-#define NT_STATUS_MEMBER_NOT_IN_GROUP (0xC0000000 | 104)
-#define NT_STATUS_LAST_ADMIN (0xC0000000 | 105)
-#define NT_STATUS_WRONG_PASSWORD (0xC0000000 | 106)
-#define NT_STATUS_ILL_FORMED_PASSWORD (0xC0000000 | 107)
-#define NT_STATUS_PASSWORD_RESTRICTION (0xC0000000 | 108)
-#define NT_STATUS_LOGON_FAILURE (0xC0000000 | 109)
-#define NT_STATUS_ACCOUNT_RESTRICTION (0xC0000000 | 110)
-#define NT_STATUS_INVALID_LOGON_HOURS (0xC0000000 | 111)
-#define NT_STATUS_INVALID_WORKSTATION (0xC0000000 | 112)
-#define NT_STATUS_PASSWORD_EXPIRED (0xC0000000 | 113)
-#define NT_STATUS_ACCOUNT_DISABLED (0xC0000000 | 114)
-#define NT_STATUS_NONE_MAPPED (0xC0000000 | 115)
-#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED (0xC0000000 | 116)
-#define NT_STATUS_LUIDS_EXHAUSTED (0xC0000000 | 117)
-#define NT_STATUS_INVALID_SUB_AUTHORITY (0xC0000000 | 118)
-#define NT_STATUS_INVALID_ACL (0xC0000000 | 119)
-#define NT_STATUS_INVALID_SID (0xC0000000 | 120)
-#define NT_STATUS_INVALID_SECURITY_DESCR (0xC0000000 | 121)
-#define NT_STATUS_PROCEDURE_NOT_FOUND (0xC0000000 | 122)
-#define NT_STATUS_INVALID_IMAGE_FORMAT (0xC0000000 | 123)
-#define NT_STATUS_NO_TOKEN (0xC0000000 | 124)
-#define NT_STATUS_BAD_INHERITANCE_ACL (0xC0000000 | 125)
-#define NT_STATUS_RANGE_NOT_LOCKED (0xC0000000 | 126)
-#define NT_STATUS_DISK_FULL (0xC0000000 | 127)
-#define NT_STATUS_SERVER_DISABLED (0xC0000000 | 128)
-#define NT_STATUS_SERVER_NOT_DISABLED (0xC0000000 | 129)
-#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED (0xC0000000 | 130)
-#define NT_STATUS_GUIDS_EXHAUSTED (0xC0000000 | 131)
-#define NT_STATUS_INVALID_ID_AUTHORITY (0xC0000000 | 132)
-#define NT_STATUS_AGENTS_EXHAUSTED (0xC0000000 | 133)
-#define NT_STATUS_INVALID_VOLUME_LABEL (0xC0000000 | 134)
-#define NT_STATUS_SECTION_NOT_EXTENDED (0xC0000000 | 135)
-#define NT_STATUS_NOT_MAPPED_DATA (0xC0000000 | 136)
-#define NT_STATUS_RESOURCE_DATA_NOT_FOUND (0xC0000000 | 137)
-#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND (0xC0000000 | 138)
-#define NT_STATUS_RESOURCE_NAME_NOT_FOUND (0xC0000000 | 139)
-#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED (0xC0000000 | 140)
-#define NT_STATUS_FLOAT_DENORMAL_OPERAND (0xC0000000 | 141)
-#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO (0xC0000000 | 142)
-#define NT_STATUS_FLOAT_INEXACT_RESULT (0xC0000000 | 143)
-#define NT_STATUS_FLOAT_INVALID_OPERATION (0xC0000000 | 144)
-#define NT_STATUS_FLOAT_OVERFLOW (0xC0000000 | 145)
-#define NT_STATUS_FLOAT_STACK_CHECK (0xC0000000 | 146)
-#define NT_STATUS_FLOAT_UNDERFLOW (0xC0000000 | 147)
-#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO (0xC0000000 | 148)
-#define NT_STATUS_INTEGER_OVERFLOW (0xC0000000 | 149)
-#define NT_STATUS_PRIVILEGED_INSTRUCTION (0xC0000000 | 150)
-#define NT_STATUS_TOO_MANY_PAGING_FILES (0xC0000000 | 151)
-#define NT_STATUS_FILE_INVALID (0xC0000000 | 152)
-#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED (0xC0000000 | 153)
-#define NT_STATUS_INSUFFICIENT_RESOURCES (0xC0000000 | 154)
-#define NT_STATUS_DFS_EXIT_PATH_FOUND (0xC0000000 | 155)
-#define NT_STATUS_DEVICE_DATA_ERROR (0xC0000000 | 156)
-#define NT_STATUS_DEVICE_NOT_CONNECTED (0xC0000000 | 157)
-#define NT_STATUS_DEVICE_POWER_FAILURE (0xC0000000 | 158)
-#define NT_STATUS_FREE_VM_NOT_AT_BASE (0xC0000000 | 159)
-#define NT_STATUS_MEMORY_NOT_ALLOCATED (0xC0000000 | 160)
-#define NT_STATUS_WORKING_SET_QUOTA (0xC0000000 | 161)
-#define NT_STATUS_MEDIA_WRITE_PROTECTED (0xC0000000 | 162)
-#define NT_STATUS_DEVICE_NOT_READY (0xC0000000 | 163)
-#define NT_STATUS_INVALID_GROUP_ATTRIBUTES (0xC0000000 | 164)
-#define NT_STATUS_BAD_IMPERSONATION_LEVEL (0xC0000000 | 165)
-#define NT_STATUS_CANT_OPEN_ANONYMOUS (0xC0000000 | 166)
-#define NT_STATUS_BAD_VALIDATION_CLASS (0xC0000000 | 167)
-#define NT_STATUS_BAD_TOKEN_TYPE (0xC0000000 | 168)
-#define NT_STATUS_BAD_MASTER_BOOT_RECORD (0xC0000000 | 169)
-#define NT_STATUS_INSTRUCTION_MISALIGNMENT (0xC0000000 | 170)
-#define NT_STATUS_INSTANCE_NOT_AVAILABLE (0xC0000000 | 171)
-#define NT_STATUS_PIPE_NOT_AVAILABLE (0xC0000000 | 172)
-#define NT_STATUS_INVALID_PIPE_STATE (0xC0000000 | 173)
-#define NT_STATUS_PIPE_BUSY (0xC0000000 | 174)
-#define NT_STATUS_ILLEGAL_FUNCTION (0xC0000000 | 175)
-#define NT_STATUS_PIPE_DISCONNECTED (0xC0000000 | 176)
-#define NT_STATUS_PIPE_CLOSING (0xC0000000 | 177)
-#define NT_STATUS_PIPE_CONNECTED (0xC0000000 | 178)
-#define NT_STATUS_PIPE_LISTENING (0xC0000000 | 179)
-#define NT_STATUS_INVALID_READ_MODE (0xC0000000 | 180)
-#define NT_STATUS_IO_TIMEOUT (0xC0000000 | 181)
-#define NT_STATUS_FILE_FORCED_CLOSED (0xC0000000 | 182)
-#define NT_STATUS_PROFILING_NOT_STARTED (0xC0000000 | 183)
-#define NT_STATUS_PROFILING_NOT_STOPPED (0xC0000000 | 184)
-#define NT_STATUS_COULD_NOT_INTERPRET (0xC0000000 | 185)
-#define NT_STATUS_FILE_IS_A_DIRECTORY (0xC0000000 | 186)
-#define NT_STATUS_NOT_SUPPORTED (0xC0000000 | 187)
-#define NT_STATUS_REMOTE_NOT_LISTENING (0xC0000000 | 188)
-#define NT_STATUS_DUPLICATE_NAME (0xC0000000 | 189)
-#define NT_STATUS_BAD_NETWORK_PATH (0xC0000000 | 190)
-#define NT_STATUS_NETWORK_BUSY (0xC0000000 | 191)
-#define NT_STATUS_DEVICE_DOES_NOT_EXIST (0xC0000000 | 192)
-#define NT_STATUS_TOO_MANY_COMMANDS (0xC0000000 | 193)
-#define NT_STATUS_ADAPTER_HARDWARE_ERROR (0xC0000000 | 194)
-#define NT_STATUS_INVALID_NETWORK_RESPONSE (0xC0000000 | 195)
-#define NT_STATUS_UNEXPECTED_NETWORK_ERROR (0xC0000000 | 196)
-#define NT_STATUS_BAD_REMOTE_ADAPTER (0xC0000000 | 197)
-#define NT_STATUS_PRINT_QUEUE_FULL (0xC0000000 | 198)
-#define NT_STATUS_NO_SPOOL_SPACE (0xC0000000 | 199)
-#define NT_STATUS_PRINT_CANCELLED (0xC0000000 | 200)
-#define NT_STATUS_NETWORK_NAME_DELETED (0xC0000000 | 201)
-#define NT_STATUS_NETWORK_ACCESS_DENIED (0xC0000000 | 202)
-#define NT_STATUS_BAD_DEVICE_TYPE (0xC0000000 | 203)
-#define NT_STATUS_BAD_NETWORK_NAME (0xC0000000 | 204)
-#define NT_STATUS_TOO_MANY_NAMES (0xC0000000 | 205)
-#define NT_STATUS_TOO_MANY_SESSIONS (0xC0000000 | 206)
-#define NT_STATUS_SHARING_PAUSED (0xC0000000 | 207)
-#define NT_STATUS_REQUEST_NOT_ACCEPTED (0xC0000000 | 208)
-#define NT_STATUS_REDIRECTOR_PAUSED (0xC0000000 | 209)
-#define NT_STATUS_NET_WRITE_FAULT (0xC0000000 | 210)
-#define NT_STATUS_PROFILING_AT_LIMIT (0xC0000000 | 211)
-#define NT_STATUS_NOT_SAME_DEVICE (0xC0000000 | 212)
-#define NT_STATUS_FILE_RENAMED (0xC0000000 | 213)
-#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED (0xC0000000 | 214)
-#define NT_STATUS_NO_SECURITY_ON_OBJECT (0xC0000000 | 215)
-#define NT_STATUS_CANT_WAIT (0xC0000000 | 216)
-#define NT_STATUS_PIPE_EMPTY (0xC0000000 | 217)
-#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO (0xC0000000 | 218)
-#define NT_STATUS_CANT_TERMINATE_SELF (0xC0000000 | 219)
-#define NT_STATUS_INVALID_SERVER_STATE (0xC0000000 | 220)
-#define NT_STATUS_INVALID_DOMAIN_STATE (0xC0000000 | 221)
-#define NT_STATUS_INVALID_DOMAIN_ROLE (0xC0000000 | 222)
-#define NT_STATUS_NO_SUCH_DOMAIN (0xC0000000 | 223)
-#define NT_STATUS_DOMAIN_EXISTS (0xC0000000 | 224)
-#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED (0xC0000000 | 225)
-#define NT_STATUS_OPLOCK_NOT_GRANTED (0xC0000000 | 226)
-#define NT_STATUS_INVALID_OPLOCK_PROTOCOL (0xC0000000 | 227)
-#define NT_STATUS_INTERNAL_DB_CORRUPTION (0xC0000000 | 228)
-#define NT_STATUS_INTERNAL_ERROR (0xC0000000 | 229)
-#define NT_STATUS_GENERIC_NOT_MAPPED (0xC0000000 | 230)
-#define NT_STATUS_BAD_DESCRIPTOR_FORMAT (0xC0000000 | 231)
-#define NT_STATUS_INVALID_USER_BUFFER (0xC0000000 | 232)
-#define NT_STATUS_UNEXPECTED_IO_ERROR (0xC0000000 | 233)
-#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR (0xC0000000 | 234)
-#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR (0xC0000000 | 235)
-#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR (0xC0000000 | 236)
-#define NT_STATUS_NOT_LOGON_PROCESS (0xC0000000 | 237)
-#define NT_STATUS_LOGON_SESSION_EXISTS (0xC0000000 | 238)
-#define NT_STATUS_INVALID_PARAMETER_1 (0xC0000000 | 239)
-#define NT_STATUS_INVALID_PARAMETER_2 (0xC0000000 | 240)
-#define NT_STATUS_INVALID_PARAMETER_3 (0xC0000000 | 241)
-#define NT_STATUS_INVALID_PARAMETER_4 (0xC0000000 | 242)
-#define NT_STATUS_INVALID_PARAMETER_5 (0xC0000000 | 243)
-#define NT_STATUS_INVALID_PARAMETER_6 (0xC0000000 | 244)
-#define NT_STATUS_INVALID_PARAMETER_7 (0xC0000000 | 245)
-#define NT_STATUS_INVALID_PARAMETER_8 (0xC0000000 | 246)
-#define NT_STATUS_INVALID_PARAMETER_9 (0xC0000000 | 247)
-#define NT_STATUS_INVALID_PARAMETER_10 (0xC0000000 | 248)
-#define NT_STATUS_INVALID_PARAMETER_11 (0xC0000000 | 249)
-#define NT_STATUS_INVALID_PARAMETER_12 (0xC0000000 | 250)
-#define NT_STATUS_REDIRECTOR_NOT_STARTED (0xC0000000 | 251)
-#define NT_STATUS_REDIRECTOR_STARTED (0xC0000000 | 252)
-#define NT_STATUS_STACK_OVERFLOW (0xC0000000 | 253)
-#define NT_STATUS_NO_SUCH_PACKAGE (0xC0000000 | 254)
-#define NT_STATUS_BAD_FUNCTION_TABLE (0xC0000000 | 255)
-#define NT_STATUS_DIRECTORY_NOT_EMPTY (0xC0000000 | 257)
-#define NT_STATUS_FILE_CORRUPT_ERROR (0xC0000000 | 258)
-#define NT_STATUS_NOT_A_DIRECTORY (0xC0000000 | 259)
-#define NT_STATUS_BAD_LOGON_SESSION_STATE (0xC0000000 | 260)
-#define NT_STATUS_LOGON_SESSION_COLLISION (0xC0000000 | 261)
-#define NT_STATUS_NAME_TOO_LONG (0xC0000000 | 262)
-#define NT_STATUS_FILES_OPEN (0xC0000000 | 263)
-#define NT_STATUS_CONNECTION_IN_USE (0xC0000000 | 264)
-#define NT_STATUS_MESSAGE_NOT_FOUND (0xC0000000 | 265)
-#define NT_STATUS_PROCESS_IS_TERMINATING (0xC0000000 | 266)
-#define NT_STATUS_INVALID_LOGON_TYPE (0xC0000000 | 267)
-#define NT_STATUS_NO_GUID_TRANSLATION (0xC0000000 | 268)
-#define NT_STATUS_CANNOT_IMPERSONATE (0xC0000000 | 269)
-#define NT_STATUS_IMAGE_ALREADY_LOADED (0xC0000000 | 270)
-#define NT_STATUS_ABIOS_NOT_PRESENT (0xC0000000 | 271)
-#define NT_STATUS_ABIOS_LID_NOT_EXIST (0xC0000000 | 272)
-#define NT_STATUS_ABIOS_LID_ALREADY_OWNED (0xC0000000 | 273)
-#define NT_STATUS_ABIOS_NOT_LID_OWNER (0xC0000000 | 274)
-#define NT_STATUS_ABIOS_INVALID_COMMAND (0xC0000000 | 275)
-#define NT_STATUS_ABIOS_INVALID_LID (0xC0000000 | 276)
-#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE (0xC0000000 | 277)
-#define NT_STATUS_ABIOS_INVALID_SELECTOR (0xC0000000 | 278)
-#define NT_STATUS_NO_LDT (0xC0000000 | 279)
-#define NT_STATUS_INVALID_LDT_SIZE (0xC0000000 | 280)
-#define NT_STATUS_INVALID_LDT_OFFSET (0xC0000000 | 281)
-#define NT_STATUS_INVALID_LDT_DESCRIPTOR (0xC0000000 | 282)
-#define NT_STATUS_INVALID_IMAGE_NE_FORMAT (0xC0000000 | 283)
-#define NT_STATUS_RXACT_INVALID_STATE (0xC0000000 | 284)
-#define NT_STATUS_RXACT_COMMIT_FAILURE (0xC0000000 | 285)
-#define NT_STATUS_MAPPED_FILE_SIZE_ZERO (0xC0000000 | 286)
-#define NT_STATUS_TOO_MANY_OPENED_FILES (0xC0000000 | 287)
-#define NT_STATUS_CANCELLED (0xC0000000 | 288)
-#define NT_STATUS_CANNOT_DELETE (0xC0000000 | 289)
-#define NT_STATUS_INVALID_COMPUTER_NAME (0xC0000000 | 290)
-#define NT_STATUS_FILE_DELETED (0xC0000000 | 291)
-#define NT_STATUS_SPECIAL_ACCOUNT (0xC0000000 | 292)
-#define NT_STATUS_SPECIAL_GROUP (0xC0000000 | 293)
-#define NT_STATUS_SPECIAL_USER (0xC0000000 | 294)
-#define NT_STATUS_MEMBERS_PRIMARY_GROUP (0xC0000000 | 295)
-#define NT_STATUS_FILE_CLOSED (0xC0000000 | 296)
-#define NT_STATUS_TOO_MANY_THREADS (0xC0000000 | 297)
-#define NT_STATUS_THREAD_NOT_IN_PROCESS (0xC0000000 | 298)
-#define NT_STATUS_TOKEN_ALREADY_IN_USE (0xC0000000 | 299)
-#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED (0xC0000000 | 300)
-#define NT_STATUS_COMMITMENT_LIMIT (0xC0000000 | 301)
-#define NT_STATUS_INVALID_IMAGE_LE_FORMAT (0xC0000000 | 302)
-#define NT_STATUS_INVALID_IMAGE_NOT_MZ (0xC0000000 | 303)
-#define NT_STATUS_INVALID_IMAGE_PROTECT (0xC0000000 | 304)
-#define NT_STATUS_INVALID_IMAGE_WIN_16 (0xC0000000 | 305)
-#define NT_STATUS_LOGON_SERVER_CONFLICT (0xC0000000 | 306)
-#define NT_STATUS_TIME_DIFFERENCE_AT_DC (0xC0000000 | 307)
-#define NT_STATUS_SYNCHRONIZATION_REQUIRED (0xC0000000 | 308)
-#define NT_STATUS_DLL_NOT_FOUND (0xC0000000 | 309)
-#define NT_STATUS_OPEN_FAILED (0xC0000000 | 310)
-#define NT_STATUS_IO_PRIVILEGE_FAILED (0xC0000000 | 311)
-#define NT_STATUS_ORDINAL_NOT_FOUND (0xC0000000 | 312)
-#define NT_STATUS_ENTRYPOINT_NOT_FOUND (0xC0000000 | 313)
-#define NT_STATUS_CONTROL_C_EXIT (0xC0000000 | 314)
-#define NT_STATUS_LOCAL_DISCONNECT (0xC0000000 | 315)
-#define NT_STATUS_REMOTE_DISCONNECT (0xC0000000 | 316)
-#define NT_STATUS_REMOTE_RESOURCES (0xC0000000 | 317)
-#define NT_STATUS_LINK_FAILED (0xC0000000 | 318)
-#define NT_STATUS_LINK_TIMEOUT (0xC0000000 | 319)
-#define NT_STATUS_INVALID_CONNECTION (0xC0000000 | 320)
-#define NT_STATUS_INVALID_ADDRESS (0xC0000000 | 321)
-#define NT_STATUS_DLL_INIT_FAILED (0xC0000000 | 322)
-#define NT_STATUS_MISSING_SYSTEMFILE (0xC0000000 | 323)
-#define NT_STATUS_UNHANDLED_EXCEPTION (0xC0000000 | 324)
-#define NT_STATUS_APP_INIT_FAILURE (0xC0000000 | 325)
-#define NT_STATUS_PAGEFILE_CREATE_FAILED (0xC0000000 | 326)
-#define NT_STATUS_NO_PAGEFILE (0xC0000000 | 327)
-#define NT_STATUS_INVALID_LEVEL (0xC0000000 | 328)
-#define NT_STATUS_WRONG_PASSWORD_CORE (0xC0000000 | 329)
-#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT (0xC0000000 | 330)
-#define NT_STATUS_PIPE_BROKEN (0xC0000000 | 331)
-#define NT_STATUS_REGISTRY_CORRUPT (0xC0000000 | 332)
-#define NT_STATUS_REGISTRY_IO_FAILED (0xC0000000 | 333)
-#define NT_STATUS_NO_EVENT_PAIR (0xC0000000 | 334)
-#define NT_STATUS_UNRECOGNIZED_VOLUME (0xC0000000 | 335)
-#define NT_STATUS_SERIAL_NO_DEVICE_INITED (0xC0000000 | 336)
-#define NT_STATUS_NO_SUCH_ALIAS (0xC0000000 | 337)
-#define NT_STATUS_MEMBER_NOT_IN_ALIAS (0xC0000000 | 338)
-#define NT_STATUS_MEMBER_IN_ALIAS (0xC0000000 | 339)
-#define NT_STATUS_ALIAS_EXISTS (0xC0000000 | 340)
-#define NT_STATUS_LOGON_NOT_GRANTED (0xC0000000 | 341)
-#define NT_STATUS_TOO_MANY_SECRETS (0xC0000000 | 342)
-#define NT_STATUS_SECRET_TOO_LONG (0xC0000000 | 343)
-#define NT_STATUS_INTERNAL_DB_ERROR (0xC0000000 | 344)
-#define NT_STATUS_FULLSCREEN_MODE (0xC0000000 | 345)
-#define NT_STATUS_TOO_MANY_CONTEXT_IDS (0xC0000000 | 346)
-#define NT_STATUS_LOGON_TYPE_NOT_GRANTED (0xC0000000 | 347)
-#define NT_STATUS_NOT_REGISTRY_FILE (0xC0000000 | 348)
-#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED (0xC0000000 | 349)
-#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR (0xC0000000 | 350)
-#define NT_STATUS_FT_MISSING_MEMBER (0xC0000000 | 351)
-#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY (0xC0000000 | 352)
-#define NT_STATUS_ILLEGAL_CHARACTER (0xC0000000 | 353)
-#define NT_STATUS_UNMAPPABLE_CHARACTER (0xC0000000 | 354)
-#define NT_STATUS_UNDEFINED_CHARACTER (0xC0000000 | 355)
-#define NT_STATUS_FLOPPY_VOLUME (0xC0000000 | 356)
-#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND (0xC0000000 | 357)
-#define NT_STATUS_FLOPPY_WRONG_CYLINDER (0xC0000000 | 358)
-#define NT_STATUS_FLOPPY_UNKNOWN_ERROR (0xC0000000 | 359)
-#define NT_STATUS_FLOPPY_BAD_REGISTERS (0xC0000000 | 360)
-#define NT_STATUS_DISK_RECALIBRATE_FAILED (0xC0000000 | 361)
-#define NT_STATUS_DISK_OPERATION_FAILED (0xC0000000 | 362)
-#define NT_STATUS_DISK_RESET_FAILED (0xC0000000 | 363)
-#define NT_STATUS_SHARED_IRQ_BUSY (0xC0000000 | 364)
-#define NT_STATUS_FT_ORPHANING (0xC0000000 | 365)
-#define NT_STATUS_PARTITION_FAILURE (0xC0000000 | 370)
-#define NT_STATUS_INVALID_BLOCK_LENGTH (0xC0000000 | 371)
-#define NT_STATUS_DEVICE_NOT_PARTITIONED (0xC0000000 | 372)
-#define NT_STATUS_UNABLE_TO_LOCK_MEDIA (0xC0000000 | 373)
-#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA (0xC0000000 | 374)
-#define NT_STATUS_EOM_OVERFLOW (0xC0000000 | 375)
-#define NT_STATUS_NO_MEDIA (0xC0000000 | 376)
-#define NT_STATUS_NO_SUCH_MEMBER (0xC0000000 | 378)
-#define NT_STATUS_INVALID_MEMBER (0xC0000000 | 379)
-#define NT_STATUS_KEY_DELETED (0xC0000000 | 380)
-#define NT_STATUS_NO_LOG_SPACE (0xC0000000 | 381)
-#define NT_STATUS_TOO_MANY_SIDS (0xC0000000 | 382)
-#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED (0xC0000000 | 383)
-#define NT_STATUS_KEY_HAS_CHILDREN (0xC0000000 | 384)
-#define NT_STATUS_CHILD_MUST_BE_VOLATILE (0xC0000000 | 385)
-#define NT_STATUS_DEVICE_CONFIGURATION_ERROR (0xC0000000 | 386)
-#define NT_STATUS_DRIVER_INTERNAL_ERROR (0xC0000000 | 387)
-#define NT_STATUS_INVALID_DEVICE_STATE (0xC0000000 | 388)
-#define NT_STATUS_IO_DEVICE_ERROR (0xC0000000 | 389)
-#define NT_STATUS_DEVICE_PROTOCOL_ERROR (0xC0000000 | 390)
-#define NT_STATUS_BACKUP_CONTROLLER (0xC0000000 | 391)
-#define NT_STATUS_LOG_FILE_FULL (0xC0000000 | 392)
-#define NT_STATUS_TOO_LATE (0xC0000000 | 393)
-#define NT_STATUS_NO_TRUST_LSA_SECRET (0xC0000000 | 394)
-#define NT_STATUS_NO_TRUST_SAM_ACCOUNT (0xC0000000 | 395)
-#define NT_STATUS_TRUSTED_DOMAIN_FAILURE (0xC0000000 | 396)
-#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE (0xC0000000 | 397)
-#define NT_STATUS_EVENTLOG_FILE_CORRUPT (0xC0000000 | 398)
-#define NT_STATUS_EVENTLOG_CANT_START (0xC0000000 | 399)
-#define NT_STATUS_TRUST_FAILURE (0xC0000000 | 400)
-#define NT_STATUS_MUTANT_LIMIT_EXCEEDED (0xC0000000 | 401)
-#define NT_STATUS_NETLOGON_NOT_STARTED (0xC0000000 | 402)
-#define NT_STATUS_ACCOUNT_EXPIRED (0xC0000000 | 403)
-#define NT_STATUS_POSSIBLE_DEADLOCK (0xC0000000 | 404)
-#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT (0xC0000000 | 405)
-#define NT_STATUS_REMOTE_SESSION_LIMIT (0xC0000000 | 406)
-#define NT_STATUS_EVENTLOG_FILE_CHANGED (0xC0000000 | 407)
-#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT (0xC0000000 | 408)
-#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT (0xC0000000 | 409)
-#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT (0xC0000000 | 410)
-#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT (0xC0000000 | 411)
-#define NT_STATUS_FS_DRIVER_REQUIRED (0xC0000000 | 412)
-#define NT_STATUS_NO_USER_SESSION_KEY (0xC0000000 | 514)
-#define NT_STATUS_USER_SESSION_DELETED (0xC0000000 | 515)
-#define NT_STATUS_RESOURCE_LANG_NOT_FOUND (0xC0000000 | 516)
-#define NT_STATUS_INSUFF_SERVER_RESOURCES (0xC0000000 | 517)
-#define NT_STATUS_INVALID_BUFFER_SIZE (0xC0000000 | 518)
-#define NT_STATUS_INVALID_ADDRESS_COMPONENT (0xC0000000 | 519)
-#define NT_STATUS_INVALID_ADDRESS_WILDCARD (0xC0000000 | 520)
-#define NT_STATUS_TOO_MANY_ADDRESSES (0xC0000000 | 521)
-#define NT_STATUS_ADDRESS_ALREADY_EXISTS (0xC0000000 | 522)
-#define NT_STATUS_ADDRESS_CLOSED (0xC0000000 | 523)
-#define NT_STATUS_CONNECTION_DISCONNECTED (0xC0000000 | 524)
-#define NT_STATUS_CONNECTION_RESET (0xC0000000 | 525)
-#define NT_STATUS_TOO_MANY_NODES (0xC0000000 | 526)
-#define NT_STATUS_TRANSACTION_ABORTED (0xC0000000 | 527)
-#define NT_STATUS_TRANSACTION_TIMED_OUT (0xC0000000 | 528)
-#define NT_STATUS_TRANSACTION_NO_RELEASE (0xC0000000 | 529)
-#define NT_STATUS_TRANSACTION_NO_MATCH (0xC0000000 | 530)
-#define NT_STATUS_TRANSACTION_RESPONDED (0xC0000000 | 531)
-#define NT_STATUS_TRANSACTION_INVALID_ID (0xC0000000 | 532)
-#define NT_STATUS_TRANSACTION_INVALID_TYPE (0xC0000000 | 533)
-#define NT_STATUS_NOT_SERVER_SESSION (0xC0000000 | 534)
-#define NT_STATUS_NOT_CLIENT_SESSION (0xC0000000 | 535)
-#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE (0xC0000000 | 536)
-#define NT_STATUS_DEBUG_ATTACH_FAILED (0xC0000000 | 537)
-#define NT_STATUS_SYSTEM_PROCESS_TERMINATED (0xC0000000 | 538)
-#define NT_STATUS_DATA_NOT_ACCEPTED (0xC0000000 | 539)
-#define NT_STATUS_NO_BROWSER_SERVERS_FOUND (0xC0000000 | 540)
-#define NT_STATUS_VDM_HARD_ERROR (0xC0000000 | 541)
-#define NT_STATUS_DRIVER_CANCEL_TIMEOUT (0xC0000000 | 542)
-#define NT_STATUS_REPLY_MESSAGE_MISMATCH (0xC0000000 | 543)
-#define NT_STATUS_MAPPED_ALIGNMENT (0xC0000000 | 544)
-#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH (0xC0000000 | 545)
-#define NT_STATUS_LOST_WRITEBEHIND_DATA (0xC0000000 | 546)
-#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID (0xC0000000 | 547)
-#define NT_STATUS_PASSWORD_MUST_CHANGE (0xC0000000 | 548)
-#define NT_STATUS_NOT_FOUND (0xC0000000 | 549)
-#define NT_STATUS_NOT_TINY_STREAM (0xC0000000 | 550)
-#define NT_STATUS_RECOVERY_FAILURE (0xC0000000 | 551)
-#define NT_STATUS_STACK_OVERFLOW_READ (0xC0000000 | 552)
-#define NT_STATUS_FAIL_CHECK (0xC0000000 | 553)
-#define NT_STATUS_DUPLICATE_OBJECTID (0xC0000000 | 554)
-#define NT_STATUS_OBJECTID_EXISTS (0xC0000000 | 555)
-#define NT_STATUS_CONVERT_TO_LARGE (0xC0000000 | 556)
-#define NT_STATUS_RETRY (0xC0000000 | 557)
-#define NT_STATUS_FOUND_OUT_OF_SCOPE (0xC0000000 | 558)
-#define NT_STATUS_ALLOCATE_BUCKET (0xC0000000 | 559)
-#define NT_STATUS_PROPSET_NOT_FOUND (0xC0000000 | 560)
-#define NT_STATUS_MARSHALL_OVERFLOW (0xC0000000 | 561)
-#define NT_STATUS_INVALID_VARIANT (0xC0000000 | 562)
-#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND (0xC0000000 | 563)
-#define NT_STATUS_ACCOUNT_LOCKED_OUT (0xC0000000 | 564)
-#define NT_STATUS_HANDLE_NOT_CLOSABLE (0xC0000000 | 565)
-#define NT_STATUS_CONNECTION_REFUSED (0xC0000000 | 566)
-#define NT_STATUS_GRACEFUL_DISCONNECT (0xC0000000 | 567)
-#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED (0xC0000000 | 568)
-#define NT_STATUS_ADDRESS_NOT_ASSOCIATED (0xC0000000 | 569)
-#define NT_STATUS_CONNECTION_INVALID (0xC0000000 | 570)
-#define NT_STATUS_CONNECTION_ACTIVE (0xC0000000 | 571)
-#define NT_STATUS_NETWORK_UNREACHABLE (0xC0000000 | 572)
-#define NT_STATUS_HOST_UNREACHABLE (0xC0000000 | 573)
-#define NT_STATUS_PROTOCOL_UNREACHABLE (0xC0000000 | 574)
-#define NT_STATUS_PORT_UNREACHABLE (0xC0000000 | 575)
-#define NT_STATUS_REQUEST_ABORTED (0xC0000000 | 576)
-#define NT_STATUS_CONNECTION_ABORTED (0xC0000000 | 577)
-#define NT_STATUS_BAD_COMPRESSION_BUFFER (0xC0000000 | 578)
-#define NT_STATUS_USER_MAPPED_FILE (0xC0000000 | 579)
-#define NT_STATUS_AUDIT_FAILED (0xC0000000 | 580)
-#define NT_STATUS_TIMER_RESOLUTION_NOT_SET (0xC0000000 | 581)
-#define NT_STATUS_CONNECTION_COUNT_LIMIT (0xC0000000 | 582)
-#define NT_STATUS_LOGIN_TIME_RESTRICTION (0xC0000000 | 583)
-#define NT_STATUS_LOGIN_WKSTA_RESTRICTION (0xC0000000 | 584)
-#define NT_STATUS_IMAGE_MP_UP_MISMATCH (0xC0000000 | 585)
-#define NT_STATUS_INSUFFICIENT_LOGON_INFO (0xC0000000 | 592)
-#define NT_STATUS_BAD_DLL_ENTRYPOINT (0xC0000000 | 593)
-#define NT_STATUS_BAD_SERVICE_ENTRYPOINT (0xC0000000 | 594)
-#define NT_STATUS_LPC_REPLY_LOST (0xC0000000 | 595)
-#define NT_STATUS_IP_ADDRESS_CONFLICT1 (0xC0000000 | 596)
-#define NT_STATUS_IP_ADDRESS_CONFLICT2 (0xC0000000 | 597)
-#define NT_STATUS_REGISTRY_QUOTA_LIMIT (0xC0000000 | 598)
-#define NT_STATUS_PATH_NOT_COVERED (0xC0000000 | 599)
-#define NT_STATUS_NO_CALLBACK_ACTIVE (0xC0000000 | 600)
-#define NT_STATUS_LICENSE_QUOTA_EXCEEDED (0xC0000000 | 601)
-#define NT_STATUS_PWD_TOO_SHORT (0xC0000000 | 602)
-#define NT_STATUS_PWD_TOO_RECENT (0xC0000000 | 603)
-#define NT_STATUS_PWD_HISTORY_CONFLICT (0xC0000000 | 604)
-#define NT_STATUS_PLUGPLAY_NO_DEVICE (0xC0000000 | 606)
-#define NT_STATUS_UNSUPPORTED_COMPRESSION (0xC0000000 | 607)
-#define NT_STATUS_INVALID_HW_PROFILE (0xC0000000 | 608)
-#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH (0xC0000000 | 609)
-#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND (0xC0000000 | 610)
-#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND (0xC0000000 | 611)
-#define NT_STATUS_RESOURCE_NOT_OWNED (0xC0000000 | 612)
-#define NT_STATUS_TOO_MANY_LINKS (0xC0000000 | 613)
-#define NT_STATUS_QUOTA_LIST_INCONSISTENT (0xC0000000 | 614)
-#define NT_STATUS_FILE_IS_OFFLINE (0xC0000000 | 615)
+#define NT_STATUS_OK (0x0000)
+#define NT_STATUS_UNSUCCESSFUL (0xC0000000 | 0x0001)
+#define NT_STATUS_NOT_IMPLEMENTED (0xC0000000 | 0x0002)
+#define NT_STATUS_INVALID_INFO_CLASS (0xC0000000 | 0x0003)
+#define NT_STATUS_INFO_LENGTH_MISMATCH (0xC0000000 | 0x0004)
+#define NT_STATUS_ACCESS_VIOLATION (0xC0000000 | 0x0005)
+#define NT_STATUS_IN_PAGE_ERROR (0xC0000000 | 0x0006)
+#define NT_STATUS_PAGEFILE_QUOTA (0xC0000000 | 0x0007)
+#define NT_STATUS_INVALID_HANDLE (0xC0000000 | 0x0008)
+#define NT_STATUS_BAD_INITIAL_STACK (0xC0000000 | 0x0009)
+#define NT_STATUS_BAD_INITIAL_PC (0xC0000000 | 0x000a)
+#define NT_STATUS_INVALID_CID (0xC0000000 | 0x000b)
+#define NT_STATUS_TIMER_NOT_CANCELED (0xC0000000 | 0x000c)
+#define NT_STATUS_INVALID_PARAMETER (0xC0000000 | 0x000d)
+#define NT_STATUS_NO_SUCH_DEVICE (0xC0000000 | 0x000e)
+#define NT_STATUS_NO_SUCH_FILE (0xC0000000 | 0x000f)
+#define NT_STATUS_INVALID_DEVICE_REQUEST (0xC0000000 | 0x0010)
+#define NT_STATUS_END_OF_FILE (0xC0000000 | 0x0011)
+#define NT_STATUS_WRONG_VOLUME (0xC0000000 | 0x0012)
+#define NT_STATUS_NO_MEDIA_IN_DEVICE (0xC0000000 | 0x0013)
+#define NT_STATUS_UNRECOGNIZED_MEDIA (0xC0000000 | 0x0014)
+#define NT_STATUS_NONEXISTENT_SECTOR (0xC0000000 | 0x0015)
+#define NT_STATUS_MORE_PROCESSING_REQUIRED (0xC0000000 | 0x0016)
+#define NT_STATUS_NO_MEMORY (0xC0000000 | 0x0017)
+#define NT_STATUS_CONFLICTING_ADDRESSES (0xC0000000 | 0x0018)
+#define NT_STATUS_NOT_MAPPED_VIEW (0xC0000000 | 0x0019)
+#define NT_STATUS_UNABLE_TO_FREE_VM (0x80000000 | 0x001a)
+#define NT_STATUS_UNABLE_TO_DELETE_SECTION (0xC0000000 | 0x001b)
+#define NT_STATUS_INVALID_SYSTEM_SERVICE (0xC0000000 | 0x001c)
+#define NT_STATUS_ILLEGAL_INSTRUCTION (0xC0000000 | 0x001d)
+#define NT_STATUS_INVALID_LOCK_SEQUENCE (0xC0000000 | 0x001e)
+#define NT_STATUS_INVALID_VIEW_SIZE (0xC0000000 | 0x001f)
+#define NT_STATUS_INVALID_FILE_FOR_SECTION (0xC0000000 | 0x0020)
+#define NT_STATUS_ALREADY_COMMITTED (0xC0000000 | 0x0021)
+#define NT_STATUS_ACCESS_DENIED (0xC0000000 | 0x0022)
+#define NT_STATUS_BUFFER_TOO_SMALL (0xC0000000 | 0x0023)
+#define NT_STATUS_OBJECT_TYPE_MISMATCH (0xC0000000 | 0x0024)
+#define NT_STATUS_NONCONTINUABLE_EXCEPTION (0xC0000000 | 0x0025)
+#define NT_STATUS_INVALID_DISPOSITION (0xC0000000 | 0x0026)
+#define NT_STATUS_UNWIND (0xC0000000 | 0x0027)
+#define NT_STATUS_BAD_STACK (0xC0000000 | 0x0028)
+#define NT_STATUS_INVALID_UNWIND_TARGET (0xC0000000 | 0x0029)
+#define NT_STATUS_NOT_LOCKED (0xC0000000 | 0x002a)
+#define NT_STATUS_PARITY_ERROR (0xC0000000 | 0x002b)
+#define NT_STATUS_UNABLE_TO_DECOMMIT_VM (0xC0000000 | 0x002c)
+#define NT_STATUS_NOT_COMMITTED (0xC0000000 | 0x002d)
+#define NT_STATUS_INVALID_PORT_ATTRIBUTES (0xC0000000 | 0x002e)
+#define NT_STATUS_PORT_MESSAGE_TOO_LONG (0xC0000000 | 0x002f)
+#define NT_STATUS_INVALID_PARAMETER_MIX (0xC0000000 | 0x0030)
+#define NT_STATUS_INVALID_QUOTA_LOWER (0xC0000000 | 0x0031)
+#define NT_STATUS_DISK_CORRUPT_ERROR (0xC0000000 | 0x0032)
+#define NT_STATUS_OBJECT_NAME_INVALID (0xC0000000 | 0x0033)
+#define NT_STATUS_OBJECT_NAME_NOT_FOUND (0xC0000000 | 0x0034)
+#define NT_STATUS_OBJECT_NAME_COLLISION (0xC0000000 | 0x0035)
+#define NT_STATUS_HANDLE_NOT_WAITABLE (0xC0000000 | 0x0036)
+#define NT_STATUS_PORT_DISCONNECTED (0xC0000000 | 0x0037)
+#define NT_STATUS_DEVICE_ALREADY_ATTACHED (0xC0000000 | 0x0038)
+#define NT_STATUS_OBJECT_PATH_INVALID (0xC0000000 | 0x0039)
+#define NT_STATUS_OBJECT_PATH_NOT_FOUND (0xC0000000 | 0x003a)
+#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD (0xC0000000 | 0x003b)
+#define NT_STATUS_DATA_OVERRUN (0xC0000000 | 0x003c)
+#define NT_STATUS_DATA_LATE_ERROR (0xC0000000 | 0x003d)
+#define NT_STATUS_DATA_ERROR (0xC0000000 | 0x003e)
+#define NT_STATUS_CRC_ERROR (0xC0000000 | 0x003f)
+#define NT_STATUS_SECTION_TOO_BIG (0xC0000000 | 0x0040)
+#define NT_STATUS_PORT_CONNECTION_REFUSED (0xC0000000 | 0x0041)
+#define NT_STATUS_INVALID_PORT_HANDLE (0xC0000000 | 0x0042)
+#define NT_STATUS_SHARING_VIOLATION (0xC0000000 | 0x0043)
+#define NT_STATUS_QUOTA_EXCEEDED (0xC0000000 | 0x0044)
+#define NT_STATUS_INVALID_PAGE_PROTECTION (0xC0000000 | 0x0045)
+#define NT_STATUS_MUTANT_NOT_OWNED (0xC0000000 | 0x0046)
+#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED (0xC0000000 | 0x0047)
+#define NT_STATUS_PORT_ALREADY_SET (0xC0000000 | 0x0048)
+#define NT_STATUS_SECTION_NOT_IMAGE (0xC0000000 | 0x0049)
+#define NT_STATUS_SUSPEND_COUNT_EXCEEDED (0xC0000000 | 0x004a)
+#define NT_STATUS_THREAD_IS_TERMINATING (0xC0000000 | 0x004b)
+#define NT_STATUS_BAD_WORKING_SET_LIMIT (0xC0000000 | 0x004c)
+#define NT_STATUS_INCOMPATIBLE_FILE_MAP (0xC0000000 | 0x004d)
+#define NT_STATUS_SECTION_PROTECTION (0xC0000000 | 0x004e)
+#define NT_STATUS_EAS_NOT_SUPPORTED (0xC0000000 | 0x004f)
+#define NT_STATUS_EA_TOO_LARGE (0xC0000000 | 0x0050)
+#define NT_STATUS_NONEXISTENT_EA_ENTRY (0xC0000000 | 0x0051)
+#define NT_STATUS_NO_EAS_ON_FILE (0xC0000000 | 0x0052)
+#define NT_STATUS_EA_CORRUPT_ERROR (0xC0000000 | 0x0053)
+#define NT_STATUS_FILE_LOCK_CONFLICT (0xC0000000 | 0x0054)
+#define NT_STATUS_LOCK_NOT_GRANTED (0xC0000000 | 0x0055)
+#define NT_STATUS_DELETE_PENDING (0xC0000000 | 0x0056)
+#define NT_STATUS_CTL_FILE_NOT_SUPPORTED (0xC0000000 | 0x0057)
+#define NT_STATUS_UNKNOWN_REVISION (0xC0000000 | 0x0058)
+#define NT_STATUS_REVISION_MISMATCH (0xC0000000 | 0x0059)
+#define NT_STATUS_INVALID_OWNER (0xC0000000 | 0x005a)
+#define NT_STATUS_INVALID_PRIMARY_GROUP (0xC0000000 | 0x005b)
+#define NT_STATUS_NO_IMPERSONATION_TOKEN (0xC0000000 | 0x005c)
+#define NT_STATUS_CANT_DISABLE_MANDATORY (0xC0000000 | 0x005d)
+#define NT_STATUS_NO_LOGON_SERVERS (0xC0000000 | 0x005e)
+#define NT_STATUS_NO_SUCH_LOGON_SESSION (0xC0000000 | 0x005f)
+#define NT_STATUS_NO_SUCH_PRIVILEGE (0xC0000000 | 0x0060)
+#define NT_STATUS_PRIVILEGE_NOT_HELD (0xC0000000 | 0x0061)
+#define NT_STATUS_INVALID_ACCOUNT_NAME (0xC0000000 | 0x0062)
+#define NT_STATUS_USER_EXISTS (0xC0000000 | 0x0063)
+#define NT_STATUS_NO_SUCH_USER (0xC0000000 | 0x0064)
+#define NT_STATUS_GROUP_EXISTS (0xC0000000 | 0x0065)
+#define NT_STATUS_NO_SUCH_GROUP (0xC0000000 | 0x0066)
+#define NT_STATUS_MEMBER_IN_GROUP (0xC0000000 | 0x0067)
+#define NT_STATUS_MEMBER_NOT_IN_GROUP (0xC0000000 | 0x0068)
+#define NT_STATUS_LAST_ADMIN (0xC0000000 | 0x0069)
+#define NT_STATUS_WRONG_PASSWORD (0xC0000000 | 0x006a)
+#define NT_STATUS_ILL_FORMED_PASSWORD (0xC0000000 | 0x006b)
+#define NT_STATUS_PASSWORD_RESTRICTION (0xC0000000 | 0x006c)
+#define NT_STATUS_LOGON_FAILURE (0xC0000000 | 0x006d)
+#define NT_STATUS_ACCOUNT_RESTRICTION (0xC0000000 | 0x006e)
+#define NT_STATUS_INVALID_LOGON_HOURS (0xC0000000 | 0x006f)
+#define NT_STATUS_INVALID_WORKSTATION (0xC0000000 | 0x0070)
+#define NT_STATUS_PASSWORD_EXPIRED (0xC0000000 | 0x0071)
+#define NT_STATUS_ACCOUNT_DISABLED (0xC0000000 | 0x0072)
+#define NT_STATUS_NONE_MAPPED (0xC0000000 | 0x0073)
+#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED (0xC0000000 | 0x0074)
+#define NT_STATUS_LUIDS_EXHAUSTED (0xC0000000 | 0x0075)
+#define NT_STATUS_INVALID_SUB_AUTHORITY (0xC0000000 | 0x0076)
+#define NT_STATUS_INVALID_ACL (0xC0000000 | 0x0077)
+#define NT_STATUS_INVALID_SID (0xC0000000 | 0x0078)
+#define NT_STATUS_INVALID_SECURITY_DESCR (0xC0000000 | 0x0079)
+#define NT_STATUS_PROCEDURE_NOT_FOUND (0xC0000000 | 0x007a)
+#define NT_STATUS_INVALID_IMAGE_FORMAT (0xC0000000 | 0x007b)
+#define NT_STATUS_NO_TOKEN (0xC0000000 | 0x007c)
+#define NT_STATUS_BAD_INHERITANCE_ACL (0xC0000000 | 0x007d)
+#define NT_STATUS_RANGE_NOT_LOCKED (0xC0000000 | 0x007e)
+#define NT_STATUS_DISK_FULL (0xC0000000 | 0x007f)
+#define NT_STATUS_SERVER_DISABLED (0xC0000000 | 0x0080)
+#define NT_STATUS_SERVER_NOT_DISABLED (0xC0000000 | 0x0081)
+#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED (0xC0000000 | 0x0082)
+#define NT_STATUS_GUIDS_EXHAUSTED (0xC0000000 | 0x0083)
+#define NT_STATUS_INVALID_ID_AUTHORITY (0xC0000000 | 0x0084)
+#define NT_STATUS_AGENTS_EXHAUSTED (0xC0000000 | 0x0085)
+#define NT_STATUS_INVALID_VOLUME_LABEL (0xC0000000 | 0x0086)
+#define NT_STATUS_SECTION_NOT_EXTENDED (0xC0000000 | 0x0087)
+#define NT_STATUS_NOT_MAPPED_DATA (0xC0000000 | 0x0088)
+#define NT_STATUS_RESOURCE_DATA_NOT_FOUND (0xC0000000 | 0x0089)
+#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND (0xC0000000 | 0x008a)
+#define NT_STATUS_RESOURCE_NAME_NOT_FOUND (0xC0000000 | 0x008b)
+#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED (0xC0000000 | 0x008c)
+#define NT_STATUS_FLOAT_DENORMAL_OPERAND (0xC0000000 | 0x008d)
+#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO (0xC0000000 | 0x008e)
+#define NT_STATUS_FLOAT_INEXACT_RESULT (0xC0000000 | 0x008f)
+#define NT_STATUS_FLOAT_INVALID_OPERATION (0xC0000000 | 0x0090)
+#define NT_STATUS_FLOAT_OVERFLOW (0xC0000000 | 0x0091)
+#define NT_STATUS_FLOAT_STACK_CHECK (0xC0000000 | 0x0092)
+#define NT_STATUS_FLOAT_UNDERFLOW (0xC0000000 | 0x0093)
+#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO (0xC0000000 | 0x0094)
+#define NT_STATUS_INTEGER_OVERFLOW (0xC0000000 | 0x0095)
+#define NT_STATUS_PRIVILEGED_INSTRUCTION (0xC0000000 | 0x0096)
+#define NT_STATUS_TOO_MANY_PAGING_FILES (0xC0000000 | 0x0097)
+#define NT_STATUS_FILE_INVALID (0xC0000000 | 0x0098)
+#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED (0xC0000000 | 0x0099)
+#define NT_STATUS_INSUFFICIENT_RESOURCES (0xC0000000 | 0x009a)
+#define NT_STATUS_DFS_EXIT_PATH_FOUND (0xC0000000 | 0x009b)
+#define NT_STATUS_DEVICE_DATA_ERROR (0xC0000000 | 0x009c)
+#define NT_STATUS_DEVICE_NOT_CONNECTED (0xC0000000 | 0x009d)
+#define NT_STATUS_DEVICE_POWER_FAILURE (0xC0000000 | 0x009e)
+#define NT_STATUS_FREE_VM_NOT_AT_BASE (0xC0000000 | 0x009f)
+#define NT_STATUS_MEMORY_NOT_ALLOCATED (0xC0000000 | 0x00a0)
+#define NT_STATUS_WORKING_SET_QUOTA (0xC0000000 | 0x00a1)
+#define NT_STATUS_MEDIA_WRITE_PROTECTED (0xC0000000 | 0x00a2)
+#define NT_STATUS_DEVICE_NOT_READY (0xC0000000 | 0x00a3)
+#define NT_STATUS_INVALID_GROUP_ATTRIBUTES (0xC0000000 | 0x00a4)
+#define NT_STATUS_BAD_IMPERSONATION_LEVEL (0xC0000000 | 0x00a5)
+#define NT_STATUS_CANT_OPEN_ANONYMOUS (0xC0000000 | 0x00a6)
+#define NT_STATUS_BAD_VALIDATION_CLASS (0xC0000000 | 0x00a7)
+#define NT_STATUS_BAD_TOKEN_TYPE (0xC0000000 | 0x00a8)
+#define NT_STATUS_BAD_MASTER_BOOT_RECORD (0xC0000000 | 0x00a9)
+#define NT_STATUS_INSTRUCTION_MISALIGNMENT (0xC0000000 | 0x00aa)
+#define NT_STATUS_INSTANCE_NOT_AVAILABLE (0xC0000000 | 0x00ab)
+#define NT_STATUS_PIPE_NOT_AVAILABLE (0xC0000000 | 0x00ac)
+#define NT_STATUS_INVALID_PIPE_STATE (0xC0000000 | 0x00ad)
+#define NT_STATUS_PIPE_BUSY (0xC0000000 | 0x00ae)
+#define NT_STATUS_ILLEGAL_FUNCTION (0xC0000000 | 0x00af)
+#define NT_STATUS_PIPE_DISCONNECTED (0xC0000000 | 0x00b0)
+#define NT_STATUS_PIPE_CLOSING (0xC0000000 | 0x00b1)
+#define NT_STATUS_PIPE_CONNECTED (0xC0000000 | 0x00b2)
+#define NT_STATUS_PIPE_LISTENING (0xC0000000 | 0x00b3)
+#define NT_STATUS_INVALID_READ_MODE (0xC0000000 | 0x00b4)
+#define NT_STATUS_IO_TIMEOUT (0xC0000000 | 0x00b5)
+#define NT_STATUS_FILE_FORCED_CLOSED (0xC0000000 | 0x00b6)
+#define NT_STATUS_PROFILING_NOT_STARTED (0xC0000000 | 0x00b7)
+#define NT_STATUS_PROFILING_NOT_STOPPED (0xC0000000 | 0x00b8)
+#define NT_STATUS_COULD_NOT_INTERPRET (0xC0000000 | 0x00b9)
+#define NT_STATUS_FILE_IS_A_DIRECTORY (0xC0000000 | 0x00ba)
+#define NT_STATUS_NOT_SUPPORTED (0xC0000000 | 0x00bb)
+#define NT_STATUS_REMOTE_NOT_LISTENING (0xC0000000 | 0x00bc)
+#define NT_STATUS_DUPLICATE_NAME (0xC0000000 | 0x00bd)
+#define NT_STATUS_BAD_NETWORK_PATH (0xC0000000 | 0x00be)
+#define NT_STATUS_NETWORK_BUSY (0xC0000000 | 0x00bf)
+#define NT_STATUS_DEVICE_DOES_NOT_EXIST (0xC0000000 | 0x00c0)
+#define NT_STATUS_TOO_MANY_COMMANDS (0xC0000000 | 0x00c1)
+#define NT_STATUS_ADAPTER_HARDWARE_ERROR (0xC0000000 | 0x00c2)
+#define NT_STATUS_INVALID_NETWORK_RESPONSE (0xC0000000 | 0x00c3)
+#define NT_STATUS_UNEXPECTED_NETWORK_ERROR (0xC0000000 | 0x00c4)
+#define NT_STATUS_BAD_REMOTE_ADAPTER (0xC0000000 | 0x00c5)
+#define NT_STATUS_PRINT_QUEUE_FULL (0xC0000000 | 0x00c6)
+#define NT_STATUS_NO_SPOOL_SPACE (0xC0000000 | 0x00c7)
+#define NT_STATUS_PRINT_CANCELLED (0xC0000000 | 0x00c8)
+#define NT_STATUS_NETWORK_NAME_DELETED (0xC0000000 | 0x00c9)
+#define NT_STATUS_NETWORK_ACCESS_DENIED (0xC0000000 | 0x00ca)
+#define NT_STATUS_BAD_DEVICE_TYPE (0xC0000000 | 0x00cb)
+#define NT_STATUS_BAD_NETWORK_NAME (0xC0000000 | 0x00cc)
+#define NT_STATUS_TOO_MANY_NAMES (0xC0000000 | 0x00cd)
+#define NT_STATUS_TOO_MANY_SESSIONS (0xC0000000 | 0x00ce)
+#define NT_STATUS_SHARING_PAUSED (0xC0000000 | 0x00cf)
+#define NT_STATUS_REQUEST_NOT_ACCEPTED (0xC0000000 | 0x00d0)
+#define NT_STATUS_REDIRECTOR_PAUSED (0xC0000000 | 0x00d1)
+#define NT_STATUS_NET_WRITE_FAULT (0xC0000000 | 0x00d2)
+#define NT_STATUS_PROFILING_AT_LIMIT (0xC0000000 | 0x00d3)
+#define NT_STATUS_NOT_SAME_DEVICE (0xC0000000 | 0x00d4)
+#define NT_STATUS_FILE_RENAMED (0xC0000000 | 0x00d5)
+#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED (0xC0000000 | 0x00d6)
+#define NT_STATUS_NO_SECURITY_ON_OBJECT (0xC0000000 | 0x00d7)
+#define NT_STATUS_CANT_WAIT (0xC0000000 | 0x00d8)
+#define NT_STATUS_PIPE_EMPTY (0xC0000000 | 0x00d9)
+#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO (0xC0000000 | 0x00da)
+#define NT_STATUS_CANT_TERMINATE_SELF (0xC0000000 | 0x00db)
+#define NT_STATUS_INVALID_SERVER_STATE (0xC0000000 | 0x00dc)
+#define NT_STATUS_INVALID_DOMAIN_STATE (0xC0000000 | 0x00dd)
+#define NT_STATUS_INVALID_DOMAIN_ROLE (0xC0000000 | 0x00de)
+#define NT_STATUS_NO_SUCH_DOMAIN (0xC0000000 | 0x00df)
+#define NT_STATUS_DOMAIN_EXISTS (0xC0000000 | 0x00e0)
+#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED (0xC0000000 | 0x00e1)
+#define NT_STATUS_OPLOCK_NOT_GRANTED (0xC0000000 | 0x00e2)
+#define NT_STATUS_INVALID_OPLOCK_PROTOCOL (0xC0000000 | 0x00e3)
+#define NT_STATUS_INTERNAL_DB_CORRUPTION (0xC0000000 | 0x00e4)
+#define NT_STATUS_INTERNAL_ERROR (0xC0000000 | 0x00e5)
+#define NT_STATUS_GENERIC_NOT_MAPPED (0xC0000000 | 0x00e6)
+#define NT_STATUS_BAD_DESCRIPTOR_FORMAT (0xC0000000 | 0x00e7)
+#define NT_STATUS_INVALID_USER_BUFFER (0xC0000000 | 0x00e8)
+#define NT_STATUS_UNEXPECTED_IO_ERROR (0xC0000000 | 0x00e9)
+#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR (0xC0000000 | 0x00ea)
+#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR (0xC0000000 | 0x00eb)
+#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR (0xC0000000 | 0x00ec)
+#define NT_STATUS_NOT_LOGON_PROCESS (0xC0000000 | 0x00ed)
+#define NT_STATUS_LOGON_SESSION_EXISTS (0xC0000000 | 0x00ee)
+#define NT_STATUS_INVALID_PARAMETER_1 (0xC0000000 | 0x00ef)
+#define NT_STATUS_INVALID_PARAMETER_2 (0xC0000000 | 0x00f0)
+#define NT_STATUS_INVALID_PARAMETER_3 (0xC0000000 | 0x00f1)
+#define NT_STATUS_INVALID_PARAMETER_4 (0xC0000000 | 0x00f2)
+#define NT_STATUS_INVALID_PARAMETER_5 (0xC0000000 | 0x00f3)
+#define NT_STATUS_INVALID_PARAMETER_6 (0xC0000000 | 0x00f4)
+#define NT_STATUS_INVALID_PARAMETER_7 (0xC0000000 | 0x00f5)
+#define NT_STATUS_INVALID_PARAMETER_8 (0xC0000000 | 0x00f6)
+#define NT_STATUS_INVALID_PARAMETER_9 (0xC0000000 | 0x00f7)
+#define NT_STATUS_INVALID_PARAMETER_10 (0xC0000000 | 0x00f8)
+#define NT_STATUS_INVALID_PARAMETER_11 (0xC0000000 | 0x00f9)
+#define NT_STATUS_INVALID_PARAMETER_12 (0xC0000000 | 0x00fa)
+#define NT_STATUS_REDIRECTOR_NOT_STARTED (0xC0000000 | 0x00fb)
+#define NT_STATUS_REDIRECTOR_STARTED (0xC0000000 | 0x00fc)
+#define NT_STATUS_STACK_OVERFLOW (0xC0000000 | 0x00fd)
+#define NT_STATUS_NO_SUCH_PACKAGE (0xC0000000 | 0x00fe)
+#define NT_STATUS_BAD_FUNCTION_TABLE (0xC0000000 | 0x00ff)
+#define NT_STATUS_DIRECTORY_NOT_EMPTY (0xC0000000 | 0x0101)
+#define NT_STATUS_FILE_CORRUPT_ERROR (0xC0000000 | 0x0102)
+#define NT_STATUS_NOT_A_DIRECTORY (0xC0000000 | 0x0103)
+#define NT_STATUS_BAD_LOGON_SESSION_STATE (0xC0000000 | 0x0104)
+#define NT_STATUS_LOGON_SESSION_COLLISION (0xC0000000 | 0x0105)
+#define NT_STATUS_NAME_TOO_LONG (0xC0000000 | 0x0106)
+#define NT_STATUS_FILES_OPEN (0xC0000000 | 0x0107)
+#define NT_STATUS_CONNECTION_IN_USE (0xC0000000 | 0x0108)
+#define NT_STATUS_MESSAGE_NOT_FOUND (0xC0000000 | 0x0109)
+#define NT_STATUS_PROCESS_IS_TERMINATING (0xC0000000 | 0x010a)
+#define NT_STATUS_INVALID_LOGON_TYPE (0xC0000000 | 0x010b)
+#define NT_STATUS_NO_GUID_TRANSLATION (0xC0000000 | 0x010c)
+#define NT_STATUS_CANNOT_IMPERSONATE (0xC0000000 | 0x010d)
+#define NT_STATUS_IMAGE_ALREADY_LOADED (0xC0000000 | 0x010e)
+#define NT_STATUS_ABIOS_NOT_PRESENT (0xC0000000 | 0x010f)
+#define NT_STATUS_ABIOS_LID_NOT_EXIST (0xC0000000 | 0x0110)
+#define NT_STATUS_ABIOS_LID_ALREADY_OWNED (0xC0000000 | 0x0111)
+#define NT_STATUS_ABIOS_NOT_LID_OWNER (0xC0000000 | 0x0112)
+#define NT_STATUS_ABIOS_INVALID_COMMAND (0xC0000000 | 0x0113)
+#define NT_STATUS_ABIOS_INVALID_LID (0xC0000000 | 0x0114)
+#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE (0xC0000000 | 0x0115)
+#define NT_STATUS_ABIOS_INVALID_SELECTOR (0xC0000000 | 0x0116)
+#define NT_STATUS_NO_LDT (0xC0000000 | 0x0117)
+#define NT_STATUS_INVALID_LDT_SIZE (0xC0000000 | 0x0118)
+#define NT_STATUS_INVALID_LDT_OFFSET (0xC0000000 | 0x0119)
+#define NT_STATUS_INVALID_LDT_DESCRIPTOR (0xC0000000 | 0x011a)
+#define NT_STATUS_INVALID_IMAGE_NE_FORMAT (0xC0000000 | 0x011b)
+#define NT_STATUS_RXACT_INVALID_STATE (0xC0000000 | 0x011c)
+#define NT_STATUS_RXACT_COMMIT_FAILURE (0xC0000000 | 0x011d)
+#define NT_STATUS_MAPPED_FILE_SIZE_ZERO (0xC0000000 | 0x011e)
+#define NT_STATUS_TOO_MANY_OPENED_FILES (0xC0000000 | 0x011f)
+#define NT_STATUS_CANCELLED (0xC0000000 | 0x0120)
+#define NT_STATUS_CANNOT_DELETE (0xC0000000 | 0x0121)
+#define NT_STATUS_INVALID_COMPUTER_NAME (0xC0000000 | 0x0122)
+#define NT_STATUS_FILE_DELETED (0xC0000000 | 0x0123)
+#define NT_STATUS_SPECIAL_ACCOUNT (0xC0000000 | 0x0124)
+#define NT_STATUS_SPECIAL_GROUP (0xC0000000 | 0x0125)
+#define NT_STATUS_SPECIAL_USER (0xC0000000 | 0x0126)
+#define NT_STATUS_MEMBERS_PRIMARY_GROUP (0xC0000000 | 0x0127)
+#define NT_STATUS_FILE_CLOSED (0xC0000000 | 0x0128)
+#define NT_STATUS_TOO_MANY_THREADS (0xC0000000 | 0x0129)
+#define NT_STATUS_THREAD_NOT_IN_PROCESS (0xC0000000 | 0x012a)
+#define NT_STATUS_TOKEN_ALREADY_IN_USE (0xC0000000 | 0x012b)
+#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED (0xC0000000 | 0x012c)
+#define NT_STATUS_COMMITMENT_LIMIT (0xC0000000 | 0x012d)
+#define NT_STATUS_INVALID_IMAGE_LE_FORMAT (0xC0000000 | 0x012e)
+#define NT_STATUS_INVALID_IMAGE_NOT_MZ (0xC0000000 | 0x012f)
+#define NT_STATUS_INVALID_IMAGE_PROTECT (0xC0000000 | 0x0130)
+#define NT_STATUS_INVALID_IMAGE_WIN_16 (0xC0000000 | 0x0131)
+#define NT_STATUS_LOGON_SERVER_CONFLICT (0xC0000000 | 0x0132)
+#define NT_STATUS_TIME_DIFFERENCE_AT_DC (0xC0000000 | 0x0133)
+#define NT_STATUS_SYNCHRONIZATION_REQUIRED (0xC0000000 | 0x0134)
+#define NT_STATUS_DLL_NOT_FOUND (0xC0000000 | 0x0135)
+#define NT_STATUS_OPEN_FAILED (0xC0000000 | 0x0136)
+#define NT_STATUS_IO_PRIVILEGE_FAILED (0xC0000000 | 0x0137)
+#define NT_STATUS_ORDINAL_NOT_FOUND (0xC0000000 | 0x0138)
+#define NT_STATUS_ENTRYPOINT_NOT_FOUND (0xC0000000 | 0x0139)
+#define NT_STATUS_CONTROL_C_EXIT (0xC0000000 | 0x013a)
+#define NT_STATUS_LOCAL_DISCONNECT (0xC0000000 | 0x013b)
+#define NT_STATUS_REMOTE_DISCONNECT (0xC0000000 | 0x013c)
+#define NT_STATUS_REMOTE_RESOURCES (0xC0000000 | 0x013d)
+#define NT_STATUS_LINK_FAILED (0xC0000000 | 0x013e)
+#define NT_STATUS_LINK_TIMEOUT (0xC0000000 | 0x013f)
+#define NT_STATUS_INVALID_CONNECTION (0xC0000000 | 0x0140)
+#define NT_STATUS_INVALID_ADDRESS (0xC0000000 | 0x0141)
+#define NT_STATUS_DLL_INIT_FAILED (0xC0000000 | 0x0142)
+#define NT_STATUS_MISSING_SYSTEMFILE (0xC0000000 | 0x0143)
+#define NT_STATUS_UNHANDLED_EXCEPTION (0xC0000000 | 0x0144)
+#define NT_STATUS_APP_INIT_FAILURE (0xC0000000 | 0x0145)
+#define NT_STATUS_PAGEFILE_CREATE_FAILED (0xC0000000 | 0x0146)
+#define NT_STATUS_NO_PAGEFILE (0xC0000000 | 0x0147)
+#define NT_STATUS_INVALID_LEVEL (0xC0000000 | 0x0148)
+#define NT_STATUS_WRONG_PASSWORD_CORE (0xC0000000 | 0x0149)
+#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT (0xC0000000 | 0x014a)
+#define NT_STATUS_PIPE_BROKEN (0xC0000000 | 0x014b)
+#define NT_STATUS_REGISTRY_CORRUPT (0xC0000000 | 0x014c)
+#define NT_STATUS_REGISTRY_IO_FAILED (0xC0000000 | 0x014d)
+#define NT_STATUS_NO_EVENT_PAIR (0xC0000000 | 0x014e)
+#define NT_STATUS_UNRECOGNIZED_VOLUME (0xC0000000 | 0x014f)
+#define NT_STATUS_SERIAL_NO_DEVICE_INITED (0xC0000000 | 0x0150)
+#define NT_STATUS_NO_SUCH_ALIAS (0xC0000000 | 0x0151)
+#define NT_STATUS_MEMBER_NOT_IN_ALIAS (0xC0000000 | 0x0152)
+#define NT_STATUS_MEMBER_IN_ALIAS (0xC0000000 | 0x0153)
+#define NT_STATUS_ALIAS_EXISTS (0xC0000000 | 0x0154)
+#define NT_STATUS_LOGON_NOT_GRANTED (0xC0000000 | 0x0155)
+#define NT_STATUS_TOO_MANY_SECRETS (0xC0000000 | 0x0156)
+#define NT_STATUS_SECRET_TOO_LONG (0xC0000000 | 0x0157)
+#define NT_STATUS_INTERNAL_DB_ERROR (0xC0000000 | 0x0158)
+#define NT_STATUS_FULLSCREEN_MODE (0xC0000000 | 0x0159)
+#define NT_STATUS_TOO_MANY_CONTEXT_IDS (0xC0000000 | 0x015a)
+#define NT_STATUS_LOGON_TYPE_NOT_GRANTED (0xC0000000 | 0x015b)
+#define NT_STATUS_NOT_REGISTRY_FILE (0xC0000000 | 0x015c)
+#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED (0xC0000000 | 0x015d)
+#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR (0xC0000000 | 0x015e)
+#define NT_STATUS_FT_MISSING_MEMBER (0xC0000000 | 0x015f)
+#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY (0xC0000000 | 0x0160)
+#define NT_STATUS_ILLEGAL_CHARACTER (0xC0000000 | 0x0161)
+#define NT_STATUS_UNMAPPABLE_CHARACTER (0xC0000000 | 0x0162)
+#define NT_STATUS_UNDEFINED_CHARACTER (0xC0000000 | 0x0163)
+#define NT_STATUS_FLOPPY_VOLUME (0xC0000000 | 0x0164)
+#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND (0xC0000000 | 0x0165)
+#define NT_STATUS_FLOPPY_WRONG_CYLINDER (0xC0000000 | 0x0166)
+#define NT_STATUS_FLOPPY_UNKNOWN_ERROR (0xC0000000 | 0x0167)
+#define NT_STATUS_FLOPPY_BAD_REGISTERS (0xC0000000 | 0x0168)
+#define NT_STATUS_DISK_RECALIBRATE_FAILED (0xC0000000 | 0x0169)
+#define NT_STATUS_DISK_OPERATION_FAILED (0xC0000000 | 0x016a)
+#define NT_STATUS_DISK_RESET_FAILED (0xC0000000 | 0x016b)
+#define NT_STATUS_SHARED_IRQ_BUSY (0xC0000000 | 0x016c)
+#define NT_STATUS_FT_ORPHANING (0xC0000000 | 0x016d)
+#define NT_STATUS_PARTITION_FAILURE (0xC0000000 | 0x0172)
+#define NT_STATUS_INVALID_BLOCK_LENGTH (0xC0000000 | 0x0173)
+#define NT_STATUS_DEVICE_NOT_PARTITIONED (0xC0000000 | 0x0174)
+#define NT_STATUS_UNABLE_TO_LOCK_MEDIA (0xC0000000 | 0x0175)
+#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA (0xC0000000 | 0x0176)
+#define NT_STATUS_EOM_OVERFLOW (0xC0000000 | 0x0177)
+#define NT_STATUS_NO_MEDIA (0xC0000000 | 0x0178)
+#define NT_STATUS_NO_SUCH_MEMBER (0xC0000000 | 0x017a)
+#define NT_STATUS_INVALID_MEMBER (0xC0000000 | 0x017b)
+#define NT_STATUS_KEY_DELETED (0xC0000000 | 0x017c)
+#define NT_STATUS_NO_LOG_SPACE (0xC0000000 | 0x017d)
+#define NT_STATUS_TOO_MANY_SIDS (0xC0000000 | 0x017e)
+#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED (0xC0000000 | 0x017f)
+#define NT_STATUS_KEY_HAS_CHILDREN (0xC0000000 | 0x0180)
+#define NT_STATUS_CHILD_MUST_BE_VOLATILE (0xC0000000 | 0x0181)
+#define NT_STATUS_DEVICE_CONFIGURATION_ERROR (0xC0000000 | 0x0182)
+#define NT_STATUS_DRIVER_INTERNAL_ERROR (0xC0000000 | 0x0183)
+#define NT_STATUS_INVALID_DEVICE_STATE (0xC0000000 | 0x0184)
+#define NT_STATUS_IO_DEVICE_ERROR (0xC0000000 | 0x0185)
+#define NT_STATUS_DEVICE_PROTOCOL_ERROR (0xC0000000 | 0x0186)
+#define NT_STATUS_BACKUP_CONTROLLER (0xC0000000 | 0x0187)
+#define NT_STATUS_LOG_FILE_FULL (0xC0000000 | 0x0188)
+#define NT_STATUS_TOO_LATE (0xC0000000 | 0x0189)
+#define NT_STATUS_NO_TRUST_LSA_SECRET (0xC0000000 | 0x018a)
+#define NT_STATUS_NO_TRUST_SAM_ACCOUNT (0xC0000000 | 0x018b)
+#define NT_STATUS_TRUSTED_DOMAIN_FAILURE (0xC0000000 | 0x018c)
+#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE (0xC0000000 | 0x018d)
+#define NT_STATUS_EVENTLOG_FILE_CORRUPT (0xC0000000 | 0x018e)
+#define NT_STATUS_EVENTLOG_CANT_START (0xC0000000 | 0x018f)
+#define NT_STATUS_TRUST_FAILURE (0xC0000000 | 0x0190)
+#define NT_STATUS_MUTANT_LIMIT_EXCEEDED (0xC0000000 | 0x0191)
+#define NT_STATUS_NETLOGON_NOT_STARTED (0xC0000000 | 0x0192)
+#define NT_STATUS_ACCOUNT_EXPIRED (0xC0000000 | 0x0193)
+#define NT_STATUS_POSSIBLE_DEADLOCK (0xC0000000 | 0x0194)
+#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT (0xC0000000 | 0x0195)
+#define NT_STATUS_REMOTE_SESSION_LIMIT (0xC0000000 | 0x0196)
+#define NT_STATUS_EVENTLOG_FILE_CHANGED (0xC0000000 | 0x0197)
+#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT (0xC0000000 | 0x0198)
+#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT (0xC0000000 | 0x0199)
+#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT (0xC0000000 | 0x019a)
+#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT (0xC0000000 | 0x019b)
+#define NT_STATUS_FS_DRIVER_REQUIRED (0xC0000000 | 0x019c)
+#define NT_STATUS_NO_USER_SESSION_KEY (0xC0000000 | 0x0202)
+#define NT_STATUS_USER_SESSION_DELETED (0xC0000000 | 0x0203)
+#define NT_STATUS_RESOURCE_LANG_NOT_FOUND (0xC0000000 | 0x0204)
+#define NT_STATUS_INSUFF_SERVER_RESOURCES (0xC0000000 | 0x0205)
+#define NT_STATUS_INVALID_BUFFER_SIZE (0xC0000000 | 0x0206)
+#define NT_STATUS_INVALID_ADDRESS_COMPONENT (0xC0000000 | 0x0207)
+#define NT_STATUS_INVALID_ADDRESS_WILDCARD (0xC0000000 | 0x0208)
+#define NT_STATUS_TOO_MANY_ADDRESSES (0xC0000000 | 0x0209)
+#define NT_STATUS_ADDRESS_ALREADY_EXISTS (0xC0000000 | 0x020a)
+#define NT_STATUS_ADDRESS_CLOSED (0xC0000000 | 0x020b)
+#define NT_STATUS_CONNECTION_DISCONNECTED (0xC0000000 | 0x020c)
+#define NT_STATUS_CONNECTION_RESET (0xC0000000 | 0x020d)
+#define NT_STATUS_TOO_MANY_NODES (0xC0000000 | 0x020e)
+#define NT_STATUS_TRANSACTION_ABORTED (0xC0000000 | 0x020f)
+#define NT_STATUS_TRANSACTION_TIMED_OUT (0xC0000000 | 0x0210)
+#define NT_STATUS_TRANSACTION_NO_RELEASE (0xC0000000 | 0x0211)
+#define NT_STATUS_TRANSACTION_NO_MATCH (0xC0000000 | 0x0212)
+#define NT_STATUS_TRANSACTION_RESPONDED (0xC0000000 | 0x0213)
+#define NT_STATUS_TRANSACTION_INVALID_ID (0xC0000000 | 0x0214)
+#define NT_STATUS_TRANSACTION_INVALID_TYPE (0xC0000000 | 0x0215)
+#define NT_STATUS_NOT_SERVER_SESSION (0xC0000000 | 0x0216)
+#define NT_STATUS_NOT_CLIENT_SESSION (0xC0000000 | 0x0217)
+#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE (0xC0000000 | 0x0218)
+#define NT_STATUS_DEBUG_ATTACH_FAILED (0xC0000000 | 0x0219)
+#define NT_STATUS_SYSTEM_PROCESS_TERMINATED (0xC0000000 | 0x021a)
+#define NT_STATUS_DATA_NOT_ACCEPTED (0xC0000000 | 0x021b)
+#define NT_STATUS_NO_BROWSER_SERVERS_FOUND (0xC0000000 | 0x021c)
+#define NT_STATUS_VDM_HARD_ERROR (0xC0000000 | 0x021d)
+#define NT_STATUS_DRIVER_CANCEL_TIMEOUT (0xC0000000 | 0x021e)
+#define NT_STATUS_REPLY_MESSAGE_MISMATCH (0xC0000000 | 0x021f)
+#define NT_STATUS_MAPPED_ALIGNMENT (0xC0000000 | 0x0220)
+#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH (0xC0000000 | 0x0221)
+#define NT_STATUS_LOST_WRITEBEHIND_DATA (0xC0000000 | 0x0222)
+#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID (0xC0000000 | 0x0223)
+#define NT_STATUS_PASSWORD_MUST_CHANGE (0xC0000000 | 0x0224)
+#define NT_STATUS_NOT_FOUND (0xC0000000 | 0x0225)
+#define NT_STATUS_NOT_TINY_STREAM (0xC0000000 | 0x0226)
+#define NT_STATUS_RECOVERY_FAILURE (0xC0000000 | 0x0227)
+#define NT_STATUS_STACK_OVERFLOW_READ (0xC0000000 | 0x0228)
+#define NT_STATUS_FAIL_CHECK (0xC0000000 | 0x0229)
+#define NT_STATUS_DUPLICATE_OBJECTID (0xC0000000 | 0x022a)
+#define NT_STATUS_OBJECTID_EXISTS (0xC0000000 | 0x022b)
+#define NT_STATUS_CONVERT_TO_LARGE (0xC0000000 | 0x022c)
+#define NT_STATUS_RETRY (0xC0000000 | 0x022d)
+#define NT_STATUS_FOUND_OUT_OF_SCOPE (0xC0000000 | 0x022e)
+#define NT_STATUS_ALLOCATE_BUCKET (0xC0000000 | 0x022f)
+#define NT_STATUS_PROPSET_NOT_FOUND (0xC0000000 | 0x0230)
+#define NT_STATUS_MARSHALL_OVERFLOW (0xC0000000 | 0x0231)
+#define NT_STATUS_INVALID_VARIANT (0xC0000000 | 0x0232)
+#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND (0xC0000000 | 0x0233)
+#define NT_STATUS_ACCOUNT_LOCKED_OUT (0xC0000000 | 0x0234)
+#define NT_STATUS_HANDLE_NOT_CLOSABLE (0xC0000000 | 0x0235)
+#define NT_STATUS_CONNECTION_REFUSED (0xC0000000 | 0x0236)
+#define NT_STATUS_GRACEFUL_DISCONNECT (0xC0000000 | 0x0237)
+#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED (0xC0000000 | 0x0238)
+#define NT_STATUS_ADDRESS_NOT_ASSOCIATED (0xC0000000 | 0x0239)
+#define NT_STATUS_CONNECTION_INVALID (0xC0000000 | 0x023a)
+#define NT_STATUS_CONNECTION_ACTIVE (0xC0000000 | 0x023b)
+#define NT_STATUS_NETWORK_UNREACHABLE (0xC0000000 | 0x023c)
+#define NT_STATUS_HOST_UNREACHABLE (0xC0000000 | 0x023d)
+#define NT_STATUS_PROTOCOL_UNREACHABLE (0xC0000000 | 0x023e)
+#define NT_STATUS_PORT_UNREACHABLE (0xC0000000 | 0x023f)
+#define NT_STATUS_REQUEST_ABORTED (0xC0000000 | 0x0240)
+#define NT_STATUS_CONNECTION_ABORTED (0xC0000000 | 0x0241)
+#define NT_STATUS_BAD_COMPRESSION_BUFFER (0xC0000000 | 0x0242)
+#define NT_STATUS_USER_MAPPED_FILE (0xC0000000 | 0x0243)
+#define NT_STATUS_AUDIT_FAILED (0xC0000000 | 0x0244)
+#define NT_STATUS_TIMER_RESOLUTION_NOT_SET (0xC0000000 | 0x0245)
+#define NT_STATUS_CONNECTION_COUNT_LIMIT (0xC0000000 | 0x0246)
+#define NT_STATUS_LOGIN_TIME_RESTRICTION (0xC0000000 | 0x0247)
+#define NT_STATUS_LOGIN_WKSTA_RESTRICTION (0xC0000000 | 0x0248)
+#define NT_STATUS_IMAGE_MP_UP_MISMATCH (0xC0000000 | 0x0249)
+#define NT_STATUS_INSUFFICIENT_LOGON_INFO (0xC0000000 | 0x0250)
+#define NT_STATUS_BAD_DLL_ENTRYPOINT (0xC0000000 | 0x0251)
+#define NT_STATUS_BAD_SERVICE_ENTRYPOINT (0xC0000000 | 0x0252)
+#define NT_STATUS_LPC_REPLY_LOST (0xC0000000 | 0x0253)
+#define NT_STATUS_IP_ADDRESS_CONFLICT1 (0xC0000000 | 0x0254)
+#define NT_STATUS_IP_ADDRESS_CONFLICT2 (0xC0000000 | 0x0255)
+#define NT_STATUS_REGISTRY_QUOTA_LIMIT (0xC0000000 | 0x0256)
+#define NT_STATUS_PATH_NOT_COVERED (0xC0000000 | 0x0257)
+#define NT_STATUS_NO_CALLBACK_ACTIVE (0xC0000000 | 0x0258)
+#define NT_STATUS_LICENSE_QUOTA_EXCEEDED (0xC0000000 | 0x0259)
+#define NT_STATUS_PWD_TOO_SHORT (0xC0000000 | 0x025a)
+#define NT_STATUS_PWD_TOO_RECENT (0xC0000000 | 0x025b)
+#define NT_STATUS_PWD_HISTORY_CONFLICT (0xC0000000 | 0x025c)
+#define NT_STATUS_PLUGPLAY_NO_DEVICE (0xC0000000 | 0x025e)
+#define NT_STATUS_UNSUPPORTED_COMPRESSION (0xC0000000 | 0x025f)
+#define NT_STATUS_INVALID_HW_PROFILE (0xC0000000 | 0x0260)
+#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH (0xC0000000 | 0x0261)
+#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND (0xC0000000 | 0x0262)
+#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND (0xC0000000 | 0x0263)
+#define NT_STATUS_RESOURCE_NOT_OWNED (0xC0000000 | 0x0264)
+#define NT_STATUS_TOO_MANY_LINKS (0xC0000000 | 0x0265)
+#define NT_STATUS_QUOTA_LIST_INCONSISTENT (0xC0000000 | 0x0266)
+#define NT_STATUS_FILE_IS_OFFLINE (0xC0000000 | 0x0267)
#define NT_STATUS_NO_SUCH_JOB (0xC0000000 | 0xEDE) /* scheduler */
+
+#endif /* _NTERR_H */
diff --git a/source/include/printing.h b/source/include/printing.h
index 676a0c74bfe..ee0b25d63fd 100644
--- a/source/include/printing.h
+++ b/source/include/printing.h
@@ -57,9 +57,9 @@ struct printif
extern struct printif generic_printif;
-#ifdef HAVE_LIBCUPS
+#ifdef HAVE_CUPS
extern struct printif cups_printif;
-#endif /* HAVE_LIBCUPS */
+#endif /* HAVE_CUPS */
#define PRINT_MAX_JOBID 10000
#define UNIX_JOB_START PRINT_MAX_JOBID
diff --git a/source/include/profile.h b/source/include/profile.h
index a8ffb963671..fbd83d6e3e1 100644
--- a/source/include/profile.h
+++ b/source/include/profile.h
@@ -35,7 +35,7 @@ enum flush_reason_enum { SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH,
#define PROF_SHMEM_KEY ((key_t)0x07021999)
#define PROF_SHM_MAGIC 0x6349985
-#define PROF_SHM_VERSION 4
+#define PROF_SHM_VERSION 5
/* time values in the following structure are in microseconds */
@@ -318,6 +318,56 @@ struct profile_stats {
unsigned NT_transact_rename_time;
unsigned NT_transact_query_security_desc_count;
unsigned NT_transact_query_security_desc_time;
+/* These are ACL manipulation calls */
+ unsigned get_nt_acl_count;
+ unsigned get_nt_acl_time;
+ unsigned fget_nt_acl_count;
+ unsigned fget_nt_acl_time;
+ unsigned set_nt_acl_count;
+ unsigned set_nt_acl_time;
+ unsigned fset_nt_acl_count;
+ unsigned fset_nt_acl_time;
+ unsigned chmod_acl_count;
+ unsigned chmod_acl_time;
+ unsigned fchmod_acl_count;
+ unsigned fchmod_acl_time;
+/* These are nmbd stats */
+ unsigned name_release_count;
+ unsigned name_release_time;
+ unsigned name_refresh_count;
+ unsigned name_refresh_time;
+ unsigned name_registration_count;
+ unsigned name_registration_time;
+ unsigned node_status_count;
+ unsigned node_status_time;
+ unsigned name_query_count;
+ unsigned name_query_time;
+ unsigned host_announce_count;
+ unsigned host_announce_time;
+ unsigned workgroup_announce_count;
+ unsigned workgroup_announce_time;
+ unsigned local_master_announce_count;
+ unsigned local_master_announce_time;
+ unsigned master_browser_announce_count;
+ unsigned master_browser_announce_time;
+ unsigned lm_host_announce_count;
+ unsigned lm_host_announce_time;
+ unsigned get_backup_list_count;
+ unsigned get_backup_list_time;
+ unsigned reset_browser_count;
+ unsigned reset_browser_time;
+ unsigned announce_request_count;
+ unsigned announce_request_time;
+ unsigned lm_announce_request_count;
+ unsigned lm_announce_request_time;
+ unsigned domain_logon_count;
+ unsigned domain_logon_time;
+ unsigned sync_browse_lists_count;
+ unsigned sync_browse_lists_time;
+ unsigned run_elections_count;
+ unsigned run_elections_time;
+ unsigned election_count;
+ unsigned election_time;
};
struct profile_header {
diff --git a/source/include/proto.h b/source/include/proto.h
index 72a649b72fb..66dd9d82c52 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -64,28 +64,6 @@ void check_log_size( void );
void dbgflush( void );
BOOL dbghdr( int level, char *file, char *func, int line );
-/*The following definitions come from lib/doscalls.c */
-
-int dos_unlink(char *fname);
-int dos_open(char *fname,int flags,mode_t mode);
-DIR *dos_opendir(char *dname);
-char *dos_readdirname(DIR *p);
-int dos_chown(char *fname, uid_t uid, gid_t gid);
-int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf);
-int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf);
-int dos_mkdir(char *dname,mode_t mode);
-int dos_rmdir(char *dname);
-int dos_chdir(char *dname);
-int dos_utime(char *fname,struct utimbuf *times);
-int copy_reg(char *source, const char *dest);
-int dos_rename(char *from, char *to);
-int dos_chmod(char *fname,mode_t mode);
-char *dos_getwd(char *unix_path);
-BOOL dos_file_exist(char *fname,SMB_STRUCT_STAT *sbuf);
-BOOL dos_directory_exist(char *dname,SMB_STRUCT_STAT *st);
-time_t dos_file_modtime(char *fname);
-SMB_OFF_T dos_file_size(char *file_name);
-
/*The following definitions come from lib/error.c */
uint32 map_nt_error_from_unix(int unix_error);
@@ -227,7 +205,29 @@ int sys_acl_set_fd( int fd, SMB_ACL_T theacl);
int sys_acl_delete_def_file(const char *name);
int sys_acl_free_text(char *text);
int sys_acl_free_acl(SMB_ACL_T the_acl) ;
-int sys_acl_free_qualifier(void *qual) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
+int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d);
+SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type);
+SMB_ACL_T sys_acl_get_fd(int fd);
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset);
+int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen);
+SMB_ACL_T sys_acl_init( int count);
+int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual);
+int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+int sys_acl_valid( SMB_ACL_T theacl );
+int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+int sys_acl_set_fd( int fd, SMB_ACL_T theacl);
+int sys_acl_delete_def_file(const char *name);
+int sys_acl_free_text(char *text);
+int sys_acl_free_acl(SMB_ACL_T the_acl) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p);
int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p);
int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
@@ -249,7 +249,7 @@ int sys_acl_set_fd(int fd, SMB_ACL_T acl_d);
int sys_acl_delete_def_file(const char *path);
int sys_acl_free_text(char *text);
int sys_acl_free_acl(SMB_ACL_T acl_d) ;
-int sys_acl_free_qualifier(void *qual) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p);
int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p);
int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
@@ -271,7 +271,7 @@ int sys_acl_set_fd(int fd, SMB_ACL_T acl_d);
int sys_acl_delete_def_file(const char *name);
int sys_acl_free_text(char *text);
int sys_acl_free_acl(SMB_ACL_T acl_d) ;
-int sys_acl_free_qualifier(void *qual) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
int sys_acl_get_entry( SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
@@ -293,7 +293,7 @@ int sys_acl_delete_def_file(const char *name);
int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
int sys_acl_free_text(char *text);
int sys_acl_free_acl(SMB_ACL_T posix_acl);
-int sys_acl_free_qualifier(void *qual);
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
@@ -315,7 +315,7 @@ int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl
int sys_acl_set_fd( int fd, SMB_ACL_T theacl);
int sys_acl_delete_def_file(const char *name);
int sys_acl_free_acl(SMB_ACL_T the_acl) ;
-int sys_acl_free_qualifier(void *qual) ;
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype);
/*The following definitions come from lib/system.c */
@@ -380,6 +380,8 @@ char *talloc_strdup(TALLOC_CTX *t, char *p);
/*The following definitions come from lib/time.c */
+time_t get_time_t_min(void);
+time_t get_time_t_max(void);
void GetTimeOfDay(struct timeval *tval);
void TimeInit(void);
int TimeDiff(time_t t);
@@ -419,7 +421,6 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups);
char *Atoic(char *p, int *n, char *c);
char *get_numlist(char *p, uint32 **num, int *count);
BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf);
-int file_rename(char *from, char *to);
time_t file_modtime(char *fname);
BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st);
SMB_OFF_T get_file_size(char *file_name);
@@ -434,7 +435,9 @@ void unix_clean_name(char *s);
void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date);
void close_low_fds(void);
int set_blocking(int fd, BOOL set);
-SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align);
+ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
+ ssize_t (*write_fn)(int, const void *, size_t));
+SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n);
void msleep(int t);
void become_daemon(void);
BOOL yesno(char *p);
@@ -479,6 +482,7 @@ char *lock_path(char *name);
char *parent_dirname(const char *path);
BOOL ms_has_wild(char *s);
BOOL mask_match(char *string, char *pattern, BOOL is_case_sensitive);
+BOOL unix_wild_match(char *pattern, char *string);
int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6);
/*The following definitions come from lib/util_array.c */
@@ -539,7 +543,7 @@ struct cli_connection* RpcHndList_get_connection(const POLICY_HND *hnd);
/*The following definitions come from lib/util_seaccess.c */
void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping);
-BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
+BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
uint32 acc_desired, uint32 *acc_granted, uint32 *status);
SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr,
BOOL child_container);
@@ -575,6 +579,7 @@ BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid);
int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2);
BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
size_t sid_size(DOM_SID *sid);
+BOOL non_mappable_sid(DOM_SID *sid);
/*The following definitions come from lib/util_sock.c */
@@ -592,7 +597,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout);
BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout);
BOOL send_smb(int fd,char *buffer);
BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
-int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind);
+int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL rebind );
int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
void client_setfd(int fd);
char *client_name(void);
@@ -643,7 +648,6 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len);
void split_at_last_component(char *path, char *front, char sep, char *back);
char *octal_string(int i);
char *string_truncate(char *s, int length);
-void parse_domain_user(char *domuser, fstring domain, fstring user);
/*The following definitions come from lib/util_unistr.c */
@@ -773,8 +777,7 @@ struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name,
struct ntuser_creds *creds);
void cli_samr_shutdown(struct cli_state *cli);
uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- char *srv_name, uint32 access_mask,
- POLICY_HND *connect_pol);
+ uint32 access_mask, POLICY_HND *connect_pol);
uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *connect_pol);
uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -788,7 +791,7 @@ uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 group_rid, POLICY_HND *group_pol);
uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol, uint16 switch_value,
- SAM_USERINFO_CTR *ctr);
+ SAM_USERINFO_CTR **ctr);
uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *group_pol, uint32 info_level,
GROUP_INFO_CTR *ctr);
@@ -815,6 +818,28 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *domain_pol, uint32 *start_idx,
uint16 switch_value, uint32 *num_entries,
uint32 max_entries, SAM_DISPINFO_CTR *ctr);
+uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_rids, uint32 *rids,
+ uint32 *num_names, char ***names,
+ uint32 **name_types);
+uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids,
+ uint32 **rid_types);
+uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, char *acct_name,
+ uint32 acb_info, uint32 unknown,
+ POLICY_HND *user_pol, uint32 *rid);
+uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr);
+uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr);
+uint32 cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol);
/*The following definitions come from libsmb/cli_spoolss.c */
@@ -1048,6 +1073,7 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat
/*The following definitions come from libsmb/clireadwrite.c */
ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
char *buf, off_t offset, size_t size);
@@ -1196,9 +1222,12 @@ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode);
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set);
BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
int new_pwrd_size, uint32 *new_pw_len,
uchar nt_p16[16], uchar p16[16]);
+void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]);
/*The following definitions come from libsmb/smberr.c */
@@ -1252,7 +1281,10 @@ void unlock_share_entry_fsp(files_struct *fsp);
int get_share_modes(connection_struct *conn,
SMB_DEV_T dev, SMB_INO_T inode,
share_mode_entry **shares);
-size_t del_share_mode(files_struct *fsp, share_mode_entry **ppse);
+BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2);
+ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
+ share_mode_entry *entry, share_mode_entry **ppse);
+ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse);
BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type);
BOOL remove_share_oplock(files_struct *fsp);
BOOL downgrade_share_oplock(files_struct *fsp);
@@ -1262,7 +1294,6 @@ int share_mode_forall(SHAREMODE_FN(fn));
/*The following definitions come from locking/posix.c */
int fd_close_posix(struct connection_struct *conn, files_struct *fsp);
-uint32 map_lock_offset(uint32 high, uint32 low);
BOOL is_posix_locked(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type);
BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type);
BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count);
@@ -1272,13 +1303,15 @@ BOOL posix_locking_end(void);
/*The following definitions come from msdfs/msdfs.c */
-BOOL create_junction(char* pathname, struct junction_map* jn);
-BOOL is_msdfs_link(connection_struct* conn, char* path);
-BOOL get_referred_path(struct junction_map* junction);
-BOOL dfs_redirect(char* pathname, connection_struct* conn);
-BOOL dfs_findfirst_redirect(char* pathname, connection_struct* conn);
+BOOL is_msdfs_link(connection_struct* conn, char* path,
+ struct referral** reflistp, int* refcnt);
+BOOL dfs_redirect(char* pathname, connection_struct* conn,
+ BOOL findfirst_flag);
+BOOL get_referred_path(char *pathname, struct junction_map* jn,
+ int* consumedcntp, BOOL* self_referralp);
int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata);
int dfs_path_error(char* inbuf, char* outbuf);
+BOOL create_junction(char* pathname, struct junction_map* jn);
BOOL create_msdfs_link(struct junction_map* jn, BOOL exists);
BOOL remove_msdfs_link(struct junction_map* jn);
int enum_msdfs_links(struct junction_map* jn);
@@ -1641,6 +1674,7 @@ BOOL winbind_nametogid(gid_t *pgid, char *gname);
/*The following definitions come from nsswitch/wb_common.c */
+void winbind_exclude_domain(const char *domain);
void init_request(struct winbindd_request *request, int request_type);
void init_response(struct winbindd_response *response);
void close_sock(void);
@@ -1648,6 +1682,43 @@ int write_sock(void *buffer, int count);
int read_reply(struct winbindd_response *response);
void free_response(struct winbindd_response *response);
+/*The following definitions come from nsswitch/winbindd_glue.c */
+
+BOOL wb_lsa_open_policy(char *server, BOOL sec_qos, uint32 des_access,
+ CLI_POLICY_HND *pol);
+BOOL wb_lsa_enum_trust_dom(CLI_POLICY_HND *hnd, uint32 *enum_ctx,
+ uint32 * num_doms, char ***names, DOM_SID **sids);
+BOOL wb_lsa_query_info_pol(CLI_POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, DOM_SID *domain_sid);
+BOOL wb_lsa_lookup_names(CLI_POLICY_HND *hnd, int num_names, char **names,
+ DOM_SID **sids, uint32 **types, int *num_sids);
+BOOL wb_lsa_lookup_sids(CLI_POLICY_HND *hnd, int num_sids, DOM_SID *sids,
+ char ***names, uint32 **types, int *num_names);
+BOOL wb_lsa_close(CLI_POLICY_HND *hnd);
+BOOL wb_samr_close(CLI_POLICY_HND *hnd);
+BOOL wb_samr_connect(char *server, uint32 access_mask, CLI_POLICY_HND *pol);
+BOOL wb_samr_open_domain(CLI_POLICY_HND *connect_pol, uint32 ace_perms,
+ DOM_SID *sid, CLI_POLICY_HND *domain_pol);
+uint32 wb_samr_enum_dom_groups(CLI_POLICY_HND *pol, uint32 *start_idx,
+ uint32 size, struct acct_info **sam,
+ uint32 *num_sam_groups);
+BOOL wb_get_samr_query_userinfo(CLI_POLICY_HND *pol, uint32 info_level,
+ uint32 user_rid, SAM_USERINFO_CTR **ctr);
+BOOL wb_samr_open_user(CLI_POLICY_HND *pol, uint32 access_mask, uint32 rid,
+ POLICY_HND *user_pol);
+BOOL wb_samr_query_usergroups(CLI_POLICY_HND *pol, uint32 *num_groups,
+ DOM_GID **gid);
+BOOL wb_get_samr_query_groupinfo(CLI_POLICY_HND *pol, uint32 info_level,
+ uint32 group_rid, GROUP_INFO_CTR *ctr);
+BOOL wb_sam_query_groupmem(CLI_POLICY_HND *pol, uint32 group_rid,
+ uint32 *num_names, uint32 **rid_mem,
+ char ***names, uint32 **name_types);
+BOOL wb_samr_query_dom_info(CLI_POLICY_HND *pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr);
+uint32 wb_samr_query_dispinfo(CLI_POLICY_HND *pol, uint32 *start_ndx,
+ uint16 info_level, uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr);
+
/*The following definitions come from param/loadparm.c */
void lp_talloc_free(void);
@@ -1701,12 +1772,15 @@ char *lp_winbind_gid(void);
char *lp_template_homedir(void);
char *lp_template_shell(void);
char *lp_winbind_separator(void);
+BOOL lp_winbind_enum_users(void);
+BOOL lp_winbind_enum_groups(void);
char *lp_codepagedir(void);
char *lp_ldap_server(void);
char *lp_ldap_suffix(void);
char *lp_ldap_filter(void);
-char *lp_ldap_root(void);
-char *lp_ldap_rootpasswd(void);
+char *lp_ldap_admin_dn(void);
+int lp_ldap_port(void);
+int lp_ldap_ssl(void);
char *lp_add_share_cmd(void);
char *lp_change_share_cmd(void);
char *lp_delete_share_cmd(void);
@@ -1720,6 +1794,9 @@ char *lp_ssl_privkey(void);
char *lp_ssl_client_cert(void);
char *lp_ssl_client_privkey(void);
char *lp_ssl_ciphers(void);
+char *lp_ssl_egdsocket(void);
+char *lp_ssl_entropyfile(void);
+int lp_ssl_entropybytes(void);
BOOL lp_ssl_enabled(void);
BOOL lp_ssl_reqClientCert(void);
BOOL lp_ssl_reqServerCert(void);
@@ -1764,6 +1841,7 @@ BOOL lp_lanman_auth(void);
BOOL lp_host_msdfs(void);
BOOL lp_kernel_oplocks(void);
BOOL lp_enhanced_browsing(void);
+BOOL lp_use_mmap(void);
int lp_os_level(void);
int lp_max_ttl(void);
int lp_max_wins_ttl(void);
@@ -1782,6 +1860,7 @@ int lp_security(void);
int lp_maxdisksize(void);
int lp_lpqcachetime(void);
int lp_max_smbd_processes(void);
+int lp_disable_spoolss(void);
int lp_totalprintjobs(void);
int lp_syslog(void);
int lp_client_code_page(void);
@@ -1793,7 +1872,6 @@ int lp_stat_cache_size(void);
int lp_map_to_guest(void);
int lp_min_passwd_length(void);
int lp_oplock_break_wait_time(void);
-int lp_ldap_port(void);
char *lp_preexec(int );
char *lp_postexec(int );
char *lp_rootpreexec(int );
@@ -1855,7 +1933,6 @@ BOOL lp_map_archive(int );
BOOL lp_locking(int );
BOOL lp_strict_locking(int );
BOOL lp_posix_locking(int );
-BOOL lp_share_modes(int );
BOOL lp_oplocks(int );
BOOL lp_level2_oplocks(int );
BOOL lp_onlyuser(int );
@@ -1863,6 +1940,7 @@ BOOL lp_manglednames(int );
BOOL lp_widelinks(int );
BOOL lp_symlinks(int );
BOOL lp_syncalways(int );
+BOOL lp_strict_allocate(int );
BOOL lp_strict_sync(int );
BOOL lp_map_system(int );
BOOL lp_delete_readonly(int );
@@ -1874,6 +1952,7 @@ BOOL lp_dos_filetime_resolution(int );
BOOL lp_fake_dir_create_times(int );
BOOL lp_blocking_locks(int );
BOOL lp_inherit_perms(int );
+BOOL lp_use_client_driver(int );
int lp_create_mask(int );
int lp_force_create_mode(int );
int lp_security_mask(int );
@@ -1924,6 +2003,7 @@ int lp_major_announce_version(void);
int lp_minor_announce_version(void);
void lp_set_name_resolve_order(char *new_order);
char *lp_printername(int snum);
+void get_private_directory(pstring priv_dir);
/*The following definitions come from param/params.c */
@@ -1931,13 +2011,9 @@ BOOL pm_process( char *FileName,
BOOL (*sfunc)(char *),
BOOL (*pfunc)(char *, char *) );
-/*The following definitions come from passdb/ldap.c */
-
-struct passdb_ops *ldap_initialize_password_db(void);
+/*The following definitions come from passdb/machine_sid.c */
-/*The following definitions come from passdb/nispass.c */
-
-struct passdb_ops *nisplus_initialize_password_db(void);
+BOOL pdb_generate_sam_sid(void);
/*The following definitions come from passdb/pampass.c */
@@ -1955,46 +2031,17 @@ BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd,
/*The following definitions come from passdb/passdb.c */
-BOOL initialize_password_db(void);
-void *startsmbpwent(BOOL update);
-void endsmbpwent(void *vp);
-struct smb_passwd *getsmbpwent(void *vp);
-BOOL add_smbpwd_entry(struct smb_passwd *newpwd);
-BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override);
-BOOL del_smbpwd_entry(const char *name);
-struct smb_passwd *getsmbpwnam(char *name);
-struct smb_passwd *getsmbpwrid(uint32 user_rid);
-struct smb_passwd *getsmbpwuid(uid_t smb_userid);
-struct sam_passwd *iterate_getsam21pwnam(char *name);
-struct sam_passwd *iterate_getsam21pwrid(uint32 rid);
-struct sam_passwd *iterate_getsam21pwuid(uid_t uid);
-struct sam_disp_info *getsamdisprid(uint32 rid);
-struct sam_passwd *getsam21pwent(void *vp);
-struct sam_passwd *getsam21pwnam(char *name);
-struct sam_passwd *getsam21pwrid(uint32 rid);
-BOOL add_sam21pwd_entry(struct sam_passwd *pwd);
-BOOL mod_sam21pwd_entry(struct sam_passwd *pwd, BOOL override);
-void pdb_init_smb(struct smb_passwd *user);
-void pdb_init_sam(struct sam_passwd *user);
-struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user);
-struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user);
-struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user);
-void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from);
-void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from);
-void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from);
+BOOL initialize_password_db(BOOL reload);
+BOOL pdb_init_sam(SAM_ACCOUNT **user);
+BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, struct passwd *pwd);
+BOOL pdb_reset_sam(SAM_ACCOUNT *user);
+BOOL pdb_free_sam(SAM_ACCOUNT *user);
+struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user);
char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
uint16 pdb_decode_acct_ctrl(const char *p);
-time_t pdb_get_last_set_time(const char *p);
-void pdb_set_logon_time(char *p, int max_len, time_t t);
-void pdb_set_logoff_time(char *p, int max_len, time_t t);
-void pdb_set_kickoff_time(char *p, int max_len, time_t t);
-void pdb_set_can_change_time(char *p, int max_len, time_t t);
-void pdb_set_must_change_time(char *p, int max_len, time_t t);
-void pdb_set_last_set_time(char *p, int max_len, time_t t);
void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl);
BOOL pdb_gethexpwd(char *p, unsigned char *pwd);
BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid);
-BOOL pdb_generate_sam_sid(void);
uid_t pdb_user_rid_to_uid(uint32 user_rid);
gid_t pdb_user_rid_to_gid(uint32 user_rid);
uint32 pdb_uid_to_user_rid(uid_t uid);
@@ -2006,6 +2053,122 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid);
BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type);
DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid);
BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type);
+void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from);
+void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from);
+void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from);
+BOOL local_password_change(char *user_name, int local_flags,
+ char *new_passwd,
+ char *err_str, size_t err_str_len,
+ char *msg_str, size_t msg_str_len);
+uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass);
+time_t pdb_get_logon_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_logoff_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_kickoff_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_pass_last_set_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_pass_can_change_time (SAM_ACCOUNT *sampass);
+time_t pdb_get_pass_must_change_time (SAM_ACCOUNT *sampass);
+uint16 pdb_get_logon_divs (SAM_ACCOUNT *sampass);
+uint32 pdb_get_hours_len (SAM_ACCOUNT *sampass);
+uint8* pdb_get_hours (SAM_ACCOUNT *sampass);
+uint8* pdb_get_nt_passwd (SAM_ACCOUNT *sampass);
+uint8* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass);
+uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass);
+uint32 pdb_get_group_rid (SAM_ACCOUNT *sampass);
+uid_t pdb_get_uid (SAM_ACCOUNT *sampass);
+gid_t pdb_get_gid (SAM_ACCOUNT *sampass);
+char* pdb_get_username (SAM_ACCOUNT *sampass);
+char* pdb_get_domain (SAM_ACCOUNT *sampass);
+char* pdb_get_nt_username (SAM_ACCOUNT *sampass);
+char* pdb_get_fullname (SAM_ACCOUNT *sampass);
+char* pdb_get_homedir (SAM_ACCOUNT *sampass);
+char* pdb_get_dirdrive (SAM_ACCOUNT *sampass);
+char* pdb_get_logon_script (SAM_ACCOUNT *sampass);
+char* pdb_get_profile_path (SAM_ACCOUNT *sampass);
+char* pdb_get_acct_desc (SAM_ACCOUNT *sampass);
+char* pdb_get_workstations (SAM_ACCOUNT *sampass);
+char* pdb_get_munged_dial (SAM_ACCOUNT *sampass);
+uint32 pdb_get_unknown3 (SAM_ACCOUNT *sampass);
+uint32 pdb_get_unknown5 (SAM_ACCOUNT *sampass);
+uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass);
+BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags);
+BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime);
+BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len);
+BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours);
+BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid);
+BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid);
+BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid);
+BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid);
+BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username);
+BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain);
+BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username);
+BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname);
+BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script);
+BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path);
+BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive);
+BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir);
+BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc);
+BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations);
+BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial);
+BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd);
+BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, uint8 *pwd);
+BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, char *plaintext);
+BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn);
+BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn);
+BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn);
+BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours);
+
+/*The following definitions come from passdb/pdb_ldap.c */
+
+BOOL pdb_setsampwent(BOOL update);
+void pdb_endsampwent(void);
+BOOL pdb_getsampwent(SAM_ACCOUNT * user);
+BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname);
+BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid);
+BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid);
+BOOL pdb_delete_sam_account(char *sname);
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override);
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd);
+
+/*The following definitions come from passdb/pdb_nisplus.c */
+
+BOOL pdb_setsampwent(BOOL update);
+void pdb_endsampwent(void);
+BOOL pdb_getsampwent(SAM_ACCOUNT *user);
+BOOL pdb_getsampwnam(SAM_ACCOUNT * user, char *sname);
+BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid);
+BOOL pdb_getsampwuid(SAM_ACCOUNT * user, uid_t uid);
+BOOL pdb_delete_sam_account(char *sname);
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd);
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd, BOOL override);
+
+/*The following definitions come from passdb/pdb_smbpasswd.c */
+
+BOOL pdb_setsampwent (BOOL update);
+void pdb_endsampwent (void);
+BOOL pdb_getsampwent(SAM_ACCOUNT *user);
+BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, char *username);
+BOOL pdb_getsampwuid (SAM_ACCOUNT *sam_acct, uid_t uid);
+BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid);
+BOOL pdb_add_sam_account(SAM_ACCOUNT *sampass);
+BOOL pdb_update_sam_account(SAM_ACCOUNT *sampass, BOOL override);
+BOOL pdb_delete_sam_account (char* username);
+
+/*The following definitions come from passdb/pdb_tdb.c */
+
+BOOL pdb_setsampwent(BOOL update);
+void pdb_endsampwent(void);
+BOOL pdb_getsampwent(SAM_ACCOUNT *user);
+BOOL pdb_getsampwnam (SAM_ACCOUNT *user, char *sname);
+BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid);
+BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid);
+BOOL pdb_delete_sam_account(char *sname);
+BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override);
+BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd);
/*The following definitions come from passdb/secrets.c */
@@ -2021,31 +2184,13 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16],
BOOL secrets_store_trust_account_password(char *domain, uint8 new_pwd[16]);
BOOL trust_password_delete(char *domain);
void reset_globals_after_fork(void);
-
-/*The following definitions come from passdb/smbpass.c */
-
-char *format_new_smbpasswd_entry(struct smb_passwd *newpwd);
-struct sam_passwd *smbiterate_getsam21pwrid(uint32 rid);
-struct sam_passwd *smbiterate_getsam21pwuid(uid_t uid);
-struct passdb_ops *file_initialize_password_db(void);
-
-/*The following definitions come from passdb/smbpasschange.c */
-
-BOOL local_password_change(char *user_name, int local_flags,
- char *new_passwd,
- char *err_str, size_t err_str_len,
- char *msg_str, size_t msg_str_len);
+BOOL secrets_store_ldap_pw(char* dn, char* pw);
+BOOL fetch_ldap_pw(char *dn, char* pw, int len);
/*The following definitions come from passdb/smbpassfile.c */
-BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth);
-BOOL pw_file_unlock(int fd, int *plock_depth);
BOOL migrate_from_old_password_file(char *domain);
-/*The following definitions come from passdb/tdbpass.c */
-
-struct passdb_ops *tdb_initialize_password_db(void);
-
/*The following definitions come from printing/load.c */
void add_all_printers(void);
@@ -2083,6 +2228,8 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr);
void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname);
uint32 mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level);
+uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level);
+uint32 save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param);
uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename);
uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level);
uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
@@ -2211,7 +2358,6 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]);
BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
-BOOL change_trust_account_password( char *domain, char *remote_machine_list);
/*The following definitions come from rpc_client/cli_pipe.c */
@@ -2231,6 +2377,10 @@ BOOL cli_spoolss_reply_rrpcn(struct cli_state *cli, POLICY_HND *handle,
uint32 change_low, uint32 change_high, uint32 *status);
BOOL cli_spoolss_reply_close_printer(struct cli_state *cli, POLICY_HND *handle, uint32 *status);
+/*The following definitions come from rpc_client/cli_trust.c */
+
+BOOL change_trust_account_password( char *domain, char *remote_machine_list);
+
/*The following definitions come from rpc_client/cli_use.c */
void init_cli_use(void);
@@ -2353,7 +2503,7 @@ BOOL init_q_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM * q_e, POLICY_HND *pol,
uint32 enum_context, uint32 preferred_len);
BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e,
prs_struct *ps, int depth);
-void init_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
+void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
char *domain_name, DOM_SID *domain_sid,
uint32 status);
BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e,
@@ -2510,38 +2660,12 @@ void init_sam_info(DOM_SAM_INFO *sam,
char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
DOM_CRED *rtn_cred, uint16 logon_level,
NET_ID_INFO_CTR *ctr);
-void init_net_user_info3(TALLOC_CTX *ctx,
- NET_USER_INFO_3 *usr,
- NTTIME *logon_time,
- NTTIME *logoff_time,
- NTTIME *kickoff_time,
- NTTIME *pass_last_set_time,
- NTTIME *pass_can_change_time,
- NTTIME *pass_must_change_time,
-
- char *user_name,
- char *full_name,
- char *logon_script,
- char *profile_path,
- char *home_dir,
- char *dir_drive,
-
- uint16 logon_count,
- uint16 bad_pw_count,
-
- uint32 user_id,
- uint32 group_id,
- uint32 num_groups,
- DOM_GID *gids,
- uint32 user_flgs,
-
- char *sess_key,
-
- char *logon_srv,
- char *logon_dom,
-
- DOM_SID *dom_sid,
- char *other_sids);
+void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
+ uint16 logon_count, uint16 bad_pw_count,
+ uint32 num_groups, DOM_GID *gids,
+ uint32 user_flgs, char *sess_key,
+ char *logon_srv, char *logon_dom,
+ DOM_SID *dom_sid, char *other_sids);
BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
@@ -3047,7 +3171,7 @@ void init_sam_user_info11(SAM_USER_INFO_11 * usr,
NTTIME * expiry,
char *mach_acct,
uint32 rid_user, uint32 rid_group, uint16 acct_ctrl);
-void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516]);
+void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516], uint16 pw_len);
void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all zeros */
NTTIME * logoff_time, /* all zeros */
NTTIME * kickoff_time, /* all zeros */
@@ -3113,30 +3237,7 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
uint16 logon_divs,
LOGON_HRS * hrs,
uint32 unknown_5, uint32 unknown_6);
-void init_sam_user_info21A(SAM_USER_INFO_21 * usr,
- NTTIME * logon_time,
- NTTIME * logoff_time,
- NTTIME * kickoff_time,
- NTTIME * pass_last_set_time,
- NTTIME * pass_can_change_time,
- NTTIME * pass_must_change_time,
- char *user_name,
- char *full_name,
- char *home_dir,
- char *dir_drive,
- char *log_scr,
- char *prof_path,
- char *desc,
- char *wkstas,
- char *unk_str,
- char *mung_dial,
- uint32 user_rid,
- uint32 group_rid,
- uint32 acb_info,
- uint32 unknown_3,
- uint16 logon_divs,
- LOGON_HRS * hrs,
- uint32 unknown_5, uint32 unknown_6);
+void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw);
uint32 make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
uint16 switch_value,
SAM_USER_INFO_21 * usr);
@@ -3227,6 +3328,7 @@ BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth
BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
prs_struct *ps, int depth);
+BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode);
BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
const fstring printername,
const fstring datatype,
@@ -3845,6 +3947,7 @@ uint32 _wks_query_info(pipes_struct *p, WKS_Q_QUERY_INFO *q_u, WKS_R_QUERY_INFO
/*The following definitions come from rpcclient/cmd_samr.c */
+void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1);
/*The following definitions come from rpcclient/cmd_spoolss.c */
@@ -3876,8 +3979,8 @@ void process_blocking_lock_queue(time_t t);
BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root);
BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root);
BOOL check_lanman_password(char *user, uchar * pass1,
- uchar * pass2, struct smb_passwd **psmbpw);
-BOOL change_lanman_password(struct smb_passwd *smbpw, uchar * pass1,
+ uchar * pass2, SAM_ACCOUNT **hnd);
+BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar * pass1,
uchar * pass2);
BOOL pass_oem_change(char *user,
uchar * lmdata, uchar * lmhash,
@@ -3885,12 +3988,12 @@ BOOL pass_oem_change(char *user,
BOOL check_oem_password(char *user,
uchar * lmdata, uchar * lmhash,
uchar * ntdata, uchar * nthash,
- struct smb_passwd **psmbpw, char *new_passwd,
+ SAM_ACCOUNT **hnd, char *new_passwd,
int new_passwd_size);
-BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd,
+BOOL change_oem_password(SAM_ACCOUNT *hnd, char *new_passwd,
BOOL override);
BOOL check_plaintext_password(char *user, char *old_passwd,
- int old_passwd_size, struct smb_passwd **psmbpw);
+ int old_passwd_size, SAM_ACCOUNT **hnd);
/*The following definitions come from smbd/close.c */
@@ -3957,9 +4060,8 @@ BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime);
/*The following definitions come from smbd/error.c */
-int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line);
-int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
-int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line);
+int unix_error_packet(char *outbuf,int def_class,uint32 def_code,int line, const char *file);
+int error_packet(char *outbuf,uint32 nt_err, int error_class,uint32 error_code,int line, const char *file);
/*The following definitions come from smbd/fileio.c */
@@ -4059,8 +4161,6 @@ struct cnotify_fns *kernel_notify_init(void) ;
/*The following definitions come from smbd/nttrans.c */
-void fail_next_srvsvc_open(void);
-BOOL should_fail_next_srvsvc_open(const char *pipename);
int reply_ntcreate_and_X(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
int reply_ntcancel(connection_struct *conn,
@@ -4086,6 +4186,7 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
/*The following definitions come from smbd/oplock.c */
int32 get_number_of_exclusive_open_oplocks(void);
+BOOL oplock_message_waiting(fd_set *fds);
BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout);
BOOL set_file_oplock(files_struct *fsp, int oplock_type);
void release_file_oplock(files_struct *fsp);
@@ -4121,11 +4222,10 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
char *domain,BOOL guest);
void add_session_user(char *user);
BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
-BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
+BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8],
uchar lm_pass[24], uchar nt_pass[24]);
-BOOL pass_check_smb(char *user, char *domain,
- uchar *chal, uchar *lm_pwd, uchar *nt_pwd,
- struct passwd *pwd);
+BOOL pass_check_smb(char *user, char *domain, uchar *chal,
+ uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd);
BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd);
BOOL user_ok(char *user,int snum);
BOOL authorise_login(int snum,char *user,char *password, int pwlen,
@@ -4194,12 +4294,14 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
int unlink_internals(connection_struct *conn, char *inbuf,char *outbuf,
int dirtype, char *name);
int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+void fail_readraw(void);
int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz);
int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int allocate_space_error(char *inbuf,char *outbuf, int errno_val);
int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize);
int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
@@ -4238,9 +4340,6 @@ uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format);
SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format);
SMB_BIG_UINT get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err);
int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
-int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
-int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
-int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
@@ -4339,10 +4438,10 @@ int vfswrap_rmdir(connection_struct *conn, char *path);
int vfswrap_closedir(connection_struct *conn, DIR *dirp);
int vfswrap_open(connection_struct *conn, char *fname, int flags, mode_t mode);
int vfswrap_close(files_struct *fsp, int fd);
-ssize_t vfswrap_read(files_struct *fsp, int fd, char *data, size_t n);
-ssize_t vfswrap_write(files_struct *fsp, int fd, char *data, size_t n);
+ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n);
+ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n);
SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
-int vfswrap_rename(connection_struct *conn, char *old, char *new);
+int vfswrap_rename(connection_struct *conn, char *oldname, char *newname);
int vfswrap_fsync(files_struct *fsp, int fd);
int vfswrap_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *sbuf);
int vfswrap_fstat(files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
@@ -4375,10 +4474,9 @@ char *vfs_getwd(connection_struct *conn, char *unix_path);
BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf);
ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count);
ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N);
+int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len);
int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len);
-SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp,
- int out_fd, files_struct *out_fsp,
- SMB_OFF_T n, char *header, int headlen, int align);
+SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n);
char *vfs_readdirname(connection_struct *conn, void *p);
int vfs_ChDir(connection_struct *conn, char *path);
char *vfs_GetWd(connection_struct *conn, char *path);
@@ -4495,6 +4593,8 @@ void tdb_unlockkeys(TDB_CONTEXT *tdb);
int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key);
void tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key);
void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...));
+int tdb_reopen(TDB_CONTEXT *tdb);
+int tdb_reopen_all(void);
/*The following definitions come from tdb/tdbutil.c */
@@ -4528,6 +4628,7 @@ void nb_create(char *fname, int size);
/*The following definitions come from utils/torture.c */
+int cli_setfileinfo_test(struct cli_state *cli, int fnum, int level, char *data, int data_len);
/*The following definitions come from web/cgi.c */
diff --git a/source/include/rpc_dfs.h b/source/include/rpc_dfs.h
index 40e73c5afb4..193075f754d 100644
--- a/source/include/rpc_dfs.h
+++ b/source/include/rpc_dfs.h
@@ -35,7 +35,6 @@
#define DFSFLAG_ADD_VOLUME 0x00000001
#define DFSFLAG_RESTORE_VOLUME 0x00000002
-/* API errors from lmerr.h */
#ifndef NERR_BASE
#define NERR_BASE (2100)
#endif
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index cdfb19580de..c3bd20921dd 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -217,6 +217,7 @@ typedef struct sam_user_info_23
typedef struct sam_user_info_24
{
uint8 pass[516];
+ uint16 pw_len;
} SAM_USER_INFO_24;
/*
diff --git a/source/include/smb.h b/source/include/smb.h
index 7cb9c0bb973..ac76ff8f928 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -153,119 +153,7 @@ implemented */
#define STYPE_IPC 3 /* Interprocess communication (IPC) */
#define STYPE_HIDDEN 0x80000000 /* share is a hidden one (ends with $) */
-/* SMB X/Open error codes for the ERRDOS error class */
-#define ERRbadfunc 1 /* Invalid function (or system call) */
-#define ERRbadfile 2 /* File not found (pathname error) */
-#define ERRbadpath 3 /* Directory not found */
-#define ERRnofids 4 /* Too many open files */
-#define ERRnoaccess 5 /* Access denied */
-#define ERRbadfid 6 /* Invalid fid */
-#define ERRnomem 8 /* Out of memory */
-#define ERRbadmem 9 /* Invalid memory block address */
-#define ERRbadenv 10 /* Invalid environment */
-#define ERRbadaccess 12 /* Invalid open mode */
-#define ERRbaddata 13 /* Invalid data (only from ioctl call) */
-#define ERRres 14 /* reserved */
-#define ERRbaddrive 15 /* Invalid drive */
-#define ERRremcd 16 /* Attempt to delete current directory */
-#define ERRdiffdevice 17 /* rename/move across different filesystems */
-#define ERRnofiles 18 /* no more files found in file search */
-#define ERRbadshare 32 /* Share mode on file conflict with open mode */
-#define ERRlock 33 /* Lock request conflicts with existing lock */
-#define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */
-#define ERRnosuchshare 67 /* You specified an invalid share name */
-#define ERRfilexists 80 /* File in operation already exists */
-#define ERRcannotopen 110 /* Cannot open the file specified */
-#define ERRunknownlevel 124
-#define ERRnotlocked 158 /* This region is not locked by this locking context. */
-#define ERRrename 183
-#define ERRbadpipe 230 /* Named pipe invalid */
-#define ERRpipebusy 231 /* All instances of pipe are busy */
-#define ERRpipeclosing 232 /* named pipe close in progress */
-#define ERRnotconnected 233 /* No process on other end of named pipe */
-#define ERRmoredata 234 /* More data to be returned */
-#define ERRbaddirectory 267 /* Invalid directory name in a path. */
-#define ERRunknownipc 2142
-#define ERRbuftoosmall 2123
-#define ERRnosuchprintjob 2151
-
-#define ERROR_SUCCESS (0)
-#define ERROR_INVALID_FUNCTION (1)
-#define ERROR_ACCESS_DENIED (5)
-#define ERROR_INVALID_HANDLE (6)
-#define ERROR_NOT_ENOUGH_MEMORY (8)
-#define ERROR_INVALID_PARAMETER (87)
-#define ERROR_INSUFFICIENT_BUFFER (122)
-#define ERROR_INVALID_NAME (123)
-#define ERROR_INVALID_LEVEL (124)
-#define ERROR_MORE_DATA (234)
-#define ERROR_NO_MORE_ITEMS (259)
-#define ERROR_EAS_DIDNT_FIT (275) /* Extended attributes didn't fit */
-#define ERROR_EAS_NOT_SUPPORTED (282) /* Extended attributes not supported */
-#define ERROR_NOTIFY_ENUM_DIR (1022) /* Buffer too small to return change notify. */
-#define ERROR_UNKNOWN_PRINTER_DRIVER (1797)
-#define ERROR_INVALID_PRINTER_NAME (1801)
-#define ERROR_INVALID_DATATYPE (1804)
-#define ERROR_INVALID_ENVIRONMENT (1805)
-#define ERROR_PRINTER_DRIVER_IN_USE (3001)
-
-/* here's a special one from observing NT */
-#define ERRnoipc 66 /* don't support ipc */
-
-/* Error codes for the ERRSRV class */
-
-#define ERRerror 1 /* Non specific error code */
-#define ERRbadpw 2 /* Bad password */
-#define ERRbadtype 3 /* reserved */
-#define ERRaccess 4 /* No permissions to do the requested operation */
-#define ERRinvnid 5 /* tid invalid */
-#define ERRinvnetname 6 /* Invalid servername */
-#define ERRinvdevice 7 /* Invalid device */
-#define ERRqfull 49 /* Print queue full */
-#define ERRqtoobig 50 /* Queued item too big */
-#define ERRinvpfid 52 /* Invalid print file in smb_fid */
-#define ERRsmbcmd 64 /* Unrecognised command */
-#define ERRsrverror 65 /* smb server internal error */
-#define ERRfilespecs 67 /* fid and pathname invalid combination */
-#define ERRbadlink 68 /* reserved */
-#define ERRbadpermits 69 /* Access specified for a file is not valid */
-#define ERRbadpid 70 /* reserved */
-#define ERRsetattrmode 71 /* attribute mode invalid */
-#define ERRpaused 81 /* Message server paused */
-#define ERRmsgoff 82 /* Not receiving messages */
-#define ERRnoroom 83 /* No room for message */
-#define ERRrmuns 87 /* too many remote usernames */
-#define ERRtimeout 88 /* operation timed out */
-#define ERRnoresource 89 /* No resources currently available for request. */
-#define ERRtoomanyuids 90 /* too many userids */
-#define ERRbaduid 91 /* bad userid */
-#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */
-#define ERRuseSTD 251 /* temporarily unable to use raw mode, use standard mode */
-#define ERRcontMPX 252 /* resume MPX mode */
-#define ERRbadPW /* reserved */
-#define ERRnosupport 0xFFFF
-#define ERRunknownsmb 22 /* from NT 3.5 response */
-
-
-/* Error codes for the ERRHRD class */
-
-#define ERRnowrite 19 /* read only media */
-#define ERRbadunit 20 /* Unknown device */
-#define ERRnotready 21 /* Drive not ready */
-#define ERRbadcmd 22 /* Unknown command */
-#define ERRdata 23 /* Data (CRC) error */
-#define ERRbadreq 24 /* Bad request structure length */
-#define ERRseek 25
-#define ERRbadmedia 26
-#define ERRbadsector 27
-#define ERRnopaper 28
-#define ERRwrite 29 /* write fault */
-#define ERRread 30 /* read fault */
-#define ERRgeneral 31 /* General hardware failure */
-#define ERRwrongdisk 34
-#define ERRFCBunavail 35
-#define ERRsharebufexc 36 /* share buffer exceeded */
-#define ERRdiskfull 39
+#include "doserr.h"
#ifndef _PSTRING
@@ -326,57 +214,6 @@ typedef struct nttime_info
#define MAX_HOURS_LEN 32
-struct sam_passwd
-{
- time_t logon_time; /* logon time */
- time_t logoff_time; /* logoff time */
- time_t kickoff_time; /* kickoff time */
- time_t pass_last_set_time; /* password last set time */
- time_t pass_can_change_time; /* password can change time */
- time_t pass_must_change_time; /* password must change time */
-
- char *smb_name; /* username string */
- char *full_name; /* user's full name string */
- char *home_dir; /* home directory string */
- char *dir_drive; /* home directory drive string */
- char *logon_script; /* logon script string */
- char *profile_path; /* profile path string */
- char *acct_desc ; /* user description string */
- char *workstations; /* login from workstations string */
- char *unknown_str ; /* don't know what this is, yet. */
- char *munged_dial ; /* munged path name and dial-back tel number */
-
- uid_t smb_userid; /* this is actually the unix uid_t */
- gid_t smb_grpid; /* this is actually the unix gid_t */
- uint32 user_rid; /* Primary User ID */
- uint32 group_rid; /* Primary Group ID */
-
- unsigned char *smb_passwd; /* Null if no password */
- unsigned char *smb_nt_passwd; /* Null if no password */
-
- uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
- uint32 unknown_3; /* 0x00ff ffff */
-
- uint16 logon_divs; /* 168 - number of hours in a week */
- uint32 hours_len; /* normally 21 bytes */
- uint8 hours[MAX_HOURS_LEN];
-
- uint32 unknown_5; /* 0x0002 0000 */
- uint32 unknown_6; /* 0x0000 04ec */
-};
-
-struct smb_passwd
-{
- uid_t smb_userid; /* this is actually the unix uid_t */
- char *smb_name; /* username string */
-
- unsigned char *smb_passwd; /* Null if no password */
- unsigned char *smb_nt_passwd; /* Null if no password */
-
- uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
- time_t pass_last_set_time; /* password last set time */
-};
-
struct sam_disp_info
{
@@ -697,69 +534,48 @@ typedef struct
#define SHAREMODE_FN(fn) \
void (*fn)(share_mode_entry *, char*)
-/*
- * Each implementation of the password database code needs
- * to support the following operations.
- */
-
-struct passdb_ops {
- /*
- * Password database ops.
- */
- void *(*startsmbpwent)(BOOL);
- void (*endsmbpwent)(void *);
- SMB_BIG_UINT (*getsmbpwpos)(void *);
- BOOL (*setsmbpwpos)(void *, SMB_BIG_UINT);
-
- /*
- * smb password database query functions.
- */
- struct smb_passwd *(*getsmbpwnam)(char *);
- struct smb_passwd *(*getsmbpwuid)(uid_t);
- struct smb_passwd *(*getsmbpwrid)(uint32);
- struct smb_passwd *(*getsmbpwent)(void *);
-
- /*
- * smb password database modification functions.
- */
- BOOL (*add_smbpwd_entry)(struct smb_passwd *);
- BOOL (*mod_smbpwd_entry)(struct smb_passwd *, BOOL);
- BOOL (*del_smbpwd_entry)(const char *);
+typedef struct sam_passwd
+{
+ time_t logon_time; /* logon time */
+ time_t logoff_time; /* logoff time */
+ time_t kickoff_time; /* kickoff time */
+ time_t pass_last_set_time; /* password last set time */
+ time_t pass_can_change_time; /* password can change time */
+ time_t pass_must_change_time; /* password must change time */
- /*
- * Functions that manupulate a struct sam_passwd.
- */
- struct sam_passwd *(*getsam21pwent)(void *);
+ pstring username; /* UNIX username string */
+ pstring domain; /* Windows Domain name */
+ pstring nt_username; /* Windows username string */
+ pstring full_name; /* user's full name string */
+ pstring home_dir; /* home directory string */
+ pstring dir_drive; /* home directory drive string */
+ pstring logon_script; /* logon script string */
+ pstring profile_path; /* profile path string */
+ pstring acct_desc ; /* user description string */
+ pstring workstations; /* login from workstations string */
+ pstring unknown_str ; /* don't know what this is, yet. */
+ pstring munged_dial ; /* munged path name and dial-back tel number */
+
+ uid_t uid; /* this is actually the unix uid_t */
+ gid_t gid; /* this is actually the unix gid_t */
+ uint32 user_rid; /* Primary User ID */
+ uint32 group_rid; /* Primary Group ID */
+
+ unsigned char *lm_pw; /* Null if no password */
+ unsigned char *nt_pw; /* Null if no password */
- /*
- * sam password database query functions.
- */
- struct sam_passwd *(*getsam21pwnam)(char *);
- struct sam_passwd *(*getsam21pwuid)(uid_t);
- struct sam_passwd *(*getsam21pwrid)(uint32);
+ uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
+ uint32 unknown_3; /* 0x00ff ffff */
- /*
- * sam password database modification functions.
- */
- BOOL (*add_sam21pwd_entry)(struct sam_passwd *);
- BOOL (*mod_sam21pwd_entry)(struct sam_passwd *, BOOL);
+ uint16 logon_divs; /* 168 - number of hours in a week */
+ uint32 hours_len; /* normally 21 bytes */
+ uint8 hours[MAX_HOURS_LEN];
- /*
- * sam query display info functions.
- */
- struct sam_disp_info *(*getsamdispnam)(char *);
- struct sam_disp_info *(*getsamdisprid)(uint32);
- struct sam_disp_info *(*getsamdispent)(void *);
+ uint32 unknown_5; /* 0x0002 0000 */
+ uint32 unknown_6; /* 0x0000 04ec */
+
+} SAM_ACCOUNT;
-#if 0
- /*
- * password checking functions
- */
- struct smb_passwd *(*smb_password_chal )(char *username, char lm_pass[24], char nt_pass[24], char chal[8]);
- struct smb_passwd *(*smb_password_check )(char *username, char lm_hash[16], char nt_hash[16]);
- struct passwd *(*unix_password_check)(char *username, char *pass, int pass_len);
-#endif
-};
/*
* Flags for local user manipulation.
@@ -771,6 +587,7 @@ struct passdb_ops {
#define LOCAL_ENABLE_USER 0x8
#define LOCAL_TRUST_ACCOUNT 0x10
#define LOCAL_SET_NO_PASSWORD 0x20
+#define LOCAL_SET_LDAP_ADMIN_PW 0x40
/* key and data in the connections database - used in smbstatus and smbd */
struct connections_key {
@@ -799,7 +616,10 @@ struct locking_key {
};
struct locking_data {
- int num_share_mode_entries;
+ union {
+ int num_share_mode_entries;
+ share_mode_entry dummy; /* Needed for alignment. */
+ } u;
/* the following two entries are implicit
share_mode_entry modes[num_share_mode_entries];
char file_name[];
@@ -1302,10 +1122,6 @@ struct bitmap {
#define SMB_SUCCESS 0 /* The request was successful. */
-#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */
-#define ERRSRV 0x02 /* Error is generated by the server network file manager.*/
-#define ERRHRD 0x03 /* Error is an hardware error. */
-#define ERRCMD 0xFF /* Command was not in the "SMB" format. */
#ifdef HAVE_STDARG_H
int slprintf(char *str, int n, char *format, ...)
@@ -1448,6 +1264,12 @@ enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
#endif /* DEVELOPER */
};
+/* LDAP schema types */
+enum schema_types {SCHEMA_COMPAT, SCHEMA_AD, SCHEMA_SAMBA};
+
+/* LDAP SSL options */
+enum ldap_ssl_types {LDAP_SSL_ON, LDAP_SSL_OFF, LDAP_SSL_START_TLS};
+
/* Remote architectures we know about. */
enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_SAMBA};
@@ -1761,4 +1583,12 @@ typedef struct user_struct
#include "nsswitch/winbindd_nss.h"
#include "smb_acls.h"
+/* Used by winbindd_glue functions */
+
+typedef struct {
+ struct cli_state *cli;
+ POLICY_HND handle;
+ TALLOC_CTX *mem_ctx;
+} CLI_POLICY_HND;
+
#endif /* _SMB_H */
diff --git a/source/include/smb_acls.h b/source/include/smb_acls.h
index bea90bf46a0..37aa7cb65c2 100644
--- a/source/include/smb_acls.h
+++ b/source/include/smb_acls.h
@@ -54,6 +54,36 @@
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
+#elif defined(HAVE_TRU64_ACLS)
+
+/* This is for DEC/Compaq Tru64 UNIX */
+
+#define SMB_ACL_TAG_T acl_tag_t
+#define SMB_ACL_TYPE_T acl_type_t
+#define SMB_ACL_PERMSET_T acl_permset_t
+#define SMB_ACL_PERM_T acl_perm_t
+#define SMB_ACL_READ ACL_READ
+#define SMB_ACL_WRITE ACL_WRITE
+#define SMB_ACL_EXECUTE ACL_EXECUTE
+
+/* Types of ACLs. */
+#define SMB_ACL_USER ACL_USER
+#define SMB_ACL_USER_OBJ ACL_USER_OBJ
+#define SMB_ACL_GROUP ACL_GROUP
+#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ
+#define SMB_ACL_OTHER ACL_OTHER
+#define SMB_ACL_MASK ACL_MASK
+
+#define SMB_ACL_T acl_t
+
+#define SMB_ACL_ENTRY_T acl_entry_t
+
+#define SMB_ACL_FIRST_ENTRY 0
+#define SMB_ACL_NEXT_ENTRY 1
+
+#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
+#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
+
#elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
/*
* Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index cad6229f1ae..6b554cb4795 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -37,11 +37,14 @@
#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
+/* free memory if the pointer is valid and zero the pointer */
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)
+
/* zero a structure */
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
/* zero a structure given a pointer to the structure */
-#define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); }
+#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0)
/* zero a structure given a pointer to the structure - no zero check */
#define ZERO_STRUCTPN(x) memset((char *)(x), 0, sizeof(*(x)))
@@ -53,6 +56,9 @@
/* pointer difference macro */
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2)))
+/* work out how many elements there are in a static array */
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
/* assert macros */
#define SMB_ASSERT(b) ((b)?(void)0: \
(DEBUG(0,("PANIC: assert failed at %s(%d)\n", \
@@ -75,8 +81,6 @@
return(ERROR(ERRDOS,ERRbadaccess))
#define CHECK_WRITE(fsp) if (!(fsp)->can_write) \
return(ERROR(ERRDOS,ERRbadaccess))
-#define CHECK_ERROR(fsp) if (HAS_CACHED_ERROR(fsp)) \
- return(CACHED_ERROR(fsp))
/* translates a connection number into a service number */
#define SNUM(conn) ((conn)?(conn)->service:-1)
@@ -134,22 +138,14 @@
#define SMB_LARGE_LKLEN_OFFSET_HIGH(indx) (12 + (20 * (indx)))
#define SMB_LARGE_LKLEN_OFFSET_LOW(indx) (16 + (20 * (indx)))
-/* Macro to cache an error in a write_bmpx_struct */
-#define CACHE_ERROR(w,c,e) ((w)->wr_errclass = (c), (w)->wr_error = (e), \
- w->wr_discard = True, -1)
-/* Macro to test if an error has been cached for this fnum */
-#define HAS_CACHED_ERROR(fsp) ((fsp)->wbmpx_ptr && \
- (fsp)->wbmpx_ptr->wr_discard)
-/* Macro to turn the cached error into an error packet */
-#define CACHED_ERROR(fsp) cached_error_packet(inbuf,outbuf,fsp,__LINE__)
-
/* these are the datagram types */
#define DGRAM_DIRECT_UNIQUE 0x10
-#define ERROR(class,x) error_packet(inbuf,outbuf,class,x,__LINE__)
+#define ERROR(class,x) error_packet(outbuf,0,class,x,__LINE__,__FILE__)
+#define ERROR_BOTH(nterr,class,x) error_packet(outbuf,nterr,class,x,__LINE__,__FILE__)
/* this is how errors are generated */
-#define UNIXERROR(defclass,deferror) unix_error_packet(inbuf,outbuf,defclass,deferror,__LINE__)
+#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,__LINE__,__FILE__)
#define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1))
diff --git a/source/include/trans2.h b/source/include/trans2.h
index bbe796b7425..3bf6203710e 100644
--- a/source/include/trans2.h
+++ b/source/include/trans2.h
@@ -259,6 +259,47 @@ Byte offset Type name description
#define TYPE_MOUNTED 0x20
#define TYPE_VIRTUAL 0x40
+/* NT passthrough levels... */
+
+#define SMB_FILE_DIRECTORY_INFORMATION 1001
+#define SMB_FILE_FULL_DIRECTORY_INFORMATION 1002
+#define SMB_FILE_BOTH_DIRECTORY_INFORMATION 1003
+#define SMB_FILE_BASIC_INFORMATION 1004
+#define SMB_FILE_STANDARD_INFORMATION 1005
+#define SMB_FILE_INTERNAL_INFORMATION 1006
+#define SMB_FILE_EA_INFORMATION 1007
+#define SMB_FILE_ACCESS_INFORMATION 1008
+#define SMB_FILE_NAME_INFORMATION 1009
+#define SMB_FILE_RENAME_INFORMATION 1010
+#define SMB_FILE_LINK_INFORMATION 1011
+#define SMB_FILE_NAMES_INFORMATION 1012
+#define SMB_FILE_DISPOSITION_INFORMATION 1013
+#define SMB_FILE_POSITION_INFORMATION 1014
+#define SMB_FILE_FULL_EA_INFORMATION 1015
+#define SMB_FILE_MODE_INFORMATION 1016
+#define SMB_FILE_ALIGNMENT_INFORMATION 1017
+#define SMB_FILE_ALL_INFORMATION 1018
+#define SMB_FILE_ALLOCATION_INFORMATION 1019
+#define SMB_FILE_END_OF_FILE_INFORMATION 1020
+#define SMB_FILE_ALTERNATE_NAME_INFORMATION 1021
+#define SMB_FILE_STREAM_INFORMATION 1022
+#define SMB_FILE_PIPE_INFORMATION 1023
+#define SMB_FILE_PIPE_LOCAL_INFORMATION 1024
+#define SMB_FILE_PIPE_REMOTE_INFORMATION 1025
+#define SMB_FILE_MAILSLOT_QUERY_INFORMATION 1026
+#define SMB_FILE_MAILSLOT_SET_INFORMATION 1027
+#define SMB_FILE_COMPRESSION_INFORMATION 1028
+#define SMB_FILE_OBJECTID_INFORMATION 1029
+#define SMB_FILE_COMPLETION_INFORMATION 1030
+#define SMB_FILE_MOVE_CLUSTER_INFORMATION 1031
+#define SMB_FILE_QUOTA_INFORMATION 1032
+#define SMB_FILE_REPARSEPOINT_INFORMATION 1033
+#define SMB_FILE_NETWORK_OPEN_INFORMATION 1034
+#define SMB_FILE_ATTRIBUTE_TAG_INFORMATION 1035
+#define SMB_FILE_TRACKING_INFORMATION 1036
+#define SMB_FILE_MAXIMUM_INFORMATION 1037
+
+
#endif
diff --git a/source/include/version.h b/source/include/version.h
index f8687c33466..d37a960b4ad 100644
--- a/source/include/version.h
+++ b/source/include/version.h
@@ -1 +1 @@
-#define VERSION "2.2.1a"
+#define VERSION "2.2.2-pre"
diff --git a/source/include/vfs.h b/source/include/vfs.h
index 93823a5f239..7d61e6f1062 100644
--- a/source/include/vfs.h
+++ b/source/include/vfs.h
@@ -68,8 +68,8 @@ struct vfs_ops {
int (*open)(struct connection_struct *conn, char *fname, int flags, mode_t mode);
int (*close)(struct files_struct *fsp, int fd);
- ssize_t (*read)(struct files_struct *fsp, int fd, char *data, size_t n);
- ssize_t (*write)(struct files_struct *fsp, int fd, char *data, size_t n);
+ ssize_t (*read)(struct files_struct *fsp, int fd, void *data, size_t n);
+ ssize_t (*write)(struct files_struct *fsp, int fd, const void *data, size_t n);
SMB_OFF_T (*lseek)(struct files_struct *fsp, int filedes, SMB_OFF_T offset, int whence);
int (*rename)(struct connection_struct *conn, char *old, char *new);
int (*fsync)(struct files_struct *fsp, int fd);
diff --git a/source/lib/debug.c b/source/lib/debug.c
index 4ec70bd118a..982d59acc10 100644
--- a/source/lib/debug.c
+++ b/source/lib/debug.c
@@ -310,11 +310,20 @@ BOOL reopen_logs( void )
FILE *new_dbf = NULL;
BOOL ret = True;
+ if (stdout_logging)
+ return True;
+
oldumask = umask( 022 );
pstrcpy(fname, debugf );
- if (lp_loaded() && (*lp_logfile()))
- pstrcpy(fname, lp_logfile());
+
+ if (lp_loaded()) {
+ char *logfname;
+
+ logfname = lp_logfile();
+ if (*logfname)
+ pstrcpy(fname, logfname);
+ }
pstrcpy(debugf, fname);
diff --git a/source/lib/genrand.c b/source/lib/genrand.c
index 7af44118ae5..e5912601182 100644
--- a/source/lib/genrand.c
+++ b/source/lib/genrand.c
@@ -158,7 +158,11 @@ static int do_reseed(BOOL use_fd, int fd)
/* Add in some secret file contents */
do_filehash("/etc/shadow", &seed_inbuf[0]);
+#ifdef WITH_TDB_SAM
+ do_filehash(lp_tdb_passwd_file(), &seed_inbuf[16]);
+#else
do_filehash(lp_smb_passwd_file(), &seed_inbuf[16]);
+#endif
/*
* Add in the root encrypted password.
diff --git a/source/lib/hash.c b/source/lib/hash.c
index 92840a4c983..3abdc2ef11b 100644
--- a/source/lib/hash.c
+++ b/source/lib/hash.c
@@ -30,10 +30,8 @@
extern int DEBUGLEVEL;
-#define NUM_PRIMES 11
-
static BOOL enlarge_hash_table(hash_table *table);
-static int primes[NUM_PRIMES] =
+static int primes[] =
{17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 16411};
/****************************************************************************
@@ -62,7 +60,7 @@ BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compar
table->comp_func = compare_func;
while (table->size < num_buckets)
table->size <<= 1;
- for (i = 0; i < NUM_PRIMES; i++) {
+ for (i = 0; i < ARRAY_SIZE(primes); i++) {
if (primes[i] > table->size) {
table->size = primes[i];
break;
@@ -94,12 +92,16 @@ BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compar
static int string_hash(int hash_size, const char *key)
{
- int j=0;
- while (*key)
- j = j*10 + *key++;
- return(((j>=0)?j:(-j)) % hash_size);
+ u32 value; /* Used to compute the hash value. */
+ u32 i; /* Used to cycle through random values. */
+
+ for (value = 0x238F13AF, i=0; key[i]; i++)
+ value = (value + (key[i] << (i*5 % 24)));
+
+ return (1103515243 * value + 12345) % hash_size;
}
+
/* *************************************************************************
* Search the hash table for the entry in the hash chain.
* The function returns the pointer to the
@@ -192,8 +194,8 @@ hash_element *hash_insert(hash_table *table, char *value, char *key)
bucket = hash_elem->bucket;
ubi_dlRemThis(&(table->lru_chain), &(hash_elem->lru_link.lru_link));
ubi_dlRemThis(bucket, (ubi_dlNodePtr)hash_elem);
- free((char*)(hash_elem->value));
- free(hash_elem);
+ SAFE_FREE(hash_elem->value);
+ SAFE_FREE(hash_elem);
} else {
table->num_elements += 1;
}
@@ -238,10 +240,8 @@ void hash_remove(hash_table *table, hash_element *hash_elem)
if (hash_elem) {
ubi_dlRemove(&(table->lru_chain), &(hash_elem->lru_link.lru_link));
ubi_dlRemove(hash_elem->bucket, (ubi_dlNodePtr) hash_elem);
- if(hash_elem->value)
- free((char *)(hash_elem->value));
- if(hash_elem)
- free((char *) hash_elem);
+ SAFE_FREE(hash_elem->value);
+ SAFE_FREE(hash_elem);
table->num_elements--;
}
}
@@ -285,8 +285,7 @@ static BOOL enlarge_hash_table(hash_table *table)
table->num_elements++;
}
}
- if(buckets)
- free((char *) buckets);
+ SAFE_FREE(buckets);
return True;
}
@@ -309,14 +308,11 @@ void hash_clear(hash_table *table)
for (i = 0; i < table->size; bucket++, i++) {
while (bucket->count != 0) {
hash_elem = (hash_element *) ubi_dlRemHead(bucket);
- if(hash_elem->value)
- free((char *)(hash_elem->value));
- if(hash_elem)
- free((char *)hash_elem);
+ SAFE_FREE(hash_elem->value);
+ SAFE_FREE(hash_elem);
}
}
table->size = 0;
- if(table->buckets)
- free((char *) table->buckets);
+ SAFE_FREE(table->buckets);
table->buckets = NULL;
}
diff --git a/source/lib/messages.c b/source/lib/messages.c
index ffa873960e7..f7a5be4c2cc 100644
--- a/source/lib/messages.c
+++ b/source/lib/messages.c
@@ -90,7 +90,7 @@ BOOL message_init(void)
if (tdb) return True;
tdb = tdb_open_log(lock_path("messages.tdb"),
- 0, TDB_CLEAR_IF_FIRST,
+ 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
O_RDWR|O_CREAT,0600);
if (!tdb) {
@@ -299,11 +299,15 @@ void message_dispatch(void)
struct dispatch_fns *dfn;
if (!received_signal) return;
+
+ DEBUG(10,("message_dispatch: received_signal = %d\n", received_signal));
+
received_signal = 0;
while (message_recv(&msg_type, &src, &buf, &len)) {
for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
if (dfn->msg_type == msg_type) {
+ DEBUG(10,("message_dispatch: processing message of type %d.\n", msg_type));
dfn->fn(msg_type, src, buf, len);
}
}
@@ -322,12 +326,19 @@ void message_register(int msg_type,
dfn = (struct dispatch_fns *)malloc(sizeof(*dfn));
- ZERO_STRUCTP(dfn);
+ if (dfn != NULL) {
+
+ ZERO_STRUCTPN(dfn);
- dfn->msg_type = msg_type;
- dfn->fn = fn;
+ dfn->msg_type = msg_type;
+ dfn->fn = fn;
- DLIST_ADD(dispatch_fns, dfn);
+ DLIST_ADD(dispatch_fns, dfn);
+ }
+ else {
+
+ DEBUG(0,("message_register: Not enough memory. malloc failed!\n"));
+ }
}
/****************************************************************************
diff --git a/source/lib/pidfile.c b/source/lib/pidfile.c
index 25ff85483d0..a26aa12a3c1 100644
--- a/source/lib/pidfile.c
+++ b/source/lib/pidfile.c
@@ -41,7 +41,7 @@ pid_t pidfile_pid(char *name)
slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
- fd = sys_open(pidFile, O_NONBLOCK | O_RDWR, 0644);
+ fd = sys_open(pidFile, O_NONBLOCK | O_RDONLY, 0644);
if (fd == -1) {
return 0;
}
@@ -49,24 +49,24 @@ pid_t pidfile_pid(char *name)
ZERO_ARRAY(pidstr);
if (read(fd, pidstr, sizeof(pidstr)-1) <= 0) {
- goto ok;
+ goto noproc;
}
ret = atoi(pidstr);
if (!process_exists((pid_t)ret)) {
- goto ok;
+ goto noproc;
}
- if (fcntl_lock(fd,SMB_F_SETLK,0,1,F_WRLCK)) {
+ if (fcntl_lock(fd,SMB_F_SETLK,0,1,F_RDLCK)) {
/* we could get the lock - it can't be a Samba process */
- goto ok;
+ goto noproc;
}
close(fd);
return (pid_t)ret;
- ok:
+ noproc:
close(fd);
unlink(pidFile);
return 0;
diff --git a/source/lib/readline.c b/source/lib/readline.c
index 75a38c68521..a1cdbe15872 100644
--- a/source/lib/readline.c
+++ b/source/lib/readline.c
@@ -22,24 +22,6 @@
#include "includes.h"
-#ifdef HAVE_LIBREADLINE
-# ifdef HAVE_READLINE_READLINE_H
-# include <readline/readline.h>
-# ifdef HAVE_READLINE_HISTORY_H
-# include <readline/history.h>
-# endif
-# else
-# ifdef HAVE_READLINE_H
-# include <readline.h>
-# ifdef HAVE_HISTORY_H
-# include <history.h>
-# endif
-# else
-# undef HAVE_LIBREADLINE
-# endif
-# endif
-#endif
-
/****************************************************************************
display the prompt and wait for input. Call callback() regularly
****************************************************************************/
diff --git a/source/lib/sysacls.c b/source/lib/sysacls.c
index 0770a8856a2..0f488888a8f 100644
--- a/source/lib/sysacls.c
+++ b/source/lib/sysacls.c
@@ -64,7 +64,7 @@ extern int DEBUGLEVEL;
int sys_acl_free_text(char *text) - free acl_to_text
int sys_acl_free_acl(SMB_ACL_T posix_acl)
- int sys_acl_free_qualifier(SMB_ACL_T posix_acl)
+ int sys_acl_free_qualifier(void *qualifier, SMB_ACL_TAG_T tagtype)
*/
@@ -186,11 +186,167 @@ int sys_acl_free_acl(SMB_ACL_T the_acl)
return acl_free(the_acl);
}
-int sys_acl_free_qualifier(void *qual)
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
{
return acl_free(qual);
}
+#elif defined(HAVE_TRU64_ACLS)
+/*
+ * The interface to DEC/Compaq Tru64 UNIX ACLs
+ * is based on Draft 13 of the POSIX spec which is
+ * slightly different from the Draft 16 interface.
+ *
+ * Also, some of the permset manipulation functions
+ * such as acl_clear_perm() and acl_add_perm() appear
+ * to be broken on Tru64 so we have to manipulate
+ * the permission bits in the permset directly.
+ */
+int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
+{
+ SMB_ACL_ENTRY_T entry;
+
+ if (entry_id == SMB_ACL_FIRST_ENTRY && acl_first_entry(the_acl) != 0) {
+ return -1;
+ }
+
+ errno = 0;
+ if ((entry = acl_get_entry(the_acl)) != NULL) {
+ *entry_p = entry;
+ return 1;
+ }
+
+ return errno ? -1 : 0;
+}
+
+int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
+{
+ return acl_get_tag_type( entry_d, tag_type_p);
+}
+
+int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
+{
+ return acl_get_permset( entry_d, permset_p);
+}
+
+void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d)
+{
+ return acl_get_qualifier( entry_d);
+}
+
+SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type)
+{
+ return acl_get_file((char *)path_p, type);
+}
+
+SMB_ACL_T sys_acl_get_fd(int fd)
+{
+ return acl_get_fd(fd, ACL_TYPE_ACCESS);
+}
+
+int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset)
+{
+ *permset = 0; /* acl_clear_perm() is broken on Tru64 */
+
+ return 0;
+}
+
+int sys_acl_add_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+ if (perm & ~(SMB_ACL_READ | SMB_ACL_WRITE | SMB_ACL_EXECUTE)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ *permset |= perm; /* acl_add_perm() is broken on Tru64 */
+
+ return 0;
+}
+
+int sys_acl_get_perm( SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+ return *permset & perm; /* Tru64 doesn't have acl_get_perm() */
+}
+
+char *sys_acl_to_text( SMB_ACL_T the_acl, ssize_t *plen)
+{
+ return acl_to_text( the_acl, plen);
+}
+
+SMB_ACL_T sys_acl_init( int count)
+{
+ return acl_init(count);
+}
+
+int sys_acl_create_entry( SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
+{
+ SMB_ACL_ENTRY_T entry;
+
+ if ((entry = acl_create_entry(pacl)) == NULL) {
+ return -1;
+ }
+
+ *pentry = entry;
+ return 0;
+}
+
+int sys_acl_set_tag_type( SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
+{
+ return acl_set_tag_type(entry, tagtype);
+}
+
+int sys_acl_set_qualifier( SMB_ACL_ENTRY_T entry, void *qual)
+{
+ return acl_set_qualifier(entry, qual);
+}
+
+int sys_acl_set_permset( SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
+{
+ return acl_set_permset(entry, permset);
+}
+
+int sys_acl_valid( SMB_ACL_T theacl )
+{
+ acl_entry_t entry;
+
+ return acl_valid(theacl, &entry);
+}
+
+int sys_acl_set_file( const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+{
+ return acl_set_file((char *)name, acltype, theacl);
+}
+
+int sys_acl_set_fd( int fd, SMB_ACL_T theacl)
+{
+ return acl_set_fd(fd, ACL_TYPE_ACCESS, theacl);
+}
+
+int sys_acl_delete_def_file(const char *name)
+{
+ return acl_delete_def_file((char *)name);
+}
+
+int sys_acl_free_text(char *text)
+{
+ /*
+ * (void) cast and explicit return 0 are for DEC UNIX
+ * which just #defines acl_free_text() to be free()
+ */
+ (void) acl_free_text(text);
+ return 0;
+}
+
+int sys_acl_free_acl(SMB_ACL_T the_acl)
+{
+ return acl_free(the_acl);
+}
+
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
+{
+ return acl_free_qualifier(qual, tagtype);
+}
+
#elif defined(HAVE_UNIXWARE_ACLS) || defined(HAVE_SOLARIS_ACLS)
/*
@@ -543,7 +699,7 @@ char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
maxlen += nbytes + 20 * (acl_d->count - i);
- if ((text = realloc(oldtext, maxlen)) == NULL) {
+ if ((text = Realloc(oldtext, maxlen)) == NULL) {
free(oldtext);
errno = ENOMEM;
return NULL;
@@ -820,7 +976,7 @@ int sys_acl_free_acl(SMB_ACL_T acl_d)
return 0;
}
-int sys_acl_free_qualifier(void *qual)
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
{
return 0;
}
@@ -1075,7 +1231,7 @@ int sys_acl_free_acl(SMB_ACL_T acl_d)
return 0;
}
-int sys_acl_free_qualifier(void *qual)
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
{
return 0;
}
@@ -1960,7 +2116,7 @@ int sys_acl_free_acl(SMB_ACL_T posix_acl)
return(0);
}
-int sys_acl_free_qualifier(void *qual)
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
{
return(0);
}
@@ -2093,7 +2249,7 @@ int sys_acl_free_acl(SMB_ACL_T the_acl)
return -1;
}
-int sys_acl_free_qualifier(void *qual)
+int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
{
errno = ENOSYS;
return -1;
diff --git a/source/lib/talloc.c b/source/lib/talloc.c
index a8ee481744b..cfd130e888b 100644
--- a/source/lib/talloc.c
+++ b/source/lib/talloc.c
@@ -90,7 +90,7 @@ void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
for (tc=t->list; tc; tc=tc->next) {
if (tc->ptr == ptr) {
- ptr = realloc(ptr, size);
+ ptr = Realloc(ptr, size);
if (ptr) {
t->total_alloc_size += (size - tc->size);
tc->size = size;
diff --git a/source/lib/time.c b/source/lib/time.c
index 9714d4b9f8e..bf58cdd018a 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -44,7 +44,19 @@ extern int DEBUGLEVEL;
#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
#endif
+/*******************************************************************
+ External access to time_t_min and time_t_max.
+********************************************************************/
+time_t get_time_t_min(void)
+{
+ return TIME_T_MIN;
+}
+
+time_t get_time_t_max(void)
+{
+ return TIME_T_MAX;
+}
/*******************************************************************
a gettimeofday wrapper
@@ -121,7 +133,7 @@ Updated by Paul Eggert <eggert@twinsun.com>
********************************************************************/
static int TimeZoneFaster(time_t t)
{
- static struct dst_table {time_t start,end; int zone;} *dst_table = NULL;
+ static struct dst_table {time_t start,end; int zone;} *tdt, *dst_table = NULL;
static int table_size = 0;
int i;
int zone = 0;
@@ -141,13 +153,18 @@ static int TimeZoneFaster(time_t t)
time_t low,high;
zone = TimeZone(t);
- dst_table = (struct dst_table *)Realloc(dst_table,
+ tdt = (struct dst_table *)Realloc(dst_table,
sizeof(dst_table[0])*(i+1));
- if (!dst_table) {
+ if (!tdt) {
+ DEBUG(0,("TimeZoneFaster: out of memory!\n"));
+ if (dst_table)
+ free(dst_table);
table_size = 0;
} else {
- table_size++;
+ dst_table = tdt;
+ table_size++;
+
dst_table[i].zone = zone;
dst_table[i].start = dst_table[i].end = t;
@@ -304,6 +321,12 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
nt->high = 0;
return;
}
+ if (t == TIME_T_MAX)
+ {
+ nt->low = 0xffffffff;
+ nt->high = 0x7fffffff;
+ return;
+ }
if (t == -1)
{
nt->low = 0xffffffff;
diff --git a/source/lib/username.c b/source/lib/username.c
index e465cfbf226..5cd57e0ae50 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -262,7 +262,7 @@ static BOOL user_in_netgroup_list(char *user,char *ngname)
user, mydomain, ngname));
DEBUG(5,("innetgr is %s\n",
innetgr(ngname, NULL, user, mydomain)
- ? "TRUE" : "FALSE"));
+ ? "True" : "False"));
if (innetgr(ngname, NULL, user, mydomain))
return (True);
diff --git a/source/lib/util.c b/source/lib/util.c
index 453bccdd361..26ca621fde2 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -3,6 +3,7 @@
Version 1.9.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001
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
@@ -52,7 +53,7 @@
#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
#ifdef WITH_SSL
-#include <ssl.h>
+#include <openssl/ssl.h>
#undef Realloc /* SSLeay defines this and samba has a function of this name */
extern SSL *ssl;
extern int sslFd;
@@ -92,27 +93,28 @@ char **my_netbios_names;
/****************************************************************************
- find a suitable temporary directory. The result should be copied immediately
- as it may be overwritten by a subsequent call
- ****************************************************************************/
+ Find a suitable temporary directory. The result should be copied immediately
+ as it may be overwritten by a subsequent call.
+****************************************************************************/
+
char *tmpdir(void)
{
- char *p;
- if ((p = getenv("TMPDIR"))) {
- return p;
- }
- return "/tmp";
+ char *p;
+ if ((p = getenv("TMPDIR")))
+ return p;
+ return "/tmp";
}
/****************************************************************************
-determine whether we are in the specified group
+ Determine whether we are in the specified group.
****************************************************************************/
BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
{
int i;
- if (group == current_gid) return(True);
+ if (group == current_gid)
+ return(True);
for (i=0;i<ngroups;i++)
if (group == groups[i])
@@ -121,14 +123,13 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
return(False);
}
-
/****************************************************************************
-like atoi but gets the value up to the separater character
+ Like atoi but gets the value up to the separater character.
****************************************************************************/
+
char *Atoic(char *p, int *n, char *c)
{
- if (!isdigit((int)*p))
- {
+ if (!isdigit((int)*p)) {
DEBUG(5, ("Atoic: malformed number\n"));
return NULL;
}
@@ -136,12 +137,9 @@ char *Atoic(char *p, int *n, char *c)
(*n) = atoi(p);
while ((*p) && isdigit((int)*p))
- {
p++;
- }
- if (strchr(c, *p) == NULL)
- {
+ if (strchr(c, *p) == NULL) {
DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
return NULL;
}
@@ -150,27 +148,29 @@ char *Atoic(char *p, int *n, char *c)
}
/*************************************************************************
- reads a list of numbers
+ Reads a list of numbers.
*************************************************************************/
+
char *get_numlist(char *p, uint32 **num, int *count)
{
int val;
if (num == NULL || count == NULL)
- {
return NULL;
- }
(*count) = 0;
(*num ) = NULL;
- while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':')
- {
- (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32));
- if ((*num) == NULL)
- {
+ while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
+ uint32 *tn;
+
+ tn = Realloc((*num), ((*count)+1) * sizeof(uint32));
+ if (tn == NULL) {
+ if (*num)
+ free(*num);
return NULL;
- }
+ } else
+ (*num) = tn;
(*num)[(*count)] = val;
(*count)++;
p++;
@@ -179,52 +179,40 @@ char *get_numlist(char *p, uint32 **num, int *count)
return p;
}
-
/*******************************************************************
- check if a file exists - call vfs_file_exist for samba files
+ Check if a file exists - call vfs_file_exist for samba files.
********************************************************************/
+
BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
{
- SMB_STRUCT_STAT st;
- if (!sbuf) sbuf = &st;
+ SMB_STRUCT_STAT st;
+ if (!sbuf)
+ sbuf = &st;
- if (sys_stat(fname,sbuf) != 0)
- return(False);
+ if (sys_stat(fname,sbuf) != 0)
+ return(False);
- return(S_ISREG(sbuf->st_mode));
+ return(S_ISREG(sbuf->st_mode));
}
/*******************************************************************
- rename a unix file
+ Check a files mod time.
********************************************************************/
-int file_rename(char *from, char *to)
-{
- int rcode = rename (from, to);
-
- if (errno == EXDEV)
- {
- /* Rename across filesystems needed. */
- rcode = copy_reg (from, to);
- }
- return rcode;
-}
-/*******************************************************************
-check a files mod time
-********************************************************************/
time_t file_modtime(char *fname)
{
- SMB_STRUCT_STAT st;
+ SMB_STRUCT_STAT st;
- if (sys_stat(fname,&st) != 0)
- return(0);
+ if (sys_stat(fname,&st) != 0)
+ return(0);
- return(st.st_mtime);
+ return(st.st_mtime);
}
/*******************************************************************
- check if a directory exists
+ Check if a directory exists.
********************************************************************/
+
BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
{
SMB_STRUCT_STAT st2;
@@ -522,111 +510,85 @@ int set_blocking(int fd, BOOL set)
}
/****************************************************************************
-transfer some data between two fd's
+ Transfer some data between two fd's.
****************************************************************************/
-SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
-{
- static char *buf=NULL;
- static int size=0;
- char *buf1,*abuf;
- SMB_OFF_T total = 0;
-
- DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
-
- if (size == 0) {
- size = lp_readsize();
- size = MAX(size,1024);
- }
-
- while (!buf && size>0) {
- buf = (char *)Realloc(buf,size+8);
- if (!buf) size /= 2;
- }
-
- if (!buf) {
- DEBUG(0,("Can't allocate transfer buffer!\n"));
- exit(1);
- }
-
- abuf = buf + (align%8);
- if (header)
- n += headlen;
-
- while (n > 0)
- {
- int s = (int)MIN(n,(SMB_OFF_T)size);
- int ret,ret2=0;
+ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
+ ssize_t (*write_fn)(int, const void *, size_t))
+{
+ static char buf[16384];
+ size_t total = 0;
+ ssize_t read_ret;
+ size_t write_total = 0;
+ ssize_t write_ret;
- ret = 0;
+ while (total < n) {
+ size_t num_to_read_thistime = MIN((n - total), sizeof(buf));
- if (header && (headlen >= MIN(s,1024))) {
- buf1 = header;
- s = headlen;
- ret = headlen;
- headlen = 0;
- header = NULL;
- } else {
- buf1 = abuf;
- }
+ read_ret = (*read_fn)(infd, buf + total, num_to_read_thistime);
+ if (read_ret == -1) {
+ DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
+ return -1;
+ }
+ if (read_ret == 0)
+ break;
- if (header && headlen > 0)
- {
- ret = MIN(headlen,size);
- memcpy(buf1,header,ret);
- headlen -= ret;
- header += ret;
- if (headlen <= 0) header = NULL;
- }
+ write_total = 0;
+
+ while (write_total < read_ret) {
+ write_ret = (*write_fn)(outfd,buf + total, read_ret);
+
+ if (write_ret == -1) {
+ DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
+ return -1;
+ }
+ if (write_ret == 0)
+ return (ssize_t)total;
+
+ write_total += (size_t)write_ret;
+ }
- if (s > ret)
- ret += read(infd,buf1+ret,s-ret);
+ total += (size_t)read_ret;
+ }
- if (ret > 0)
- {
- ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
- if (ret2 > 0) total += ret2;
- /* if we can't write then dump excess data */
- if (ret2 != ret)
- transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
- }
- if (ret <= 0 || ret2 != ret)
- return(total);
- n -= ret;
- }
- return(total);
+ return (ssize_t)total;
}
+SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
+{
+ return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, read, write);
+}
/*******************************************************************
-sleep for a specified number of milliseconds
+ Sleep for a specified number of milliseconds.
********************************************************************/
+
void msleep(int t)
{
- int tdiff=0;
- struct timeval tval,t1,t2;
- fd_set fds;
+ int tdiff=0;
+ struct timeval tval,t1,t2;
+ fd_set fds;
- GetTimeOfDay(&t1);
- GetTimeOfDay(&t2);
+ GetTimeOfDay(&t1);
+ GetTimeOfDay(&t2);
- while (tdiff < t) {
- tval.tv_sec = (t-tdiff)/1000;
- tval.tv_usec = 1000*((t-tdiff)%1000);
+ while (tdiff < t) {
+ tval.tv_sec = (t-tdiff)/1000;
+ tval.tv_usec = 1000*((t-tdiff)%1000);
- FD_ZERO(&fds);
- errno = 0;
- sys_select_intr(0,&fds,&tval);
+ FD_ZERO(&fds);
+ errno = 0;
+ sys_select_intr(0,&fds,&tval);
- GetTimeOfDay(&t2);
- tdiff = TvalDiff(&t1,&t2);
- }
+ GetTimeOfDay(&t2);
+ tdiff = TvalDiff(&t1,&t2);
+ }
}
-
/****************************************************************************
-become a daemon, discarding the controlling terminal
+ Become a daemon, discarding the controlling terminal.
****************************************************************************/
+
void become_daemon(void)
{
if (sys_fork()) {
@@ -650,74 +612,64 @@ void become_daemon(void)
close_low_fds();
}
-
/****************************************************************************
-put up a yes/no prompt
+ Put up a yes/no prompt
****************************************************************************/
+
BOOL yesno(char *p)
{
- pstring ans;
- printf("%s",p);
+ pstring ans;
+ printf("%s",p);
- if (!fgets(ans,sizeof(ans)-1,stdin))
- return(False);
+ if (!fgets(ans,sizeof(ans)-1,stdin))
+ return(False);
- if (*ans == 'y' || *ans == 'Y')
- return(True);
+ if (*ans == 'y' || *ans == 'Y')
+ return(True);
- return(False);
+ return(False);
}
-#ifdef HPUX
/****************************************************************************
-this is a version of setbuffer() for those machines that only have setvbuf
+ Expand a pointer to be a particular size.
****************************************************************************/
- void setbuffer(FILE *f,char *buf,int bufsize)
-{
- setvbuf(f,buf,_IOFBF,bufsize);
-}
-#endif
-/****************************************************************************
-expand a pointer to be a particular size
-****************************************************************************/
void *Realloc(void *p,size_t size)
{
- void *ret=NULL;
+ void *ret=NULL;
- if (size == 0) {
- if (p) free(p);
- DEBUG(5,("Realloc asked for 0 bytes\n"));
- return NULL;
- }
+ if (size == 0) {
+ if (p)
+ free(p);
+ DEBUG(5,("Realloc asked for 0 bytes\n"));
+ return NULL;
+ }
- if (!p)
- ret = (void *)malloc(size);
- else
- ret = (void *)realloc(p,size);
+ if (!p)
+ ret = (void *)malloc(size);
+ else
+ ret = (void *)realloc(p,size);
- if (!ret)
- DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
+ if (!ret)
+ DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
- return(ret);
+ return(ret);
}
-
/****************************************************************************
-free memory, checks for NULL
+ Free memory, checks for NULL.
****************************************************************************/
+
void safe_free(void *p)
{
if (p != NULL)
- {
free(p);
- }
}
-
/****************************************************************************
-get my own name and IP
+ Get my own name and IP.
****************************************************************************/
+
BOOL get_myname(char *my_name)
{
pstring hostname;
@@ -736,7 +688,8 @@ BOOL get_myname(char *my_name)
if (my_name) {
/* split off any parts after an initial . */
char *p = strchr(hostname,'.');
- if (p) *p = 0;
+ if (p)
+ *p = 0;
fstrcpy(my_name,hostname);
}
@@ -745,8 +698,9 @@ BOOL get_myname(char *my_name)
}
/****************************************************************************
-interpret a protocol description string, with a default
+ Interpret a protocol description string, with a default.
****************************************************************************/
+
int interpret_protocol(char *str,int def)
{
if (strequal(str,"NT1"))
@@ -1808,7 +1762,131 @@ BOOL mask_match(char *string, char *pattern, BOOL is_case_sensitive)
return ms_fnmatch(p2, s2) == 0;
}
+/*********************************************************
+ Recursive routine that is called by unix_wild_match.
+*********************************************************/
+
+static BOOL unix_do_match(char *regexp, char *str)
+{
+ char *p;
+
+ for( p = regexp; *p && *str; ) {
+
+ switch(*p) {
+ case '?':
+ str++;
+ p++;
+ break;
+
+ case '*':
+
+ /*
+ * Look for a character matching
+ * the one after the '*'.
+ */
+ p++;
+ if(!*p)
+ return True; /* Automatic match */
+ while(*str) {
+
+ while(*str && (*p != *str))
+ str++;
+
+ /*
+ * Patch from weidel@multichart.de. In the case of the regexp
+ * '*XX*' we want to ensure there are at least 2 'X' characters
+ * in the string after the '*' for a match to be made.
+ */
+
+ {
+ int matchcount=0;
+
+ /*
+ * Eat all the characters that match, but count how many there were.
+ */
+
+ while(*str && (*p == *str)) {
+ str++;
+ matchcount++;
+ }
+
+ /*
+ * Now check that if the regexp had n identical characters that
+ * matchcount had at least that many matches.
+ */
+
+ while ( *(p+1) && (*(p+1) == *p)) {
+ p++;
+ matchcount--;
+ }
+
+ if ( matchcount <= 0 )
+ return False;
+ }
+
+ str--; /* We've eaten the match char after the '*' */
+
+ if(unix_do_match(p, str))
+ return True;
+
+ if(!*str)
+ return False;
+ else
+ str++;
+ }
+ return False;
+
+ default:
+ if(*str != *p)
+ return False;
+ str++;
+ p++;
+ break;
+ }
+ }
+
+ if(!*p && !*str)
+ return True;
+ if (!*p && str[0] == '.' && str[1] == 0)
+ return(True);
+
+ if (!*str && *p == '?') {
+ while (*p == '?')
+ p++;
+ return(!*p);
+ }
+
+ if(!*str && (*p == '*' && p[1] == '\0'))
+ return True;
+
+ return False;
+}
+
+/*******************************************************************
+ Simple case insensitive interface to a UNIX wildcard matcher.
+*******************************************************************/
+
+BOOL unix_wild_match(char *pattern, char *string)
+{
+ pstring p2, s2;
+ char *p;
+
+ pstrcpy(p2, pattern);
+ pstrcpy(s2, string);
+ strlower(p2);
+ strlower(s2);
+
+ /* Remove any *? and ** from the pattern as they are meaningless */
+ for(p = p2; *p; p++)
+ while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
+ pstrcpy( &p[1], &p[2]);
+
+ if (strequal(p2,"*"))
+ return True;
+
+ return unix_do_match(p2, s2) == 0;
+}
#ifdef __INSURE__
diff --git a/source/lib/util_array.c b/source/lib/util_array.c
index 567c170834a..dcb2a6b5f08 100644
--- a/source/lib/util_array.c
+++ b/source/lib/util_array.c
@@ -58,18 +58,20 @@ void* add_copy_to_array(uint32 *len, void ***array, const void *item,
void* add_item_to_array(uint32 *len, void ***array, void *item)
{
+ void **tary;
+
if (len == NULL || array == NULL)
- {
return NULL;
- }
- (*array) = (void**)Realloc((*array), ((*len)+1)*sizeof((*array)[0]));
-
- if ((*array) != NULL)
- {
+ tary = (void**)Realloc((*array), ((*len)+1)*sizeof((*array)[0]));
+
+ if (tary != NULL) {
+ (*array) = tary;
(*array)[(*len)] = item;
(*len)++;
return item;
+ } else {
+ free((char *)*array);
}
return NULL;
}
diff --git a/source/lib/util_file.c b/source/lib/util_file.c
index 4e2adc97bcc..f3d8afde5d4 100644
--- a/source/lib/util_file.c
+++ b/source/lib/util_file.c
@@ -282,13 +282,25 @@ char *fgets_slash(char *s2,int maxlen,FILE *f)
if (feof(f))
return(NULL);
+ if (maxlen <2) return(NULL);
+
if (!s2)
{
+ char *t;
+
maxlen = MIN(maxlen,8);
- s = (char *)Realloc(s,maxlen);
+ t = (char *)Realloc(s,maxlen);
+ if (!t) {
+ DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
+ if (s)
+ free(s);
+ return(NULL);
+ } else
+ s = t;
}
- if (!s || maxlen < 2) return(NULL);
+ if (!s)
+ return(NULL);
*s = 0;
@@ -323,12 +335,19 @@ char *fgets_slash(char *s2,int maxlen,FILE *f)
s[len++] = c;
s[len] = 0;
}
- if (!s2 && len > maxlen-3)
- {
- maxlen *= 2;
- s = (char *)Realloc(s,maxlen);
- if (!s) return(NULL);
- }
+ if (!s2 && len > maxlen-3) {
+ char *t;
+
+ maxlen *= 2;
+ t = (char *)Realloc(s,maxlen);
+ if (!t) {
+ DEBUG(0,("fgets_slash: failed to expand buffer!\n"));
+ if (s)
+ free(s);
+ return(NULL);
+ } else
+ s = t;
+ }
}
return(s);
}
@@ -340,7 +359,7 @@ load from a pipe into memory
char *file_pload(char *syscmd, size_t *size)
{
int fd, n;
- char *p;
+ char *p, *tp;
pstring buf;
size_t total;
@@ -351,11 +370,15 @@ char *file_pload(char *syscmd, size_t *size)
total = 0;
while ((n = read(fd, buf, sizeof(buf))) > 0) {
- p = Realloc(p, total + n + 1);
- if (!p) {
+ tp = Realloc(p, total + n + 1);
+ if (!tp) {
+ DEBUG(0,("file_pload: failed to exand buffer!\n"));
close(fd);
+ if (p)
+ free(p);
return NULL;
- }
+ } else
+ p = tp;
memcpy(p+total, buf, n);
total += n;
}
diff --git a/source/lib/util_list.c b/source/lib/util_list.c
index 19354c87843..0175a7c8a16 100644
--- a/source/lib/util_list.c
+++ b/source/lib/util_list.c
@@ -230,7 +230,7 @@ BOOL compare_rpc_hnd_node(const RPC_HND_NODE *x,
{
/* only compare valid nodes */
if (x==NULL || y==NULL)
- return FALSE;
+ return False;
/* if the POLICY_HND field(s) are ever changed, this
will need to be updated. Probably should be a set of
diff --git a/source/lib/util_seaccess.c b/source/lib/util_seaccess.c
index 8b75a5f4876..860988aad57 100644
--- a/source/lib/util_seaccess.c
+++ b/source/lib/util_seaccess.c
@@ -30,7 +30,7 @@ extern int DEBUGLEVEL;
Check if this ACE has a SID in common with the token.
**********************************************************************************/
-static BOOL token_sid_in_ace( NT_USER_TOKEN *token, SEC_ACE *ace)
+static BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
{
size_t i;
@@ -154,7 +154,7 @@ static BOOL get_max_access( SEC_ACL *the_acl, NT_USER_TOKEN *token, uint32 *gran
*/
*granted = acc_granted;
- *status = NT_STATUS_NOPROBLEMO;
+ *status = NT_STATUS_OK;
return True;
}
@@ -201,24 +201,27 @@ void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping)
"Access-Checking" document in MSDN.
*****************************************************************************/
-BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
+BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
uint32 acc_desired, uint32 *acc_granted, uint32 *status)
{
extern NT_USER_TOKEN anonymous_token;
size_t i;
SEC_ACL *the_acl;
fstring sid_str;
- NT_USER_TOKEN *token = user->nt_user_token ? user->nt_user_token : &anonymous_token;
uint32 tmp_acc_desired = acc_desired;
if (!status || !acc_granted)
return False;
- *status = NT_STATUS_NOPROBLEMO;
+ if (!token)
+ token = &anonymous_token;
+
+ *status = NT_STATUS_OK;
*acc_granted = 0;
- DEBUG(10,("se_access_check: requested access %x, for uid %u\n",
- (unsigned int)acc_desired, (unsigned int)user->uid ));
+ DEBUG(10,("se_access_check: requested access %x, for NT token with %u entries and first sid %s.\n",
+ (unsigned int)acc_desired, (unsigned int)token->num_sids,
+ sid_to_string(sid_str, &token->user_sids[0])));
/*
* No security descriptor or security descriptor with no DACL
@@ -228,7 +231,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
/* ACL must have something in it */
if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
- *status = NT_STATUS_NOPROBLEMO;
+ *status = NT_STATUS_OK;
*acc_granted = acc_desired;
DEBUG(5, ("se_access_check: no sd or blank DACL, access allowed\n"));
return True;
@@ -276,7 +279,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
(unsigned int)tmp_acc_desired ));
tmp_acc_desired = check_ace( ace, token, tmp_acc_desired, status);
- if (*status != NT_STATUS_NOPROBLEMO) {
+ if (*status != NT_STATUS_OK) {
*acc_granted = 0;
DEBUG(5,("se_access_check: ACE %u denied with status %x.\n", (unsigned int)i, (unsigned int)*status ));
return False;
@@ -290,7 +293,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
if (tmp_acc_desired == 0) {
*acc_granted = acc_desired;
- *status = NT_STATUS_NOPROBLEMO;
+ *status = NT_STATUS_OK;
DEBUG(5,("se_access_check: access (%x) granted.\n", (unsigned int)acc_desired ));
return True;
}
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 70341507cb7..864d8a50d21 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -38,6 +38,7 @@ DOM_SID global_sid_World_Domain; /* Everyone domain */
DOM_SID global_sid_World; /* Everyone */
DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner domain */
DOM_SID global_sid_Creator_Owner; /* Creator Owner */
+DOM_SID global_sid_Creator_Group; /* Creator Group */
DOM_SID global_sid_NT_Authority; /* NT Authority */
DOM_SID global_sid_NULL; /* NULL sid */
DOM_SID global_sid_Builtin_Guests; /* Builtin guest users */
@@ -61,6 +62,7 @@ static known_sid_users everyone_users[] = {
static known_sid_users creator_owner_users[] = {
{ 0, SID_NAME_ALIAS, "Creator Owner" },
+ { 1, SID_NAME_ALIAS, "Creator Group" },
{0, (enum SID_NAME_USE)0, NULL}};
static known_sid_users nt_authority_users[] = {
@@ -179,6 +181,7 @@ void generate_wellknown_sids(void)
string_to_sid(&global_sid_World, "S-1-1-0");
string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
+ string_to_sid(&global_sid_Creator_Group, "S-1-3-1");
string_to_sid(&global_sid_NT_Authority, "S-1-5");
string_to_sid(&global_sid_NULL, "S-1-0-0");
string_to_sid(&global_sid_Authenticated_Users, "S-1-5-11");
@@ -566,3 +569,27 @@ size_t sid_size(DOM_SID *sid)
return sid->num_auths * sizeof(uint32) + 8;
}
+
+/*****************************************************************
+ Returns true if SID is internal (and non-mappable).
+*****************************************************************/
+
+BOOL non_mappable_sid(DOM_SID *sid)
+{
+ DOM_SID dom;
+ uint32 rid;
+
+ sid_copy(&dom, sid);
+ sid_split_rid(&dom, &rid);
+
+ if (sid_equal(&dom, &global_sid_Builtin))
+ return True;
+
+ if (sid_equal(&dom, &global_sid_Creator_Owner_Domain))
+ return True;
+
+ if (sid_equal(&dom, &global_sid_NT_Authority))
+ return True;
+
+ return False;
+}
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index 24290e9af44..9058cf9368c 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -22,7 +22,7 @@
#include "includes.h"
#ifdef WITH_SSL
-#include <ssl.h>
+#include <openssl/ssl.h>
#undef Realloc /* SSLeay defines this and samba has a function of this name */
extern SSL *ssl;
extern int sslFd;
@@ -490,30 +490,31 @@ static ssize_t read_socket_data(int fd,char *buffer,size_t N)
ssize_t write_data(int fd,char *buffer,size_t N)
{
- size_t total=0;
- ssize_t ret;
+ size_t total=0;
+ ssize_t ret;
- while (total < N)
- {
+ while (total < N) {
#ifdef WITH_SSL
- if(fd == sslFd){
- ret = SSL_write(ssl,buffer + total,N - total);
- }else{
- ret = write(fd,buffer + total,N - total);
- }
+ if(fd == sslFd){
+ ret = SSL_write(ssl,buffer + total,N - total);
+ } else {
+ ret = write(fd,buffer + total,N - total);
+ }
#else /* WITH_SSL */
- ret = write(fd,buffer + total,N - total);
+ ret = write(fd,buffer + total,N - total);
#endif /* WITH_SSL */
- if (ret == -1) {
- DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
- return -1;
- }
- if (ret == 0) return total;
+ if (ret == -1) {
+ DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
+ return -1;
+ }
+ if (ret == 0)
+ return (ssize_t)total;
- total += ret;
- }
- return (ssize_t)total;
+ total += (size_t)ret;
+ }
+
+ return (ssize_t)total;
}
/****************************************************************************
@@ -775,64 +776,70 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
}
/****************************************************************************
-open a socket of the specified type, port and address for incoming data
+ Open a socket of the specified type, port, and address for incoming data.
****************************************************************************/
-int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind)
+int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL rebind )
{
- struct sockaddr_in sock;
- int res;
+ struct sockaddr_in sock;
+ int res;
- memset((char *)&sock,'\0',sizeof(sock));
+ memset( (char *)&sock, '\0', sizeof(sock) );
#ifdef HAVE_SOCK_SIN_LEN
- sock.sin_len = sizeof(sock);
+ sock.sin_len = sizeof(sock);
#endif
- sock.sin_port = htons( port );
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = socket_addr;
- res = socket(AF_INET, type, 0);
- if (res == -1)
- { DEBUG(0,("socket failed\n")); return -1; }
+ sock.sin_port = htons( port );
+ sock.sin_family = AF_INET;
+ sock.sin_addr.s_addr = socket_addr;
+
+ res = socket( AF_INET, type, 0 );
+ if( res == -1 ) {
+ if( DEBUGLVL(0) ) {
+ dbgtext( "open_socket_in(): socket() call failed: " );
+ dbgtext( "%s\n", strerror( errno ) );
+ }
+ return -1;
+ }
- {
- int val=1;
- if(rebind)
- val=1;
- else
- val=0;
- if(setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1)
- DEBUG(dlevel,("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n",
- val, port, strerror(errno) ));
+ /* This block sets/clears the SO_REUSEADDR and possibly SO_REUSEPORT. */
+ {
+ int val = rebind ? 1 : 0;
+ if( setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1 ) {
+ if( DEBUGLVL( dlevel ) ) {
+ dbgtext( "open_socket_in(): setsockopt: " );
+ dbgtext( "SO_REUSEADDR = %s ", val?"True":"False" );
+ dbgtext( "on port %d failed ", port );
+ dbgtext( "with error = %s\n", strerror(errno) );
+ }
+ }
#ifdef SO_REUSEPORT
- if(setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1)
- DEBUG(dlevel,("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n",
- val, port, strerror(errno) ));
+ if( setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1 ) {
+ if( DEBUGLVL( dlevel ) ) {
+ dbgtext( "open_socket_in(): setsockopt: ");
+ dbgtext( "SO_REUSEPORT = %d ", val?"True":"False" );
+ dbgtext( "on port %d failed ", port );
+ dbgtext( "with error = %s\n", strerror(errno) );
+ }
+ }
#endif /* SO_REUSEPORT */
- }
-
- /* now we've got a socket - we need to bind it */
- if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
- {
- if (port) {
- if (port == SMB_PORT || port == NMB_PORT)
- DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
- port,inet_ntoa(sock.sin_addr),strerror(errno)));
- close(res);
-
- if (dlevel > 0 && port < 1000)
- port = 7999;
+ }
- if (port >= 1000 && port < 9000)
- return(open_socket_in(type,port+1,dlevel,socket_addr,rebind));
- }
+ /* now we've got a socket - we need to bind it */
+ if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
+ if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) {
+ dbgtext( "bind failed on port %d ", port );
+ dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) );
+ dbgtext( "Error = %s\n", strerror(errno) );
+ }
+ close( res );
+ return( -1 );
+ }
- return(-1);
- }
- DEBUG(3,("bind succeeded on port %d\n",port));
+ DEBUG( 3, ( "bind succeeded on port %d\n", port ) );
- return res;
-}
+ return( res );
+ }
/****************************************************************************
create an outgoing socket. timeout is in milliseconds.
@@ -889,7 +896,7 @@ connect_again:
#endif
if (ret < 0) {
- DEBUG(1,("error connecting to %s:%d (%s)\n",
+ DEBUG(2,("error connecting to %s:%d (%s)\n",
inet_ntoa(*addr),port,strerror(errno)));
close(res);
return -1;
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 07c91805cc7..32e2c40a7b4 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -1288,24 +1288,3 @@ char *string_truncate(char *s, int length)
}
return s;
}
-
-/* Parse a string of the form DOMAIN/user into a domain and a user */
-
-void parse_domain_user(char *domuser, fstring domain, fstring user)
-{
- char *p;
- char *sep = lp_winbind_separator();
- if (!sep) sep = "\\";
- p = strchr(domuser,*sep);
- if (!p) p = strchr(domuser,'\\');
- if (!p) {
- fstrcpy(domain,"");
- fstrcpy(user, domuser);
- return;
- }
-
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
- strupper(domain);
-}
diff --git a/source/libsmb/cli_lsarpc.c b/source/libsmb/cli_lsarpc.c
index 88f0dff225b..ef5dd4896f1 100644
--- a/source/libsmb/cli_lsarpc.c
+++ b/source/libsmb/cli_lsarpc.c
@@ -127,7 +127,7 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*pol = r.pol;
}
@@ -175,7 +175,7 @@ uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*pol = r.pol;
}
@@ -233,7 +233,7 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- if (result != NT_STATUS_NOPROBLEMO && result != 0x00000107 &&
+ if (result != NT_STATUS_OK && result != 0x00000107 &&
result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) {
/* An actual error occured */
@@ -241,7 +241,7 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- result = NT_STATUS_NOPROBLEMO;
+ result = NT_STATUS_OK;
/* Return output parameters */
@@ -336,7 +336,7 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- if (result != NT_STATUS_NOPROBLEMO &&
+ if (result != NT_STATUS_OK &&
result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) {
/* An actual error occured */
@@ -344,7 +344,7 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- result = NT_STATUS_NOPROBLEMO;
+ result = NT_STATUS_OK;
/* Return output parameters */
@@ -430,7 +430,7 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- if ((result = r.status) != NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) != NT_STATUS_OK) {
goto done;
}
@@ -525,7 +525,7 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
0x8000001a (NT_STATUS_UNABLE_TO_FREE_VM) so we ignore it and
pretend everything is OK. */
- if (result != NT_STATUS_NOPROBLEMO &&
+ if (result != NT_STATUS_OK &&
result != NT_STATUS_UNABLE_TO_FREE_VM) {
/* An actual error ocured */
@@ -533,7 +533,7 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- result = NT_STATUS_NOPROBLEMO;
+ result = NT_STATUS_OK;
/* Return output parameters */
diff --git a/source/libsmb/cli_samr.c b/source/libsmb/cli_samr.c
index 9fb7e078f67..09bb599a194 100644
--- a/source/libsmb/cli_samr.c
+++ b/source/libsmb/cli_samr.c
@@ -85,8 +85,7 @@ void cli_samr_shutdown(struct cli_state *cli)
/* Connect to SAMR database */
uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- char *srv_name, uint32 access_mask,
- POLICY_HND *connect_pol)
+ uint32 access_mask, POLICY_HND *connect_pol)
{
prs_struct qbuf, rbuf;
SAMR_Q_CONNECT q;
@@ -103,7 +102,7 @@ uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
- init_samr_q_connect(&q, srv_name, access_mask);
+ init_samr_q_connect(&q, cli->desthost, access_mask);
if (!samr_io_q_connect("", &q, &qbuf, 0) ||
!rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) {
@@ -118,7 +117,7 @@ uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*connect_pol = r.connect_pol;
}
@@ -164,7 +163,7 @@ uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*connect_pol = r.pol;
}
@@ -211,7 +210,7 @@ uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*domain_pol = r.domain_pol;
}
@@ -258,7 +257,7 @@ uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*user_pol = r.user_pol;
}
@@ -305,7 +304,7 @@ uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*group_pol = r.pol;
}
@@ -320,7 +319,7 @@ uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *user_pol, uint16 switch_value,
- SAM_USERINFO_CTR *ctr)
+ SAM_USERINFO_CTR **ctr)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_USERINFO q;
@@ -346,8 +345,6 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Unmarshall response */
- r.ctr = ctr;
-
if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) {
goto done;
}
@@ -355,6 +352,7 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
result = r.status;
+ *ctr = r.ctr;
done:
prs_mem_free(&qbuf);
@@ -446,7 +444,7 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*num_groups = r.num_entries;
*gid = r.gid;
}
@@ -494,7 +492,7 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*num_mem = r.num_entries;
*rid = r.rid;
*attr = r.attr;
@@ -546,7 +544,7 @@ uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
result = r.status;
- if (result != NT_STATUS_NOPROBLEMO &&
+ if (result != NT_STATUS_OK &&
result != STATUS_MORE_ENTRIES) {
goto done;
}
@@ -620,7 +618,7 @@ uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) != NT_STATUS_OK) {
goto done;
}
@@ -680,7 +678,7 @@ uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*alias_pol = r.pol;
}
@@ -729,7 +727,7 @@ uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) != NT_STATUS_OK) {
goto done;
}
@@ -772,13 +770,18 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Unmarshall response */
+ r.ctr = ctr;
+
if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
goto done;
}
/* Return output parameters */
- if ((result = r.status) != NT_STATUS_NOPROBLEMO) {
+ result = r.status;
+
+ if (result != NT_STATUS_OK &&
+ result != STATUS_MORE_ENTRIES) {
goto done;
}
@@ -791,3 +794,336 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
+
+/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are
+ looked up in one packet. */
+
+uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_rids, uint32 *rids,
+ uint32 *num_names, char ***names,
+ uint32 **name_types)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_LOOKUP_RIDS q;
+ SAMR_R_LOOKUP_RIDS r;
+ uint32 result = NT_STATUS_UNSUCCESSFUL, i;
+
+ if (num_rids > 1000) {
+ DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
+ "more than ~1000 rids are looked up at once.\n"));
+ }
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
+ num_rids, rids);
+
+ if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if ((result = r.status) != NT_STATUS_OK) {
+ goto done;
+ }
+
+ if (r.num_names1 == 0) {
+ *num_names = 0;
+ *names = NULL;
+ goto done;
+ }
+
+ *num_names = r.num_names1;
+ *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
+ *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
+
+ for (i = 0; i < r.num_names1; i++) {
+ fstring tmp;
+
+ unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
+ (*names)[i] = talloc_strdup(mem_ctx, tmp);
+ (*name_types)[i] = r.type[i];
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Lookup names */
+
+uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, uint32 flags,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids,
+ uint32 **rid_types)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_LOOKUP_NAMES q;
+ SAMR_R_LOOKUP_NAMES r;
+ uint32 result = NT_STATUS_UNSUCCESSFUL, i;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
+ num_names, names);
+
+ if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if ((result = r.status) != NT_STATUS_OK) {
+ goto done;
+ }
+
+ if (r.num_rids1 == 0) {
+ *num_rids = 0;
+ goto done;
+ }
+
+ *num_rids = r.num_rids1;
+ *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
+ *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
+
+ for (i = 0; i < r.num_rids1; i++) {
+ (*rids)[i] = r.rids[i];
+ (*rid_types)[i] = r.types[i];
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Create a domain user */
+
+uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *domain_pol, char *acct_name,
+ uint32 acb_info, uint32 unknown,
+ POLICY_HND *user_pol, uint32 *rid)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_CREATE_USER q;
+ SAMR_R_CREATE_USER r;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
+
+ if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if ((result = r.status) != NT_STATUS_OK) {
+ goto done;
+ }
+
+ if (user_pol)
+ *user_pol = r.user_pol;
+
+ if (rid)
+ *rid = r.user_rid;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Set userinfo */
+
+uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_SET_USERINFO q;
+ SAMR_R_SET_USERINFO r;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ q.ctr = ctr;
+
+ init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value,
+ ctr->info.id);
+
+ if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if ((result = r.status) != NT_STATUS_OK) {
+ goto done;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Set userinfo2 */
+
+uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol, uint16 switch_value,
+ uchar sess_key[16], SAM_USERINFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_SET_USERINFO2 q;
+ SAMR_R_SET_USERINFO2 r;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
+
+ if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if ((result = r.status) != NT_STATUS_OK) {
+ goto done;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+/* Delete domain user */
+
+uint32 cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *user_pol)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_DELETE_DOM_USER q;
+ SAMR_R_DELETE_DOM_USER r;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Marshall data and send request */
+
+ init_samr_q_delete_dom_user(&q, user_pol);
+
+ if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ result = r.status;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
diff --git a/source/libsmb/cli_spoolss.c b/source/libsmb/cli_spoolss.c
index 2c962ef27a0..6353365773d 100644
--- a/source/libsmb/cli_spoolss.c
+++ b/source/libsmb/cli_spoolss.c
@@ -133,7 +133,7 @@ uint32 cli_spoolss_open_printer_ex(
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*pol = r.handle;
}
@@ -186,7 +186,7 @@ uint32 cli_spoolss_close_printer(
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
*pol = r.handle;
}
@@ -221,7 +221,7 @@ static void decode_printer_info_0(
uint32 i;
PRINTER_INFO_0 *inf;
- inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0));
+ inf=(PRINTER_INFO_0 *)talloc(mem_ctx,returned*sizeof(PRINTER_INFO_0));
buffer->prs.data_offset=0;
@@ -478,7 +478,7 @@ uint32 cli_spoolss_enum_printers(
/* Return output parameters */
- if (((result=r.status) == NT_STATUS_NOPROBLEMO) && (*returned = r.returned))
+ if (((result=r.status) == NT_STATUS_OK) && (*returned = r.returned))
{
switch (level) {
@@ -554,7 +554,7 @@ uint32 cli_spoolss_enum_ports(
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO &&
+ if ((result = r.status) == NT_STATUS_OK &&
r.returned > 0) {
*returned = r.returned;
@@ -623,7 +623,7 @@ uint32 cli_spoolss_getprinter(
}
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO) {
+ if ((result = r.status) == NT_STATUS_OK) {
switch (level) {
case 0:
@@ -754,7 +754,7 @@ uint32 cli_spoolss_getprinterdriver (
}
/* Return output parameters */
- if ((result = r.status) == NT_STATUS_NOPROBLEMO)
+ if ((result = r.status) == NT_STATUS_OK)
{
switch (level)
@@ -833,7 +833,7 @@ uint32 cli_spoolss_enumprinterdrivers (
}
/* Return output parameters */
- if (((result=r.status) == NT_STATUS_NOPROBLEMO) &&
+ if (((result=r.status) == NT_STATUS_OK) &&
(r.returned != 0))
{
*returned = r.returned;
@@ -914,7 +914,7 @@ uint32 cli_spoolss_getprinterdriverdir (
}
/* Return output parameters */
- if ((result=r.status) == NT_STATUS_NOPROBLEMO)
+ if ((result=r.status) == NT_STATUS_OK)
{
switch (level)
{
diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c
index 6d499867905..2f0c0e66184 100644
--- a/source/libsmb/clierror.c
+++ b/source/libsmb/clierror.c
@@ -197,7 +197,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_
case ERRrename: return EEXIST;
case ERRbadshare: return EBUSY;
case ERRlock: return EBUSY;
- case ERROR_INVALID_NAME: return ENOENT;
+ case ERRinvalidname: return ENOENT;
case ERRnosuchshare: return ENODEV;
}
}
diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c
index 56d2f63c799..d63b4817a47 100644
--- a/source/libsmb/clifile.c
+++ b/source/libsmb/clifile.c
@@ -489,6 +489,10 @@ BOOL cli_lock64(struct cli_state *cli, int fnum,
int saved_timeout = cli->timeout;
int ltype;
+ if (! (cli->capabilities & CAP_LARGE_FILES)) {
+ return cli_lock(cli, fnum, offset, len, timeout, lock_type);
+ }
+
ltype = (lock_type == READ_LOCK? 1 : 0);
ltype |= LOCKING_ANDX_LARGE_FILES;
@@ -540,6 +544,10 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_
{
char *p;
+ if (! (cli->capabilities & CAP_LARGE_FILES)) {
+ return cli_unlock(cli, fnum, offset, len);
+ }
+
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c
index 458532cb2ed..8eb54b7f389 100644
--- a/source/libsmb/clireadwrite.c
+++ b/source/libsmb/clireadwrite.c
@@ -24,7 +24,7 @@
#include "includes.h"
/****************************************************************************
-issue a single SMBread and don't wait for a reply
+Issue a single SMBread and don't wait for a reply.
****************************************************************************/
static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
@@ -50,6 +50,31 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
}
/****************************************************************************
+Issue a single SMBreadraw and don't wait for a reply.
+****************************************************************************/
+
+static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset,
+ size_t size, int i)
+{
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
+
+ set_message(cli->outbuf,10,0,True);
+
+ CVAL(cli->outbuf,smb_com) = SMBreadbraw;
+ SSVAL(cli->outbuf,smb_tid,cli->cnum);
+ cli_setup_packet(cli);
+
+ SSVAL(cli->outbuf,smb_vwv0,fnum);
+ SIVAL(cli->outbuf,smb_vwv1,offset);
+ SSVAL(cli->outbuf,smb_vwv2,size);
+ SSVAL(cli->outbuf,smb_vwv3,size);
+ SSVAL(cli->outbuf,smb_mid,cli->mid + i);
+
+ return cli_send_smb(cli);
+}
+
+/****************************************************************************
Read size bytes at offset offset using SMBreadX.
****************************************************************************/
@@ -124,6 +149,68 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
}
/****************************************************************************
+ Tester for the readraw call.
+****************************************************************************/
+
+ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size)
+{
+ char *p;
+ int size2;
+ size_t readsize;
+ ssize_t total = 0;
+
+ if (size == 0)
+ return 0;
+
+ /*
+ * Set readsize to the maximum size we can handle in one readraw.
+ */
+
+ readsize = 0xFFFF;
+
+ while (total < size) {
+ readsize = MIN(readsize, size-total);
+
+ /* Issue a read and receive a reply */
+
+ if (!cli_issue_readraw(cli, fnum, offset, readsize, 0))
+ return -1;
+
+ if (!client_receive_smb(cli->fd, cli->inbuf, cli->timeout))
+ return -1;
+
+ size2 = smb_len(cli->inbuf);
+
+ if (size2 > readsize) {
+ DEBUG(5,("server returned more than we wanted!\n"));
+ return -1;
+ } else if (size2 < 0) {
+ DEBUG(5,("read return < 0!\n"));
+ return -1;
+ }
+
+ /* Copy data into buffer */
+
+ if (size2) {
+ p = cli->inbuf + 4;
+ memcpy(buf + total, p, size2);
+ }
+
+ total += size2;
+ offset += size2;
+
+ /*
+ * If the server returned less than we asked for we're at EOF.
+ */
+
+ if (size2 < readsize)
+ break;
+ }
+
+ return total;
+}
+
+/****************************************************************************
issue a single SMBwrite and don't wait for a reply
****************************************************************************/
diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c
index d21d179126a..6038584a891 100644
--- a/source/libsmb/clitrans.c
+++ b/source/libsmb/clitrans.c
@@ -147,6 +147,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
int this_data,this_param;
uint8 eclass;
uint32 ecode;
+ char *tdata;
+ char *tparam;
*data_len = *param_len = 0;
@@ -185,8 +187,25 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
total_param = SVAL(cli->inbuf,smb_tprcnt);
/* allocate it */
- *data = Realloc(*data,total_data);
- *param = Realloc(*param,total_param);
+ if (total_data!=0) {
+ tdata = Realloc(*data,total_data);
+ if (!tdata) {
+ DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n"));
+ return False;
+ }
+ else
+ *data = tdata;
+ }
+
+ if (total_param!=0) {
+ tparam = Realloc(*param,total_param);
+ if (!tparam) {
+ DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n"));
+ return False;
+ }
+ else
+ *param = tparam;
+ }
while (1) {
this_data = SVAL(cli->inbuf,smb_drcnt);
@@ -355,6 +374,8 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
int this_data,this_param;
uint8 eclass;
uint32 ecode;
+ char *tdata;
+ char *tparam;
*data_len = *param_len = 0;
@@ -385,8 +406,20 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount);
/* allocate it */
- *data = Realloc(*data,total_data);
- *param = Realloc(*param,total_param);
+ tdata = Realloc(*data,total_data);
+ if (!tdata) {
+ DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer"));
+ return False;
+ }
+ else
+ *data = tdata;
+ tparam = Realloc(*param,total_param);
+ if (!tparam) {
+ DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer"));
+ return False;
+ }
+ else
+ *param = tparam;
while (1) {
this_data = SVAL(cli->inbuf,smb_ntr_DataCount);
diff --git a/source/libsmb/credentials.c b/source/libsmb/credentials.c
index 26d5c13bc9a..d4c87920686 100644
--- a/source/libsmb/credentials.c
+++ b/source/libsmb/credentials.c
@@ -156,8 +156,8 @@ BOOL clnt_deal_with_creds(uchar sess_key[8],
new_clnt_time.time = sto_clnt_cred->timestamp.time + 1;
/* check that the received server credentials are valid */
- if (!cred_assert(&(rcv_srv_cred->challenge), sess_key,
- &(sto_clnt_cred->challenge), new_clnt_time))
+ if (!cred_assert(&rcv_srv_cred->challenge, sess_key,
+ &sto_clnt_cred->challenge, new_clnt_time))
{
return False;
}
@@ -187,8 +187,8 @@ BOOL deal_with_creds(uchar sess_key[8],
DEBUG(5,("deal_with_creds: %d\n", __LINE__));
/* check that the received client credentials are valid */
- if (!cred_assert(&(rcv_clnt_cred->challenge), sess_key,
- &(sto_clnt_cred->challenge), rcv_clnt_cred->timestamp))
+ if (!cred_assert(&rcv_clnt_cred->challenge, sess_key,
+ &sto_clnt_cred->challenge, rcv_clnt_cred->timestamp))
{
return False;
}
@@ -208,8 +208,8 @@ BOOL deal_with_creds(uchar sess_key[8],
DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time));
/* create return credentials for inclusion in the reply */
- cred_create(sess_key, &(sto_clnt_cred->challenge), new_clnt_time,
- &(rtn_srv_cred->challenge));
+ cred_create(sess_key, &sto_clnt_cred->challenge, new_clnt_time,
+ &rtn_srv_cred->challenge);
DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data)));
@@ -218,5 +218,3 @@ BOOL deal_with_creds(uchar sess_key[8],
return True;
}
-
-
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index 465198dfad4..aa6301cc38e 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -290,151 +290,160 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
BOOL bcast,BOOL recurse,
struct in_addr to_ip, int *count)
{
- BOOL found=False;
- int i, retries = 3;
- int retry_time = bcast?250:2000;
- struct timeval tval;
- struct packet_struct p;
- struct packet_struct *p2;
- struct nmb_packet *nmb = &p.packet.nmb;
- struct in_addr *ip_list = NULL;
+ BOOL found=False;
+ int i, retries = 3;
+ int retry_time = bcast?250:2000;
+ struct timeval tval;
+ struct packet_struct p;
+ struct packet_struct *p2;
+ struct nmb_packet *nmb = &p.packet.nmb;
+ struct in_addr *ip_list = NULL;
- memset((char *)&p,'\0',sizeof(p));
- (*count) = 0;
+ memset((char *)&p,'\0',sizeof(p));
+ (*count) = 0;
- nmb->header.name_trn_id = generate_trn_id();
- nmb->header.opcode = 0;
- nmb->header.response = False;
- nmb->header.nm_flags.bcast = bcast;
- nmb->header.nm_flags.recursion_available = False;
- nmb->header.nm_flags.recursion_desired = recurse;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
- nmb->header.rcode = 0;
- nmb->header.qdcount = 1;
- nmb->header.ancount = 0;
- nmb->header.nscount = 0;
- nmb->header.arcount = 0;
+ nmb->header.name_trn_id = generate_trn_id();
+ nmb->header.opcode = 0;
+ nmb->header.response = False;
+ nmb->header.nm_flags.bcast = bcast;
+ nmb->header.nm_flags.recursion_available = False;
+ nmb->header.nm_flags.recursion_desired = recurse;
+ nmb->header.nm_flags.trunc = False;
+ nmb->header.nm_flags.authoritative = False;
+ nmb->header.rcode = 0;
+ nmb->header.qdcount = 1;
+ nmb->header.ancount = 0;
+ nmb->header.nscount = 0;
+ nmb->header.arcount = 0;
- make_nmb_name(&nmb->question.question_name,name,name_type);
+ make_nmb_name(&nmb->question.question_name,name,name_type);
- nmb->question.question_type = 0x20;
- nmb->question.question_class = 0x1;
+ nmb->question.question_type = 0x20;
+ nmb->question.question_class = 0x1;
- p.ip = to_ip;
- p.port = NMB_PORT;
- p.fd = fd;
- p.timestamp = time(NULL);
- p.packet_type = NMB_PACKET;
+ p.ip = to_ip;
+ p.port = NMB_PORT;
+ p.fd = fd;
+ p.timestamp = time(NULL);
+ p.packet_type = NMB_PACKET;
- GetTimeOfDay(&tval);
+ GetTimeOfDay(&tval);
- if (!send_packet(&p))
- return NULL;
+ if (!send_packet(&p))
+ return NULL;
- retries--;
+ retries--;
- while (1)
- {
- struct timeval tval2;
- GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time) {
- if (!retries)
- break;
- if (!found && !send_packet(&p))
- return NULL;
- GetTimeOfDay(&tval);
- retries--;
- }
+ while (1) {
+ struct timeval tval2;
+ struct in_addr *tmp_ip_list;
+
+ GetTimeOfDay(&tval2);
+ if (TvalDiff(&tval,&tval2) > retry_time) {
+ if (!retries)
+ break;
+ if (!found && !send_packet(&p))
+ return NULL;
+ GetTimeOfDay(&tval);
+ retries--;
+ }
- if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
- struct nmb_packet *nmb2 = &p2->packet.nmb;
- debug_nmb_packet(p2);
-
- /* If we get a Negative Name Query Response from a WINS
- * server, we should report it and give up.
- */
- if( 0 == nmb2->header.opcode /* A query response */
- && !(bcast) /* from a WINS server */
- && nmb2->header.rcode /* Error returned */
- ) {
-
- if( DEBUGLVL( 3 ) ) {
- /* Only executed if DEBUGLEVEL >= 3 */
- dbgtext( "Negative name query response, rcode 0x%02x: ",
- nmb2->header.rcode );
- switch( nmb2->header.rcode ) {
- case 0x01:
- dbgtext( "Request was invalidly formatted.\n" );
- break;
- case 0x02:
- dbgtext( "Problem with NBNS, cannot process name.\n");
- break;
- case 0x03:
- dbgtext( "The name requested does not exist.\n" );
- break;
- case 0x04:
- dbgtext( "Unsupported request error.\n" );
- break;
- case 0x05:
- dbgtext( "Query refused error.\n" );
- break;
- default:
- dbgtext( "Unrecognized error code.\n" );
- break;
- }
- }
- free_packet(p2);
- return( NULL );
- }
+ if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
+ struct nmb_packet *nmb2 = &p2->packet.nmb;
+ debug_nmb_packet(p2);
- if (nmb2->header.opcode != 0 ||
- nmb2->header.nm_flags.bcast ||
- nmb2->header.rcode ||
- !nmb2->header.ancount) {
- /*
- * XXXX what do we do with this? Could be a
- * redirect, but we'll discard it for the
- * moment. */
- free_packet(p2);
- continue;
- }
+ /* If we get a Negative Name Query Response from a WINS
+ * server, we should report it and give up.
+ */
+ if( 0 == nmb2->header.opcode /* A query response */
+ && !(bcast) /* from a WINS server */
+ && nmb2->header.rcode /* Error returned */
+ ) {
+
+ if( DEBUGLVL( 3 ) ) {
+ /* Only executed if DEBUGLEVEL >= 3 */
+ dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
+ switch( nmb2->header.rcode ) {
+ case 0x01:
+ dbgtext( "Request was invalidly formatted.\n" );
+ break;
+ case 0x02:
+ dbgtext( "Problem with NBNS, cannot process name.\n");
+ break;
+ case 0x03:
+ dbgtext( "The name requested does not exist.\n" );
+ break;
+ case 0x04:
+ dbgtext( "Unsupported request error.\n" );
+ break;
+ case 0x05:
+ dbgtext( "Query refused error.\n" );
+ break;
+ default:
+ dbgtext( "Unrecognized error code.\n" );
+ break;
+ }
+ }
- ip_list = (struct in_addr *)Realloc( ip_list,
- sizeof( ip_list[0] )
- * ( (*count) + nmb2->answers->rdlength/6 ) );
- if (ip_list) {
- DEBUG(2,("Got a positive name query response from %s ( ",
- inet_ntoa(p2->ip)));
- for (i=0;i<nmb2->answers->rdlength/6;i++) {
- putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
- DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
- (*count)++;
- }
- DEBUGADD(2,(")\n"));
- }
+ free_packet(p2);
+ return( NULL );
+ }
- found=True;
- retries=0;
- free_packet(p2);
- /*
- * If we're doing a unicast lookup we only
- * expect one reply. Don't wait the full 2
- * seconds if we got one. JRA.
- */
- if(!bcast && found)
- break;
- }
- }
+ if (nmb2->header.opcode != 0 ||
+ nmb2->header.nm_flags.bcast ||
+ nmb2->header.rcode ||
+ !nmb2->header.ancount) {
+ /*
+ * XXXX what do we do with this? Could be a
+ * redirect, but we'll discard it for the
+ * moment.
+ */
+ free_packet(p2);
+ continue;
+ }
- /* Reach here if we've timed out waiting for replies.. */
- if( !bcast && !found )
- {
- /* Timed out wating for WINS server to respond. Mark it dead. */
- wins_srv_died( to_ip );
- }
+ tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] )
+ * ( (*count) + nmb2->answers->rdlength/6 ) );
+
+ if (!tmp_ip_list) {
+ DEBUG(0,("name_query: Realloc failed.\n"));
+ if (ip_list)
+ free(ip_list);
+ }
+
+ ip_list = tmp_ip_list;
+
+ if (ip_list) {
+ DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
+ for (i=0;i<nmb2->answers->rdlength/6;i++) {
+ putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
+ DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
+ (*count)++;
+ }
+ DEBUGADD(2,(")\n"));
+ }
+
+ found=True;
+ retries=0;
+ free_packet(p2);
+
+ /*
+ * If we're doing a unicast lookup we only
+ * expect one reply. Don't wait the full 2
+ * seconds if we got one. JRA.
+ */
+ if(!bcast && found)
+ break;
+ }
+ }
+
+ /* Reach here if we've timed out waiting for replies.. */
+ if( !bcast && !found ) {
+ /* Timed out wating for WINS server to respond. Mark it dead. */
+ wins_srv_died( to_ip );
+ }
- return ip_list;
+ return ip_list;
}
/********************************************************
@@ -552,6 +561,13 @@ BOOL name_register_wins(const char *name, int name_type)
int num_interfaces = iface_count();
struct in_addr sendto_ip;
+ /*
+ * Check if we have any interfaces, prevents a segfault later
+ */
+
+ if (num_interfaces <= 0)
+ return False; /* Should return some indication of the problem */
+
/*
* Do a broadcast register ...
*/
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index 7efb2bb9b31..872cc288769 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -51,38 +51,6 @@ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
#endif
}
-/* Routines for Windows NT MD4 Hash functions. */
-static int _my_wcslen(int16 *str)
-{
- int len = 0;
- while(*str++ != 0)
- len++;
- return len;
-}
-
-/*
- * Convert a string into an NT UNICODE string.
- * Note that regardless of processor type
- * this must be in intel (little-endian)
- * format.
- */
-
-static int _my_mbstowcs(int16 *dst, uchar *src, int len)
-{
- int i;
- int16 val;
-
- for(i = 0; i < len; i++) {
- val = *src;
- SSVAL(dst,0,val);
- dst++;
- src++;
- if(val == 0)
- break;
- }
- return i;
-}
-
/*
* Creates the MD4 Hash of the users password in NT UNICODE.
*/
@@ -96,11 +64,10 @@ void E_md4hash(uchar *passwd, uchar *p16)
len = strlen((char *)passwd);
if(len > 128)
len = 128;
- /* Password must be converted to NT unicode */
- _my_mbstowcs(wpwd, passwd, len);
- wpwd[len] = 0; /* Ensure string is null terminated */
+ /* Password must be converted to NT unicode - null terminated. */
+ dos_struni2((char *)wpwd, (const char *)passwd, 256);
/* Calculate length in bytes */
- len = _my_wcslen(wpwd) * sizeof(int16);
+ len = strlen_w((const smb_ucs2_t *)wpwd) * sizeof(int16);
mdfour(p16, (unsigned char *)wpwd, len);
}
@@ -229,6 +196,34 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
}
/***********************************************************
+ Encode a password buffer.
+************************************************************/
+
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set)
+{
+ generate_random_buffer((unsigned char *)buffer, 516, True);
+
+ if (new_pw_len < 0 || new_pw_len > 512)
+ return False;
+
+ if (nt_pass_set) {
+ new_pw_len *= 2;
+ dos_struni2(&buffer[512 - new_pw_len], new_pass, 256);
+ } else {
+ memcpy(&buffer[512 - new_pw_len], new_pass, new_pw_len);
+ }
+
+ /*
+ * The length of the new password is in the last 4 bytes of
+ * the data buffer.
+ */
+ SIVAL(buffer, 512, new_pw_len);
+
+ return True;
+}
+
+/***********************************************************
decode a password buffer
************************************************************/
BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
@@ -319,3 +314,18 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
}
+/* Calculate the NT owfs of a user's password */
+void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16])
+{
+ char buf[512];
+ int i;
+
+ for (i = 0; i < MIN(pwd->uni_str_len, sizeof(buf) / 2); i++)
+ SIVAL(buf, i * 2, pwd->buffer[i]);
+
+ /* Calculate the MD4 hash (NT compatible) of the password */
+ mdfour(nt_p16, (unsigned char *)buf, pwd->uni_str_len * 2);
+
+ /* clear out local copy of user's password (just being paranoid). */
+ ZERO_STRUCT(buf);
+}
diff --git a/source/libsmb/smberr.c b/source/libsmb/smberr.c
index c2d8884d738..9648786ea54 100644
--- a/source/libsmb/smberr.c
+++ b/source/libsmb/smberr.c
@@ -36,34 +36,35 @@ typedef struct
/* Dos Error Messages */
err_code_struct dos_msgs[] = {
- {"ERRbadfunc",1,"Invalid function."},
- {"ERRbadfile",2,"File not found."},
- {"ERRbadpath",3,"Directory invalid."},
- {"ERRnofids",4,"No file descriptors available"},
- {"ERRnoaccess",5,"Access denied."},
- {"ERRbadfid",6,"Invalid file handle."},
+ {"ERRbadfunc",ERRbadfunc,"Invalid function."},
+ {"ERRbadfile",ERRbadfile,"File not found."},
+ {"ERRbadpath",ERRbadpath,"Directory invalid."},
+ {"ERRnofids",ERRnofids,"No file descriptors available"},
+ {"ERRnoaccess",ERRnoaccess,"Access denied."},
+ {"ERRbadfid",ERRbadfid,"Invalid file handle."},
{"ERRbadmcb",7,"Memory control blocks destroyed."},
- {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
- {"ERRbadmem",9,"Invalid memory block address."},
- {"ERRbadenv",10,"Invalid environment."},
+ {"ERRnomem",ERRnomem,"Insufficient server memory to perform the requested function."},
+ {"ERRbadmem",ERRbadmem,"Invalid memory block address."},
+ {"ERRbadenv",ERRbadenv,"Invalid environment."},
{"ERRbadformat",11,"Invalid format."},
- {"ERRbadaccess",12,"Invalid open mode."},
- {"ERRbaddata",13,"Invalid data."},
- {"ERR",14,"reserved."},
- {"ERRbaddrive",15,"Invalid drive specified."},
- {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."},
- {"ERRdiffdevice",17,"Not same device."},
- {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
- {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
- {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
- {"ERRunsup", 50, "The operation is unsupported"},
- {"ERRnosuchshare", 67, "You specified an invalid share name"},
- {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."},
- {"ERRbadpipe",230,"Pipe invalid."},
- {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
- {"ERRpipeclosing",232,"Pipe close in progress."},
- {"ERRnotconnected",233,"No process on other end of pipe."},
- {"ERRmoredata",234,"There is more data to be returned."},
+ {"ERRbadaccess",ERRbadaccess,"Invalid open mode."},
+ {"ERRbaddata",ERRbaddata,"Invalid data."},
+ {"ERR",ERRres,"reserved."},
+ {"ERRbaddrive",ERRbaddrive,"Invalid drive specified."},
+ {"ERRremcd",ERRremcd,"A Delete Directory request attempted to remove the server's current directory."},
+ {"ERRdiffdevice",ERRdiffdevice,"Not same device."},
+ {"ERRnofiles",ERRnofiles,"A File Search command can find no more files matching the specified criteria."},
+ {"ERRbadshare",ERRbadshare,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
+ {"ERRlock",ERRlock,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
+ {"ERRunsup", ERRunsup, "The operation is unsupported"},
+ {"ERRnosuchshare", ERRnosuchshare, "You specified an invalid share name"},
+ {"ERRfilexists",ERRfilexists,"The file named in a Create Directory, Make New File or Link request already exists."},
+ {"ERRinvalidname",ERRinvalidname, "Invalid name"},
+ {"ERRbadpipe",ERRbadpipe,"Pipe invalid."},
+ {"ERRpipebusy",ERRpipebusy,"All instances of the requested pipe are busy."},
+ {"ERRpipeclosing",ERRpipeclosing,"Pipe close in progress."},
+ {"ERRnotconnected",ERRnotconnected,"No process on other end of pipe."},
+ {"ERRmoredata",ERRmoredata,"There is more data to be returned."},
{"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"},
{NULL,-1,NULL}};
@@ -164,10 +165,12 @@ char *smb_errstr(char *inbuf)
if (num == err[j].code)
{
if (DEBUGLEVEL > 0)
- slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class,
- err[j].name,err[j].message);
+ slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",
+ err_classes[i].class,
+ err[j].name,err[j].message);
else
- slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name);
+ slprintf(ret, sizeof(ret) - 1, "%s - %s",
+ err_classes[i].class,err[j].name);
return ret;
}
}
diff --git a/source/libsmb/unexpected.c b/source/libsmb/unexpected.c
index 4aa566de5b2..8f115623a1c 100644
--- a/source/libsmb/unexpected.c
+++ b/source/libsmb/unexpected.c
@@ -50,7 +50,7 @@ void unexpected_packet(struct packet_struct *p)
if (!tdbd) {
tdbd = tdb_open_log(lock_path("unexpected.tdb"), 1,
- TDB_CLEAR_IF_FIRST,
+ TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
O_RDWR | O_CREAT, 0644);
if (!tdbd) {
DEBUG(0,("Failed to open unexpected.tdb\n"));
@@ -151,7 +151,7 @@ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
{
TDB_CONTEXT *tdb2;
- tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0);
+ tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
if (!tdb2) return NULL;
matched_packet = NULL;
diff --git a/source/locking/brlock.c b/source/locking/brlock.c
index 7f3ec6757e3..7f91f664102 100644
--- a/source/locking/brlock.c
+++ b/source/locking/brlock.c
@@ -99,11 +99,36 @@ static BOOL brl_same_context(struct lock_context *ctx1,
static BOOL brl_conflict(struct lock_struct *lck1,
struct lock_struct *lck2)
{
+ if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) {
+ return False;
+ }
+
+ if (brl_same_context(&lck1->context, &lck2->context) &&
+ lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) {
+ return False;
+ }
+
+ if (lck1->start >= (lck2->start + lck2->size) ||
+ lck2->start >= (lck1->start + lck1->size)) {
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ Check to see if this lock conflicts, but ignore our own locks on the
+ same fnum only.
+****************************************************************************/
+
+static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2)
+{
if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK)
return False;
if (brl_same_context(&lck1->context, &lck2->context) &&
- lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) return False;
+ lck1->fnum == lck2->fnum)
+ return False;
if (lck1->start >= (lck2->start + lck2->size) ||
lck2->start >= (lck1->start + lck1->size)) return False;
@@ -176,7 +201,7 @@ void brl_init(int read_only)
if (tdb)
return;
- tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_CLEAR_IF_FIRST,
+ tdb = tdb_open_log(lock_path("brlock.tdb"), 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
if (!tdb) {
DEBUG(0,("Failed to open byte range locking database\n"));
@@ -218,11 +243,19 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
TDB_DATA kbuf, dbuf;
int count, i;
struct lock_struct lock, *locks;
+ char *tp;
kbuf = locking_key(dev,ino);
dbuf.dptr = NULL;
+#if 0
+ if (start == 0 && size == 0) {
+ tdb_delete(tdb, kbuf);
+ return True;
+ }
+#endif
+
tdb_chainlock(tdb, kbuf);
dbuf = tdb_fetch(tdb, kbuf);
@@ -245,9 +278,18 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
}
}
+#if 0
+ if (start == 0 && size == 0) {
+ if (dbuf.dptr) free(dbuf.dptr);
+ tdb_chainunlock(tdb, kbuf);
+ return True;
+ }
+#endif
+
/* no conflicts - add it to the list of locks */
- dbuf.dptr = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks));
- if (!dbuf.dptr) goto fail;
+ tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks));
+ if (!tp) goto fail;
+ else dbuf.dptr = tp;
memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock));
dbuf.dsize += sizeof(lock);
tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
@@ -294,21 +336,37 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
/* there are existing locks - find a match */
locks = (struct lock_struct *)dbuf.dptr;
count = dbuf.dsize / sizeof(*locks);
- for (i=0; i<count; i++) {
+ for (i=0; i<count; i++) {
struct lock_struct *lock = &locks[i];
-#if 0
- /* JRATEST - DEBUGGING INFO */
- if(!brl_same_context(&lock->context, &context)) {
- DEBUG(10,("brl_unlock: Not same context. l_smbpid = %u, l_pid = %u, l_tid = %u: \
-smbpid = %u, pid = %u, tid = %u\n",
- lock->context.smbpid, lock->context.pid, lock->context.tid,
- context.smbpid, context.pid, context.tid ));
+ if (lock->lock_type == WRITE_LOCK &&
+ brl_same_context(&lock->context, &context) &&
+ lock->fnum == fnum &&
+ lock->start == start &&
+ lock->size == size) {
+ /* found it - delete it */
+ if (count == 1) {
+ tdb_delete(tdb, kbuf);
+ } else {
+ if (i < count-1) {
+ memmove(&locks[i], &locks[i+1],
+ sizeof(*locks)*((count-1) - i));
+ }
+ dbuf.dsize -= sizeof(*locks);
+ tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+ }
+ free(dbuf.dptr);
+ tdb_chainunlock(tdb, kbuf);
+ return True;
}
- /* JRATEST */
-#endif
+ }
+
+ locks = (struct lock_struct *)dbuf.dptr;
+ count = dbuf.dsize / sizeof(*locks);
+ for (i=0; i<count; i++) {
+ struct lock_struct *lock = &locks[i];
if (brl_same_context(&lock->context, &context) &&
lock->fnum == fnum &&
@@ -340,25 +398,6 @@ smbpid = %u, pid = %u, tid = %u\n",
return False;
}
-/****************************************************************************
- Check to see if this lock conflicts, but ignore our own locks on the
- same fnum only.
-****************************************************************************/
-
-static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2)
-{
- if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK)
- return False;
-
- if (brl_same_context(&lck1->context, &lck2->context) &&
- lck1->fnum == lck2->fnum)
- return False;
-
- if (lck1->start >= (lck2->start + lck2->size) ||
- lck2->start >= (lck1->start + lck1->size)) return False;
-
- return True;
-}
/****************************************************************************
Test if we could add a lock if we wanted to.
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 067b1dc0ddf..b2fb6812652 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -108,12 +108,9 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
if (!lp_locking(SNUM(conn)))
return(True);
- if (count == 0) {
- *eclass = ERRDOS;
- *ecode = ERRnoaccess;
- return False;
- }
-
+ /* NOTE! 0 byte long ranges ARE allowed and should be stored */
+
+
DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
@@ -239,13 +236,14 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
int i, del_count=0;
pid_t mypid = sys_getpid();
BOOL check_self = *(BOOL *)state;
+ int ret = 0;
tdb_chainlock(tdb, kbuf);
data = (struct locking_data *)dbuf.dptr;
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
- for (i=0;i<data->num_share_mode_entries;) {
+ for (i=0;i<data->u.num_share_mode_entries;) {
if (check_self && (shares[i].pid == mypid)) {
DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n",
@@ -259,7 +257,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
continue;
}
- data->num_share_mode_entries--;
+ data->u.num_share_mode_entries--;
memmove(&shares[i], &shares[i+1],
dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
del_count++;
@@ -270,13 +268,16 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
dbuf.dsize -= del_count * sizeof(*shares);
/* store it back in the database */
- if (data->num_share_mode_entries == 0)
- tdb_delete(ttdb, kbuf);
- else
- tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE);
+ if (data->u.num_share_mode_entries == 0) {
+ if (tdb_delete(ttdb, kbuf) == -1)
+ ret = -1;
+ } else {
+ if (tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE) == -1)
+ ret = -1;
+ }
tdb_chainunlock(tdb, kbuf);
- return 0;
+ return ret;
}
/****************************************************************************
@@ -295,7 +296,7 @@ BOOL locking_init(int read_only)
return True;
tdb = tdb_open_log(lock_path("locking.tdb"),
- 0, TDB_CLEAR_IF_FIRST,
+ 0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
read_only?O_RDONLY:O_RDWR|O_CREAT,
0644);
@@ -340,8 +341,9 @@ BOOL locking_end(void)
}
/*******************************************************************
- form a static locking key for a dev/inode pair
+ Form a static locking key for a dev/inode pair.
******************************************************************/
+
static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
{
static struct locking_key key;
@@ -354,14 +356,20 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
kbuf.dsize = sizeof(key);
return kbuf;
}
+
static TDB_DATA locking_key_fsp(files_struct *fsp)
{
return locking_key(fsp->dev, fsp->inode);
}
+#ifndef LOCK_SHARE_ENTRY_SPIN_COUNT
+#define LOCK_SHARE_ENTRY_SPIN_COUNT 100
+#endif
+
/*******************************************************************
Lock a hash bucket entry.
******************************************************************/
+
BOOL lock_share_entry(connection_struct *conn,
SMB_DEV_T dev, SMB_INO_T inode)
{
@@ -371,16 +379,17 @@ BOOL lock_share_entry(connection_struct *conn,
/*******************************************************************
Unlock a hash bucket entry.
******************************************************************/
+
void unlock_share_entry(connection_struct *conn,
SMB_DEV_T dev, SMB_INO_T inode)
{
tdb_chainunlock(tdb, locking_key(dev, inode));
}
-
/*******************************************************************
Lock a hash bucket entry. use a fsp for convenience
******************************************************************/
+
BOOL lock_share_entry_fsp(files_struct *fsp)
{
return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
@@ -389,6 +398,7 @@ BOOL lock_share_entry_fsp(files_struct *fsp)
/*******************************************************************
Unlock a hash bucket entry.
******************************************************************/
+
void unlock_share_entry_fsp(files_struct *fsp)
{
tdb_chainunlock(tdb, locking_key(fsp->dev, fsp->inode));
@@ -397,6 +407,7 @@ void unlock_share_entry_fsp(files_struct *fsp)
/*******************************************************************
Get all share mode entries for a dev/inode pair.
********************************************************************/
+
int get_share_modes(connection_struct *conn,
SMB_DEV_T dev, SMB_INO_T inode,
share_mode_entry **shares)
@@ -408,96 +419,148 @@ int get_share_modes(connection_struct *conn,
*shares = NULL;
dbuf = tdb_fetch(tdb, locking_key(dev, inode));
- if (!dbuf.dptr) return 0;
+ if (!dbuf.dptr)
+ return 0;
data = (struct locking_data *)dbuf.dptr;
- ret = data->num_share_mode_entries;
+ ret = data->u.num_share_mode_entries;
if(ret)
*shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares));
free(dbuf.dptr);
- if (! *shares) return 0;
+ if (! *shares)
+ return 0;
return ret;
}
/*******************************************************************
- Del the share mode of a file for this process. Return the number
- of entries left, and a memdup'ed copy of the entry deleted.
+ Fill a share mode entry.
+********************************************************************/
+
+static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type)
+{
+ share_mode_entry *e = (share_mode_entry *)p;
+ void *x = &e->time; /* Needed to force alignment. p may not be aligned.... */
+
+ memset(e, '\0', sizeof(share_mode_entry));
+ e->pid = sys_getpid();
+ e->share_mode = fsp->share_mode;
+ e->op_port = port;
+ e->op_type = op_type;
+ memcpy(x, &fsp->open_time, sizeof(struct timeval));
+}
+
+/*******************************************************************
+ Check if two share mode entries are identical, ignoring oplock
+ and port info and also ignoring the delete on close setting.
+********************************************************************/
+
+BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
+{
+ return (e1->pid == e2->pid &&
+ (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
+ e1->time.tv_sec == e2->time.tv_sec &&
+ e1->time.tv_usec == e2->time.tv_usec );
+}
+
+/*******************************************************************
+ Delete a specific share mode. Return the number
+ of entries left, and a memdup'ed copy of the entry deleted (if required).
+ Ignore if no entry deleted.
********************************************************************/
-size_t del_share_mode(files_struct *fsp, share_mode_entry **ppse)
+ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
+ share_mode_entry *entry, share_mode_entry **ppse)
{
TDB_DATA dbuf;
struct locking_data *data;
int i, del_count=0;
share_mode_entry *shares;
- pid_t pid = sys_getpid();
- size_t count;
+ ssize_t count = 0;
- *ppse = NULL;
+ if (ppse)
+ *ppse = NULL;
/* read in the existing share modes */
- dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
- if (!dbuf.dptr) return 0;
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
+ if (!dbuf.dptr)
+ return -1;
data = (struct locking_data *)dbuf.dptr;
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
- /* find any with our pid and delete it by overwriting with the rest of the data
- from the record */
- for (i=0;i<data->num_share_mode_entries;) {
- if (shares[i].pid == pid &&
- memcmp(&shares[i].time,
- &fsp->open_time,sizeof(struct timeval)) == 0) {
- *ppse = memdup(&shares[i], sizeof(*shares));
- data->num_share_mode_entries--;
+ /*
+ * Find any with this pid and delete it
+ * by overwriting with the rest of the data
+ * from the record.
+ */
+
+ DEBUG(10,("del_share_mode: num_share_modes = %d\n", data->u.num_share_mode_entries ));
+
+ for (i=0;i<data->u.num_share_mode_entries;) {
+ if (share_modes_identical(&shares[i], entry)) {
+ if (ppse)
+ *ppse = memdup(&shares[i], sizeof(*shares));
+ data->u.num_share_mode_entries--;
memmove(&shares[i], &shares[i+1],
dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
del_count++;
+
+ DEBUG(10,("del_share_mode: deleting entry %d\n", i ));
+
} else {
i++;
}
}
- /* the record has shrunk a bit */
- dbuf.dsize -= del_count * sizeof(*shares);
+ if (del_count) {
+ /* the record may have shrunk a bit */
+ dbuf.dsize -= del_count * sizeof(*shares);
- count = data->num_share_mode_entries;
+ count = (ssize_t)data->u.num_share_mode_entries;
- /* store it back in the database */
- if (data->num_share_mode_entries == 0) {
- tdb_delete(tdb, locking_key_fsp(fsp));
- } else {
- tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE);
+ /* store it back in the database */
+ if (data->u.num_share_mode_entries == 0) {
+ if (tdb_delete(tdb, locking_key(dev, inode)) == -1)
+ count = -1;
+ } else {
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1)
+ count = -1;
+ }
}
-
free(dbuf.dptr);
return count;
}
/*******************************************************************
-fill a share mode entry
+ Del the share mode of a file for this process. Return the number
+ of entries left, and a memdup'ed copy of the entry deleted.
********************************************************************/
-static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type)
+
+ssize_t del_share_mode(files_struct *fsp, share_mode_entry **ppse)
{
- share_mode_entry *e = (share_mode_entry *)p;
- e->pid = sys_getpid();
- e->share_mode = fsp->share_mode;
- e->op_port = port;
- e->op_type = op_type;
- memcpy((char *)&e->time, (char *)&fsp->open_time, sizeof(struct timeval));
+ share_mode_entry entry;
+
+ /*
+ * Fake up a share_mode_entry for comparisons.
+ */
+
+ fill_share_mode((char *)&entry, fsp, 0, 0);
+ return del_share_entry(fsp->dev, fsp->inode, &entry, ppse);
}
/*******************************************************************
Set the share mode of a file. Return False on fail, True on success.
********************************************************************/
+
BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
{
TDB_DATA dbuf;
struct locking_data *data;
char *p=NULL;
int size;
+ BOOL ret = True;
/* read in the existing share modes if any */
dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
@@ -511,23 +574,28 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
size = sizeof(*data) + sizeof(share_mode_entry) + strlen(fname) + 1;
p = (char *)malloc(size);
+ if (!p)
+ return False;
data = (struct locking_data *)p;
- data->num_share_mode_entries = 1;
+ data->u.num_share_mode_entries = 1;
pstrcpy(p + sizeof(*data) + sizeof(share_mode_entry), fname);
fill_share_mode(p + sizeof(*data), fsp, port, op_type);
dbuf.dptr = p;
dbuf.dsize = size;
- tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE);
+ if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
+ ret = False;
free(p);
- return True;
+ return ret;
}
/* we're adding to an existing entry - this is a bit fiddly */
data = (struct locking_data *)dbuf.dptr;
- data->num_share_mode_entries++;
+ data->u.num_share_mode_entries++;
size = dbuf.dsize + sizeof(share_mode_entry);
p = malloc(size);
+ if (!p)
+ return False;
memcpy(p, dbuf.dptr, sizeof(*data));
fill_share_mode(p + sizeof(*data), fsp, port, op_type);
memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data),
@@ -535,16 +603,17 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
free(dbuf.dptr);
dbuf.dptr = p;
dbuf.dsize = size;
- tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE);
+ if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
+ ret = False;
free(p);
- return True;
+ return ret;
}
-
/*******************************************************************
-a generic in-place modification call for share mode entries
+ A generic in-place modification call for share mode entries.
********************************************************************/
-static BOOL mod_share_mode(files_struct *fsp,
+
+static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry,
void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
void *param)
{
@@ -552,33 +621,32 @@ static BOOL mod_share_mode(files_struct *fsp,
struct locking_data *data;
int i;
share_mode_entry *shares;
- pid_t pid = sys_getpid();
- int need_store=0;
+ BOOL need_store=False;
/* read in the existing share modes */
- dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
- if (!dbuf.dptr) return False;
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
+ if (!dbuf.dptr)
+ return False;
data = (struct locking_data *)dbuf.dptr;
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
/* find any with our pid and call the supplied function */
- for (i=0;i<data->num_share_mode_entries;i++) {
- if (pid == shares[i].pid &&
- shares[i].share_mode == fsp->share_mode &&
- memcmp(&shares[i].time,
- &fsp->open_time,sizeof(struct timeval)) == 0) {
- mod_fn(&shares[i], fsp->dev, fsp->inode, param);
- need_store=1;
+ for (i=0;i<data->u.num_share_mode_entries;i++) {
+ if (share_modes_identical(entry, &shares[i])) {
+ mod_fn(&shares[i], dev, inode, param);
+ need_store=True;
}
}
/* if the mod fn was called then store it back */
if (need_store) {
- if (data->num_share_mode_entries == 0) {
- tdb_delete(tdb, locking_key_fsp(fsp));
+ if (data->u.num_share_mode_entries == 0) {
+ if (tdb_delete(tdb, locking_key(dev, inode)) == -1)
+ need_store = False;
} else {
- tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE);
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1)
+ need_store = False;
}
}
@@ -586,11 +654,11 @@ static BOOL mod_share_mode(files_struct *fsp,
return need_store;
}
-
/*******************************************************************
Static function that actually does the work for the generic function
below.
********************************************************************/
+
static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
void *param)
{
@@ -604,15 +672,22 @@ static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_I
/*******************************************************************
Remove an oplock port and mode entry from a share mode.
********************************************************************/
+
BOOL remove_share_oplock(files_struct *fsp)
{
- return mod_share_mode(fsp, remove_share_oplock_fn, NULL);
+ share_mode_entry entry;
+ /*
+ * Fake up an entry for comparisons...
+ */
+ fill_share_mode((char *)&entry, fsp, 0, 0);
+ return mod_share_mode(fsp->dev, fsp->inode, &entry, remove_share_oplock_fn, NULL);
}
/*******************************************************************
Static function that actually does the work for the generic function
below.
********************************************************************/
+
static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
void *param)
{
@@ -624,9 +699,15 @@ static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SM
/*******************************************************************
Downgrade a oplock type from exclusive to level II.
********************************************************************/
+
BOOL downgrade_share_oplock(files_struct *fsp)
{
- return mod_share_mode(fsp, downgrade_share_oplock_fn, NULL);
+ share_mode_entry entry;
+ /*
+ * Fake up an entry for comparisons...
+ */
+ fill_share_mode((char *)&entry, fsp, 0, 0);
+ return mod_share_mode(fsp->dev, fsp->inode, &entry, downgrade_share_oplock_fn, NULL);
}
/*******************************************************************
@@ -643,33 +724,36 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
/* read in the existing share modes */
dbuf = tdb_fetch(tdb, locking_key(dev, inode));
- if (!dbuf.dptr) return False;
+ if (!dbuf.dptr)
+ return False;
data = (struct locking_data *)dbuf.dptr;
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
/* Set/Unset the delete on close element. */
- for (i=0;i<data->num_share_mode_entries;i++,shares++) {
+ for (i=0;i<data->u.num_share_mode_entries;i++,shares++) {
shares->share_mode = (delete_on_close ?
(shares->share_mode | DELETE_ON_CLOSE_FLAG) :
(shares->share_mode & ~DELETE_ON_CLOSE_FLAG) );
}
/* store it back */
- if (data->num_share_mode_entries) {
- if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1)
+ if (data->u.num_share_mode_entries) {
+ if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) {
+ free(dbuf.dptr);
return False;
+ }
}
free(dbuf.dptr);
return True;
}
-
/****************************************************************************
-traverse the whole database with this function, calling traverse_callback
-on each share mode
+ Traverse the whole database with this function, calling traverse_callback
+ on each share mode
****************************************************************************/
+
static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
void* state)
{
@@ -682,9 +766,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
data = (struct locking_data *)dbuf.dptr;
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
- name = dbuf.dptr + sizeof(*data) + data->num_share_mode_entries*sizeof(*shares);
+ name = dbuf.dptr + sizeof(*data) + data->u.num_share_mode_entries*sizeof(*shares);
- for (i=0;i<data->num_share_mode_entries;i++) {
+ for (i=0;i<data->u.num_share_mode_entries;i++) {
traverse_callback(&shares[i], name);
}
return 0;
@@ -694,8 +778,10 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
Call the specified function on each entry under management by the
share mode system.
********************************************************************/
+
int share_mode_forall(SHAREMODE_FN(fn))
{
- if (!tdb) return 0;
+ if (!tdb)
+ return 0;
return tdb_traverse(tdb, traverse_fn, (void*)fn);
}
diff --git a/source/locking/posix.c b/source/locking/posix.c
index 2a8a7aacd73..eb5e4b6460c 100644
--- a/source/locking/posix.c
+++ b/source/locking/posix.c
@@ -98,16 +98,21 @@ static BOOL add_fd_to_close_entry(files_struct *fsp)
{
TDB_DATA kbuf = locking_key_fsp(fsp);
TDB_DATA dbuf;
+ char *tp;
dbuf.dptr = NULL;
dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- dbuf.dptr = Realloc(dbuf.dptr, dbuf.dsize + sizeof(int));
- if (!dbuf.dptr) {
+ tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(int));
+ if (!tp) {
DEBUG(0,("add_fd_to_close_entry: Realloc fail !\n"));
+ if (dbuf.dptr)
+ free(dbuf.dptr);
return False;
- }
+ } else
+ dbuf.dptr = tp;
+
memcpy(dbuf.dptr + dbuf.dsize, &fsp->fd, sizeof(int));
dbuf.dsize += sizeof(int);
@@ -354,6 +359,7 @@ static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T s
TDB_DATA kbuf = locking_key_fsp(fsp);
TDB_DATA dbuf;
struct posix_lock pl;
+ char *tp;
dbuf.dptr = NULL;
@@ -370,11 +376,12 @@ static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T s
pl.size = size;
pl.lock_type = lock_type;
- dbuf.dptr = Realloc(dbuf.dptr, dbuf.dsize + sizeof(pl));
- if (!dbuf.dptr) {
+ tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(pl));
+ if (!tp) {
DEBUG(0,("add_posix_lock_entry: Realloc fail !\n"));
goto fail;
- }
+ } else
+ dbuf.dptr = tp;
memcpy(dbuf.dptr + dbuf.dsize, &pl, sizeof(pl));
dbuf.dsize += sizeof(pl);
@@ -575,6 +582,17 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
#endif /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
/*
+ * POSIX locks of length zero mean lock to end-of-file.
+ * Win32 locks of length zero are point probes. Ignore
+ * any Win32 locks of length zero. JRA.
+ */
+
+ if (count == (SMB_OFF_T)0) {
+ DEBUG(10,("posix_lock_in_range: count = 0, ignoring.\n"));
+ return False;
+ }
+
+ /*
* If the given offset was > max_positive_lock_offset then we cannot map this at all
* ignore this lock.
*/
@@ -632,38 +650,6 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
}
/****************************************************************************
- Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
-****************************************************************************/
-
-uint32 map_lock_offset(uint32 high, uint32 low)
-{
- unsigned int i;
- uint32 mask = 0;
- uint32 highcopy = high;
-
- /*
- * Try and find out how many significant bits there are in high.
- */
-
- for(i = 0; highcopy; i++)
- highcopy >>= 1;
-
- /*
- * We use 31 bits not 32 here as POSIX
- * lock offsets may not be negative.
- */
-
- mask = (~0) << (31 - i);
-
- if(low & mask)
- return 0; /* Fail. */
-
- high <<= (31 - i);
-
- return (high|low);
-}
-
-/****************************************************************************
Actual function that does POSIX locks. Copes with 64 -> 32 bit cruft and
broken NFS implementations.
****************************************************************************/
@@ -673,80 +659,39 @@ static BOOL posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OF
int ret;
struct connection_struct *conn = fsp->conn;
-#if defined(LARGE_SMB_OFF_T)
- /*
- * In the 64 bit locking case we store the original
- * values in case we have to map to a 32 bit lock on
- * a filesystem that doesn't support 64 bit locks.
- */
- SMB_OFF_T orig_offset = offset;
- SMB_OFF_T orig_count = count;
-#endif /* LARGE_SMB_OFF_T */
-
DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fd,op,(double)offset,(double)count,type));
ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
- if (!ret && (errno == EFBIG)) {
- if( DEBUGLVL( 0 )) {
- dbgtext("posix_fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
- dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
- dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
- }
- /* 32 bit NFS file system, retry with smaller offset */
- errno = 0;
- count &= 0x7fffffff;
- ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
- }
+ if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno == EINVAL))) {
- /* A lock query - just return. */
- if (op == SMB_F_GETLK)
- return ret;
+ DEBUG(0,("posix_fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n",
+ (double)offset,(double)count));
+ DEBUG(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno)));
+ DEBUG(0,("on 32 bit NFS mounted file systems.\n"));
- /* A lock set or unset. */
- if (!ret) {
- DEBUG(3,("posix_fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
- (double)offset,(double)count,op,type,strerror(errno)));
+ /*
+ * If the offset is > 0x7FFFFFFF then this will cause problems on
+ * 32 bit NFS mounted filesystems. Just ignore it.
+ */
- /* Perhaps it doesn't support this sort of locking ? */
- if (errno == EINVAL) {
-#if defined(LARGE_SMB_OFF_T)
- {
- /*
- * Ok - if we get here then we have a 64 bit lock request
- * that has returned EINVAL. Try and map to 31 bits for offset
- * and length and try again. This may happen if a filesystem
- * doesn't support 64 bit offsets (efs/ufs) although the underlying
- * OS does.
- */
- uint32 off_low = (orig_offset & 0xFFFFFFFF);
- uint32 off_high = ((orig_offset >> 32) & 0xFFFFFFFF);
-
- count = (orig_count & 0x7FFFFFFF);
- offset = (SMB_OFF_T)map_lock_offset(off_high, off_low);
- ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
- if (!ret) {
- if (errno == EINVAL) {
- DEBUG(3,("posix_fcntl_lock: locking not supported? returning True\n"));
- return(True);
- }
- return False;
- }
- DEBUG(3,("posix_fcntl_lock: 64 -> 32 bit modified lock call successful\n"));
- return True;
- }
-#else /* LARGE_SMB_OFF_T */
- DEBUG(3,("locking not supported? returning True\n"));
- return(True);
-#endif /* LARGE_SMB_OFF_T */
+ if (offset & ~((SMB_OFF_T)0x7fffffff)) {
+ DEBUG(0,("Offset greater than 31 bits. Returning success.\n"));
+ return True;
}
- return(False);
+ if (count & ~((SMB_OFF_T)0x7fffffff)) {
+ /* 32 bit NFS file system, retry with smaller offset */
+ DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
+ errno = 0;
+ count &= 0x7fffffff;
+ ret = conn->vfs_ops.lock(fsp,fsp->fd,op,offset,count,type);
+ }
}
- DEBUG(8,("posix_fcntl_lock: Lock call successful\n"));
+ DEBUG(8,("posix_fcntl_lock: Lock call %s\n", ret ? "successful" : "failed"));
- return(True);
+ return ret;
}
/****************************************************************************
@@ -1123,8 +1068,8 @@ BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_cou
posix_lock_type_name(posix_lock_type), (double)offset, (double)count ));
if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,posix_lock_type)) {
- DEBUG(5,("set_posix_lock: Lock fail !: Type = %s: offset = %.0f, count = %.0f\n",
- posix_lock_type_name(posix_lock_type), (double)offset, (double)count ));
+ DEBUG(5,("set_posix_lock: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n",
+ posix_lock_type_name(posix_lock_type), (double)offset, (double)count, strerror(errno) ));
ret = False;
break;
}
@@ -1206,7 +1151,7 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u
if (num_overlapped_entries > 0 && deleted_lock.lock_type == F_WRLCK) {
if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_RDLCK)) {
- DEBUG(0,("release_posix_lock: downgrade of lock failed !\n"));
+ DEBUG(0,("release_posix_lock: downgrade of lock failed with error %s !\n", strerror(errno) ));
return False;
}
}
diff --git a/source/msdfs/msdfs.c b/source/msdfs/msdfs.c
index b2530a3d7f2..606977d8c42 100644
--- a/source/msdfs/msdfs.c
+++ b/source/msdfs/msdfs.c
@@ -17,6 +17,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: msdfs.c,v 1.10.4.3.2.2 2001/10/11 09:33:10 jra Exp $
*/
#include "includes.h"
@@ -28,18 +30,7 @@ extern uint32 global_client_caps;
#ifdef WITH_MSDFS
/**********************************************************************
- Create a tcon relative path from a dfs_path structure
- **********************************************************************/
-
-static void create_nondfs_path(char* pathname, struct dfs_path* pdp)
-{
- pstrcpy(pathname,pdp->volumename);
- pstrcat(pathname,"\\");
- pstrcat(pathname,pdp->restofthepath);
-}
-
-/**********************************************************************
- Parse the pathname of the form \hostname\service\volume\restofthepath
+ Parse the pathname of the form \hostname\service\reqpath
into the dfs_path structure
**********************************************************************/
@@ -70,26 +61,22 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
p = strchr(temp,'\\');
if(p == NULL) {
pstrcpy(pdp->servicename,temp);
+ pdp->reqpath[0] = '\0';
return True;
}
*p = '\0';
pstrcpy(pdp->servicename,temp);
DEBUG(10,("servicename: %s\n",pdp->servicename));
- /* parse out volumename */
- temp = p+1;
- p = strchr(temp,'\\');
- if(p == NULL) {
- pstrcpy(pdp->volumename,temp);
- return True;
+ /* rest is reqpath */
+ pstrcpy(pdp->reqpath, p+1);
+ p = pdp->reqpath;
+ while (*p) {
+ if (*p == '\\') *p = '/';
+ p++;
}
- *p = '\0';
- pstrcpy(pdp->volumename,temp);
- DEBUG(10,("volumename: %s\n",pdp->volumename));
- /* remaining path .. */
- pstrcpy(pdp->restofthepath,p+1);
- DEBUG(10,("rest of the path: %s\n",pdp->restofthepath));
+ DEBUG(10,("rest of the path: %s\n",pdp->reqpath));
return True;
}
@@ -97,11 +84,11 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
Fake up a connection struct for the VFS layer.
*********************************************************/
-static BOOL create_conn_struct( connection_struct *conn, int snum, char *path)
+static BOOL create_conn_struct( connection_struct *conn, int snum)
{
ZERO_STRUCTP(conn);
conn->service = snum;
- conn->connectpath = path;
+ conn->connectpath = lp_pathname(snum);
if (!vfs_init(conn)) {
DEBUG(0,("create_conn_struct: vfs init failed.\n"));
@@ -110,66 +97,13 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path)
return True;
}
-/**********************************************************************
- Forms a valid Unix pathname from the junction
- **********************************************************************/
-
-static BOOL form_path_from_junction(struct junction_map* jn, char* path, int max_pathlen,
- connection_struct *conn)
-{
- int snum;
-
- if(!path || !jn)
- return False;
-
- snum = lp_servicenumber(jn->service_name);
- if(snum < 0)
- return False;
-
- safe_strcpy(path, lp_pathname(snum), max_pathlen-1);
- safe_strcat(path, "/", max_pathlen-1);
- strlower(jn->volume_name);
- safe_strcat(path, jn->volume_name, max_pathlen-1);
-
- if (!create_conn_struct(conn, snum, path))
- return False;
-
- return True;
-}
-
-/**********************************************************************
- Creates a junction structure from the Dfs pathname
- **********************************************************************/
-
-BOOL create_junction(char* pathname, struct junction_map* jn)
-{
- struct dfs_path dp;
-
- parse_dfs_path(pathname,&dp);
-
- /* check if path is dfs : check hostname is the first token */
- if(global_myname && (strcasecmp(global_myname,dp.hostname)!=0)) {
- DEBUG(4,("create_junction: Invalid hostname %s in dfs path %s\n", dp.hostname, pathname));
- return False;
- }
-
- /* Check for a non-DFS share */
- if(!lp_msdfs_root(lp_servicenumber(dp.servicename))) {
- DEBUG(4,("create_junction: %s is not an msdfs root.\n", dp.servicename));
- return False;
- }
-
- pstrcpy(jn->service_name,dp.servicename);
- pstrcpy(jn->volume_name,dp.volumename);
- return True;
-}
/**********************************************************************
Parse the contents of a symlink to verify if it is an msdfs referral
A valid referral is of the form: msdfs:server1\share1,server2\share2
**********************************************************************/
-
-static BOOL parse_symlink(char* buf,struct referral** preflist, int* refcount)
+static inline BOOL parse_symlink(char* buf,struct referral** preflist,
+ int* refcount)
{
pstring temp;
char* prot;
@@ -181,11 +115,11 @@ static BOOL parse_symlink(char* buf,struct referral** preflist, int* refcount)
prot = strtok(temp,":");
- if(!strequal(prot, "msdfs"))
+ if (!strequal(prot, "msdfs"))
return False;
- /* It's an msdfs referral */
- if(!preflist)
+ /* No referral list requested. Just yes/no. */
+ if (!preflist)
return True;
/* parse out the alternate paths */
@@ -199,7 +133,7 @@ static BOOL parse_symlink(char* buf,struct referral** preflist, int* refcount)
DEBUG(0,("parse_symlink: Malloc failed!\n"));
return False;
}
-
+
for(i=0;i<count;i++) {
/* replace / in the alternate path by a \ */
char* p = strchr(alt_path[i],'/');
@@ -222,141 +156,255 @@ static BOOL parse_symlink(char* buf,struct referral** preflist, int* refcount)
/**********************************************************************
Returns true if the unix path is a valid msdfs symlink
**********************************************************************/
-
-BOOL is_msdfs_link(connection_struct* conn, char* path)
+BOOL is_msdfs_link(connection_struct* conn, char* path,
+ struct referral** reflistp, int* refcnt)
{
SMB_STRUCT_STAT st;
pstring referral;
int referral_len = 0;
- if(!path || !conn)
+ if (!path || !conn)
return False;
strlower(path);
- if(conn->vfs_ops.lstat(conn,dos_to_unix(path,False),&st) != 0) {
+ if (conn->vfs_ops.lstat(conn,dos_to_unix(path,False),&st) != 0) {
DEBUG(5,("is_msdfs_link: %s does not exist.\n",path));
return False;
}
- if(S_ISLNK(st.st_mode)) {
+ if (S_ISLNK(st.st_mode)) {
/* open the link and read it */
- referral_len = conn->vfs_ops.readlink(conn, path, referral, sizeof(pstring));
- if(referral_len == -1)
+ referral_len = conn->vfs_ops.readlink(conn, path, referral,
+ sizeof(pstring));
+ if (referral_len == -1) {
DEBUG(0,("is_msdfs_link: Error reading msdfs link %s: %s\n", path, strerror(errno)));
+ return False;
+ }
referral[referral_len] = '\0';
DEBUG(5,("is_msdfs_link: %s -> %s\n",path,referral));
- if(parse_symlink(referral, NULL, NULL))
+ if (parse_symlink(referral, reflistp, refcnt))
return True;
}
return False;
}
-/**********************************************************************
- Fills in the junction_map struct with the referrals from the
- symbolic link
- **********************************************************************/
-
-BOOL get_referred_path(struct junction_map* junction)
-{
- pstring path;
- pstring buf;
- SMB_STRUCT_STAT st;
- connection_struct conns;
- connection_struct *conn = &conns;
+/*****************************************************************
+ Used by other functions to decide if a dfs path is remote,
+and to get the list of referred locations for that remote path.
- if(!form_path_from_junction(junction, path, sizeof(path), conn))
+findfirst_flag: For findfirsts, dfs links themselves are not
+redirected, but paths beyond the links are. For normal smb calls,
+even dfs links need to be redirected.
+
+self_referralp: clients expect a dfs referral for the same share when
+they request referrals for dfs roots on a server.
+
+consumedcntp: how much of the dfs path is being redirected. the client
+should try the remaining path on the redirected server.
+*****************************************************************/
+static BOOL resolve_dfs_path(char* dfspath, struct dfs_path* dp,
+ connection_struct* conn,
+ BOOL findfirst_flag,
+ struct referral** reflistpp, int* refcntp,
+ BOOL* self_referralp, int* consumedcntp)
+{
+ fstring localpath;
+
+ char *p;
+ fstring reqpath;
+
+ if (!dp || !conn) {
+ DEBUG(1,("resolve_dfs_path: NULL dfs_path* or NULL connection_struct*!\n"));
return False;
+ }
- DEBUG(5,("get_referred_path: lstat target: %s\n", path));
-
- if(conn->vfs_ops.lstat(conn,dos_to_unix(path, False),&st) != 0) {
- DEBUG(5,("get_referred_path: %s does not exist.\n",path));
+ if (dp->reqpath[0] == '\0') {
+ if (self_referralp) {
+ DEBUG(6,("resolve_dfs_path: self-referral. returning False\n"));
+ *self_referralp = True;
+ }
return False;
}
-
- if(S_ISLNK(st.st_mode)) {
- /* open the link and read it to get the dfs referral */
- int linkcnt = 0;
- linkcnt = conn->vfs_ops.readlink(conn, path, buf, sizeof(buf));
- buf[linkcnt] = '\0';
- DEBUG(5,("get_referred_path: Referral: %s\n",buf));
- if(parse_symlink(buf, &junction->referral_list, &junction->referral_count))
+
+ /* check if need to redirect */
+ fstrcpy(localpath, conn->connectpath);
+ fstrcat(localpath, "/");
+ fstrcat(localpath, dp->reqpath);
+ if (is_msdfs_link(conn, localpath, reflistpp, refcntp)) {
+ if (findfirst_flag) {
+ DEBUG(6,("resolve_dfs_path (FindFirst) No redirection "
+ "for dfs link %s.\n", dfspath));
+ return False;
+ } else {
+ DEBUG(6,("resolve_dfs_path: %s resolves to a valid Dfs link.\n",
+ dfspath));
+ if (consumedcntp)
+ *consumedcntp = strlen(dfspath);
+ return True;
+ }
+ }
+
+ /* also redirect if the parent directory is a dfs link */
+ fstrcpy(reqpath, dp->reqpath);
+ p = strrchr(reqpath, '/');
+ if (p) {
+ *p = '\0';
+ fstrcpy(localpath, conn->connectpath);
+ fstrcat(localpath, "/");
+ fstrcat(localpath, reqpath);
+ if (is_msdfs_link(conn, localpath, reflistpp, refcntp)) {
+ DEBUG(4, ("resolve_dfs_path: Redirecting %s because parent %s is dfs link\n", dfspath, localpath));
+
+ /* To find the path consumed, we truncate the original
+ DFS pathname passed to use to remove the last
+ component. The length of the resulting string is
+ the path consumed
+ */
+ if (consumedcntp) {
+ char *q;
+ pstring buf;
+ safe_strcpy(buf, dfspath, sizeof(buf));
+ trim_string(buf, NULL, "\\");
+ q = strrchr(buf, '\\');
+ if (q)
+ *q = '\0';
+ *consumedcntp = strlen(buf);
+ DEBUG(10, ("resolve_dfs_path: Path consumed: %d\n", *consumedcntp));
+ }
+
return True;
+ }
}
+
return False;
}
-/**************************************************************
-Decides if given pathname is Dfs and if it should be redirected
-Converts pathname to non-dfs format if Dfs redirection not required
-**************************************************************/
-
-BOOL dfs_redirect(char* pathname, connection_struct* conn)
+/*****************************************************************
+ Decides if a dfs pathname should be redirected or not.
+ If not, the pathname is converted to a tcon-relative local unix path
+*****************************************************************/
+BOOL dfs_redirect(char* pathname, connection_struct* conn,
+ BOOL findfirst_flag)
{
struct dfs_path dp;
- pstring temp;
- fstring path;
-
- pstrcpy(temp,pathname);
-
- if(!lp_msdfs_root(SNUM(conn)) )
+
+ if (!conn || !pathname)
return False;
- parse_dfs_path(pathname,&dp);
+ parse_dfs_path(pathname, &dp);
- if(global_myname && (strcasecmp(global_myname,dp.hostname)!=0))
+ /* if dfs pathname for a non-dfs share, convert to tcon-relative
+ path and return false */
+ if (!lp_msdfs_root(SNUM(conn))) {
+ fstrcpy(pathname, dp.reqpath);
+ return False;
+ }
+
+ if (strcasecmp(dp.servicename, lp_servicename(SNUM(conn)) ) != 0)
return False;
- /* check if need to redirect */
- fstrcpy(path, conn->connectpath);
- fstrcat(path, "/");
- fstrcat(path, dp.volumename);
- if(is_msdfs_link(conn, path)) {
- DEBUG(4,("dfs_redirect: Redirecting %s\n",temp));
+ if (resolve_dfs_path(pathname, &dp, conn, findfirst_flag,
+ NULL, NULL, NULL, NULL)) {
+ DEBUG(3,("dfs_redirect: Redirecting %s\n", pathname));
return True;
} else {
- create_nondfs_path(pathname,&dp);
- DEBUG(4,("dfs_redirect: Not redirecting %s. Converted to non-dfs pathname \'%s\'\n",
- temp,pathname));
+ DEBUG(3,("dfs_redirect: Not redirecting %s.\n", pathname));
+
+ /* Form non-dfs tcon-relative path */
+ fstrcpy(pathname, dp.reqpath);
+ DEBUG(3,("dfs_redirect: Path converted to non-dfs path %s\n",
+ pathname));
return False;
}
+ /* never reached */
+ return False;
}
-/*
- Special DFS redirect call for findfirst's.
- If the findfirst is for the dfs junction, then no redirection,
- if it is for the underlying directory contents, redirect.
- */
-
-BOOL dfs_findfirst_redirect(char* pathname, connection_struct* conn)
+/**********************************************************************
+ Gets valid referrals for a dfs path and fills up the
+ junction_map structure
+ **********************************************************************/
+BOOL get_referred_path(char *pathname, struct junction_map* jn,
+ int* consumedcntp, BOOL* self_referralp)
{
struct dfs_path dp;
-
- pstring temp;
- pstrcpy(temp,pathname);
+ struct connection_struct conns;
+ struct connection_struct* conn = &conns;
+ int snum;
+
+ BOOL self_referral = False;
- /* Is the path Dfs-redirectable? */
- if(!dfs_redirect(temp,conn)) {
- pstrcpy(pathname,temp);
+ if (!pathname || !jn)
+ return False;
+
+ if (self_referralp)
+ *self_referralp = False;
+ else
+ self_referralp = &self_referral;
+
+ parse_dfs_path(pathname, &dp);
+
+ /* Verify hostname in path */
+ if (global_myname && (strcasecmp(global_myname, dp.hostname) != 0)) {
+ DEBUG(3, ("get_referred_path: Invalid hostname %s in path %s\n",
+ dp.hostname, pathname));
return False;
}
- parse_dfs_path(pathname,&dp);
- DEBUG(8,("dfs_findfirst_redirect: path %s is in Dfs. dp.restofthepath=.%s.\n",
- pathname,dp.restofthepath));
- if(!(*(dp.restofthepath))) {
- create_nondfs_path(pathname,&dp);
+ pstrcpy(jn->service_name, dp.servicename);
+ pstrcpy(jn->volume_name, dp.reqpath);
+
+ /* Verify the share is a dfs root */
+ snum = lp_servicenumber(jn->service_name);
+ if(snum < 0)
+ return False;
+
+ if (!create_conn_struct(conn, snum))
+ return False;
+
+ if (!lp_msdfs_root(SNUM(conn))) {
+ DEBUG(3,("get_referred_path: .%s. in dfs path %s is not a dfs root.\n",
+ dp.servicename, pathname));
return False;
}
+ /* If not remote & not a self referral, return False */
+ if (!resolve_dfs_path(pathname, &dp, conn, False,
+ &jn->referral_list, &jn->referral_count,
+ self_referralp, consumedcntp)) {
+ if (!*self_referralp) {
+ DEBUG(3,("get_referred_path: No valid referrals for path %s\n", pathname));
+ return False;
+ }
+ }
+
+ /* if self_referral, fill up the junction map */
+ if (*self_referralp) {
+ struct referral* ref;
+ jn->referral_count = 1;
+ if((ref = (struct referral*) malloc(sizeof(struct referral)))
+ == NULL) {
+ DEBUG(0,("malloc failed for referral\n"));
+ return False;
+ }
+
+ pstrcpy(ref->alternate_path,pathname);
+ ref->proximity = 0;
+ ref->ttl = REFERRAL_TTL;
+ jn->referral_list = ref;
+ if (consumedcntp)
+ *consumedcntp = strlen(pathname);
+ }
+
return True;
}
static int setup_ver2_dfs_referral(char* pathname, char** ppdata,
struct junction_map* junction,
+ int consumedcnt,
BOOL self_referral)
{
char* pdata = *ppdata;
@@ -398,18 +446,19 @@ static int setup_ver2_dfs_referral(char* pathname, char** ppdata,
/* add the unexplained 0x16 bytes */
reply_size += 0x16;
- pdata = *ppdata = Realloc(pdata,reply_size);
+ pdata = Realloc(pdata,reply_size);
if(pdata == NULL) {
DEBUG(0,("malloc failed for Realloc!\n"));
return -1;
- }
+ } else
+ *ppdata = pdata;
/* copy in the dfs requested paths.. required for offset calculations */
memcpy(pdata+uni_reqpathoffset1,uni_requestedpath,requestedpathlen);
memcpy(pdata+uni_reqpathoffset2,uni_requestedpath,requestedpathlen);
/* create the header */
- SSVAL(pdata,0,requestedpathlen-2); /* path consumed */
+ SSVAL(pdata,0,consumedcnt * 2); /* path consumed */
SSVAL(pdata,2,junction->referral_count); /* number of referral in this pkt */
if(self_referral)
SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER);
@@ -443,12 +492,12 @@ static int setup_ver2_dfs_referral(char* pathname, char** ppdata,
}
/* add in the unexplained 22 (0x16) bytes at the end */
memset(pdata+uni_curroffset,'\0',0x16);
- free(junction->referral_list);
return reply_size;
}
static int setup_ver3_dfs_referral(char* pathname, char** ppdata,
struct junction_map* junction,
+ int consumedcnt,
BOOL self_referral)
{
char* pdata = *ppdata;
@@ -476,15 +525,16 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata,
reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2;
}
- pdata = *ppdata = Realloc(pdata,reply_size);
+ pdata = Realloc(pdata,reply_size);
if(pdata == NULL) {
DEBUG(0,("version3 referral setup: malloc failed for Realloc!\n"));
return -1;
- }
-
+ } else
+ *ppdata = pdata;
+
/* create the header */
- SSVAL(pdata,0,reqpathlen-2); /* path consumed */
- SSVAL(pdata,2,junction->referral_count); /* number of referral in this pkt */
+ SSVAL(pdata,0,consumedcnt * 2); /* path consumed */
+ SSVAL(pdata,2,junction->referral_count); /* number of referral */
if(self_referral)
SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER);
else
@@ -520,7 +570,6 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata,
uni_curroffset += unilen;
offset += VERSION3_REFERRAL_SIZE;
}
- free(junction->referral_list);
return reply_size;
}
@@ -531,34 +580,24 @@ static int setup_ver3_dfs_referral(char* pathname, char** ppdata,
int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
{
struct junction_map junction;
-
- BOOL self_referral;
-
+ int consumedcnt;
+ BOOL self_referral = False;
+ pstring buf;
int reply_size = 0;
ZERO_STRUCT(junction);
- if(!create_junction(pathname, &junction))
+ /* get the junction entry */
+ if (!pathname)
return -1;
- /* get the junction entry */
- if(!get_referred_path(&junction)) {
-
- /* refer the same pathname, create a standard referral struct */
- struct referral* ref;
- self_referral = True;
- junction.referral_count = 1;
- if((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) {
- DEBUG(0,("malloc failed for referral\n"));
- return -1;
- }
-
- pstrcpy(ref->alternate_path,pathname);
- ref->proximity = 0;
- ref->ttl = REFERRAL_TTL;
- junction.referral_list = ref;
- } else {
- self_referral = False;
+ safe_strcpy(buf, pathname, sizeof(buf));
+ if (!get_referred_path(buf, &junction, &consumedcnt,
+ &self_referral))
+ return -1;
+
+ if (!self_referral)
+ {
if( DEBUGLVL( 3 ) ) {
int i=0;
dbgtext("setup_dfs_referral: Path %s to alternate path(s):",pathname);
@@ -567,7 +606,7 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
dbgtext(".\n");
}
}
-
+
/* create the referral depeding on version */
DEBUG(10,("max_referral_level :%d\n",max_referral_level));
if(max_referral_level<2 || max_referral_level>3)
@@ -576,12 +615,16 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
switch(max_referral_level) {
case 2:
{
- reply_size = setup_ver2_dfs_referral(pathname, ppdata, &junction, self_referral);
+ reply_size = setup_ver2_dfs_referral(pathname, ppdata, &junction,
+ consumedcnt, self_referral);
+ free(junction.referral_list);
break;
}
case 3:
{
- reply_size = setup_ver3_dfs_referral(pathname, ppdata, &junction, self_referral);
+ reply_size = setup_ver3_dfs_referral(pathname, ppdata, &junction,
+ consumedcnt, self_referral);
+ free(junction.referral_list);
break;
}
default:
@@ -598,19 +641,67 @@ int setup_dfs_referral(char* pathname, int max_referral_level, char** ppdata)
int dfs_path_error(char* inbuf, char* outbuf)
{
- enum remote_arch_types ra_type = get_remote_arch();
- BOOL NT_arch = ((ra_type==RA_WINNT) || (ra_type == RA_WIN2K));
- if(NT_arch && (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32)) ) {
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0,0xc0000000|NT_STATUS_PATH_NOT_COVERED));
- }
- return(ERROR(ERRSRV,ERRbadpath));
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
}
/**********************************************************************
The following functions are called by the NETDFS RPC pipe functions
**********************************************************************/
+/**********************************************************************
+ Creates a junction structure from a Dfs pathname
+ **********************************************************************/
+BOOL create_junction(char* pathname, struct junction_map* jn)
+{
+ struct dfs_path dp;
+
+ parse_dfs_path(pathname,&dp);
+
+ /* check if path is dfs : check hostname is the first token */
+ if(global_myname && (strcasecmp(global_myname,dp.hostname)!=0)) {
+ DEBUG(4,("create_junction: Invalid hostname %s in dfs path %s\n",
+ dp.hostname, pathname));
+ return False;
+ }
+
+ /* Check for a non-DFS share */
+ if(!lp_msdfs_root(lp_servicenumber(dp.servicename))) {
+ DEBUG(4,("create_junction: %s is not an msdfs root.\n",
+ dp.servicename));
+ return False;
+ }
+
+ pstrcpy(jn->service_name,dp.servicename);
+ pstrcpy(jn->volume_name,dp.reqpath);
+ return True;
+}
+
+/**********************************************************************
+ Forms a valid Unix pathname from the junction
+ **********************************************************************/
+static BOOL junction_to_local_path(struct junction_map* jn, char* path,
+ int max_pathlen, connection_struct *conn)
+{
+ int snum;
+
+ if(!path || !jn)
+ return False;
+
+ snum = lp_servicenumber(jn->service_name);
+ if(snum < 0)
+ return False;
+
+ safe_strcpy(path, lp_pathname(snum), max_pathlen-1);
+ safe_strcat(path, "/", max_pathlen-1);
+ strlower(jn->volume_name);
+ safe_strcat(path, jn->volume_name, max_pathlen-1);
+
+ if (!create_conn_struct(conn, snum))
+ return False;
+
+ return True;
+}
+
BOOL create_msdfs_link(struct junction_map* jn, BOOL exists)
{
pstring path;
@@ -618,8 +709,9 @@ BOOL create_msdfs_link(struct junction_map* jn, BOOL exists)
connection_struct conns;
connection_struct *conn = &conns;
int i=0;
+ BOOL insert_comma;
- if(!form_path_from_junction(jn, path, sizeof(path), conn))
+ if(!junction_to_local_path(jn, path, sizeof(path), conn))
return False;
/* form the msdfs_link contents */
@@ -628,13 +720,18 @@ BOOL create_msdfs_link(struct junction_map* jn, BOOL exists)
char* refpath = jn->referral_list[i].alternate_path;
trim_string(refpath, "\\", "\\");
- if(*refpath == '\0')
+ if(*refpath == '\0') {
+ if (i == 0)
+ insert_comma = False;
continue;
-
- if(i>0)
+ }
+ if (i > 0 && insert_comma)
pstrcat(msdfs_link, ",");
-
+
pstrcat(msdfs_link, refpath);
+ if (!insert_comma)
+ insert_comma = True;
+
}
DEBUG(5,("create_msdfs_link: Creating new msdfs link: %s -> %s\n", path, msdfs_link));
@@ -657,7 +754,7 @@ BOOL remove_msdfs_link(struct junction_map* jn)
connection_struct conns;
connection_struct *conn = &conns;
- if(!form_path_from_junction(jn, path, sizeof(path), conn))
+ if(!junction_to_local_path(jn, path, sizeof(path), conn))
return False;
if(conn->vfs_ops.unlink(conn, path)!=0)
@@ -685,47 +782,53 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
* Fake up a connection struct for the VFS layer.
*/
- if (!create_conn_struct(conn, snum, connect_path))
+ if (!create_conn_struct(conn, snum))
return False;
- /* form a junction for the msdfs root - convention */
- /*
- pstrpcy(jn[cnt].service_name, service_name);
+ {
+ /* form a junction for the msdfs root - convention
+ DO NOT REMOVE THIS: NT clients will not work with us
+ if this is not present
+ */
+ struct referral *ref = NULL;
+ pstring alt_path;
+ pstrcpy(jn[cnt].service_name, service_name);
jn[cnt].volume_name[0] = '\0';
jn[cnt].referral_count = 1;
-
- slprintf(alt_path,sizeof(alt_path)-1"\\\\%s\\%s", global_myname, service_name);
- jn[cnt].referral_l
- */
+
+ slprintf(alt_path,sizeof(alt_path)-1,"\\\\%s\\%s",
+ global_myname, service_name);
+ ref = jn[cnt].referral_list = (struct referral*) malloc(sizeof(struct referral));
+ if (jn[cnt].referral_list == NULL) {
+ DEBUG(0, ("Malloc failed!\n"));
+ return False;
+ }
+
+ safe_strcpy(ref->alternate_path, alt_path, sizeof(pstring));
+ ref->proximity = 0;
+ ref->ttl = REFERRAL_TTL;
+ cnt++;
+ }
dirp = conn->vfs_ops.opendir(conn, dos_to_unix(connect_path,False));
if(!dirp)
return False;
while((dname = vfs_readdirname(conn, dirp)) != NULL) {
- SMB_STRUCT_STAT st;
pstring pathreal;
- fstring buf;
- int buflen = 0;
+
pstrcpy(pathreal, connect_path);
pstrcat(pathreal, "/");
pstrcat(pathreal, dname);
- if(conn->vfs_ops.lstat(conn,pathreal,&st) != 0) {
- DEBUG(4,("lstat error for %s: %s\n",pathreal, strerror(errno)));
- continue;
- }
- if(S_ISLNK(st.st_mode)) {
- buflen = conn->vfs_ops.readlink(conn, dos_to_unix(pathreal,False), buf, sizeof(fstring));
- buf[buflen] = '\0';
- if(parse_symlink(buf, &(jn[cnt].referral_list), &(jn[cnt].referral_count))) {
- pstrcpy(jn[cnt].service_name, service_name);
- pstrcpy(jn[cnt].volume_name, dname);
- cnt++;
- }
+ if (is_msdfs_link(conn, pathreal, &(jn[cnt].referral_list),
+ &(jn[cnt].referral_count))) {
+ pstrcpy(jn[cnt].service_name, service_name);
+ pstrcpy(jn[cnt].volume_name, dname);
+ cnt++;
}
}
-
+
conn->vfs_ops.closedir(conn,dirp);
*jn_count = cnt;
return True;
@@ -754,7 +857,8 @@ int enum_msdfs_links(struct junction_map* jn)
return -1;
}
- BOOL is_msdfs_link(connection_struct* conn, char* path)
+ BOOL is_msdfs_link(connection_struct* conn, char* path,
+ struct referral** reflistpp, int* refcntp)
{
return False;
}
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 2fab8f6bc7b..3e7b2171ec0 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -732,7 +732,7 @@ static void usage(char *pname)
strupper(global_myname);
break;
case 'l':
- slprintf(debugf,sizeof(debugf)-1, "%s.nmb",optarg);
+ slprintf(debugf, sizeof(debugf)-1, "%s/log.nmbd", optarg);
break;
case 'a':
append_log = True;
@@ -776,6 +776,13 @@ static void usage(char *pname)
if ( !reload_nmbd_services(False) )
return(-1);
+#ifdef WITH_PROFILE
+ if (!profile_setup(False)) {
+ DEBUG(0,("ERROR: failed to setup profiling shared memory\n"));
+ return -1;
+ }
+#endif /* WITH_PROFILE */
+
codepage_initialise(lp_client_code_page());
if(!init_structs())
diff --git a/source/nmbd/nmbd_elections.c b/source/nmbd/nmbd_elections.c
index 522e268ae71..0fc3ab9a896 100644
--- a/source/nmbd/nmbd_elections.c
+++ b/source/nmbd/nmbd_elections.c
@@ -177,6 +177,7 @@ void run_elections(time_t t)
lastime = t;
+ START_PROFILE(run_elections);
for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
{
struct work_record *work;
@@ -215,6 +216,7 @@ yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
}
}
}
+ END_PROFILE(run_elections);
}
/*******************************************************************
@@ -276,6 +278,7 @@ void process_election(struct subnet_record *subrec, struct packet_struct *p, cha
struct work_record *work;
char *workgroup_name = dgram->dest_name.name;
+ START_PROFILE(election);
server_name[15] = 0;
DEBUG(3,("process_election: Election request from %s at IP %s on subnet %s for workgroup %s.\n",
@@ -287,14 +290,14 @@ void process_election(struct subnet_record *subrec, struct packet_struct *p, cha
{
DEBUG(0,("process_election: Cannot find workgroup %s on subnet %s.\n",
workgroup_name, subrec->subnet_name ));
- return;
+ goto done;
}
if (!strequal(work->work_group, global_myworkgroup))
{
DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \
is not my workgroup.\n", work->work_group, subrec->subnet_name ));
- return;
+ goto done;
}
if (win_election(work, version,criterion,timeup,server_name))
@@ -325,6 +328,8 @@ is not my workgroup.\n", work->work_group, subrec->subnet_name ));
unbecome_local_master_browser(subrec, work, False);
}
}
+done:
+ END_PROFILE(election);
}
/****************************************************************************
diff --git a/source/nmbd/nmbd_incomingdgrams.c b/source/nmbd/nmbd_incomingdgrams.c
index b8be579779f..dd1559c62c3 100644
--- a/source/nmbd/nmbd_incomingdgrams.c
+++ b/source/nmbd/nmbd_incomingdgrams.c
@@ -110,6 +110,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p
char *work_name;
char *source_name = dgram->source_name.name;
+ START_PROFILE(host_announce);
comment[43] = 0;
DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \
@@ -161,7 +162,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p
{
/* We have no record of this workgroup. Add it. */
if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- return;
+ goto done;
}
if((servrec = find_server_in_workgroup( work, announce_name))==NULL)
@@ -193,6 +194,8 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p
}
}
subrec->work_changed = True;
+done:
+ END_PROFILE(host_announce);
}
/*******************************************************************
@@ -209,6 +212,7 @@ void process_workgroup_announce(struct subnet_record *subrec, struct packet_stru
struct work_record *work;
char *source_name = dgram->source_name.name;
+ START_PROFILE(workgroup_announce);
master_name[43] = 0;
DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \
@@ -223,14 +227,14 @@ void process_workgroup_announce(struct subnet_record *subrec, struct packet_stru
{
DEBUG(0,("process_workgroup_announce: from IP %s should be to __MSBROWSE__<0x01> not %s\n",
inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name)));
- return;
+ goto done;
}
if ((work = find_workgroup_on_subnet(subrec, workgroup_announce_name))==NULL)
{
/* We have no record of this workgroup. Add it. */
if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl))==NULL)
- return;
+ goto done;
}
else
{
@@ -245,6 +249,8 @@ void process_workgroup_announce(struct subnet_record *subrec, struct packet_stru
}
subrec->work_changed = True;
+done:
+ END_PROFILE(workgroup_announce);
}
/*******************************************************************
@@ -263,6 +269,7 @@ void process_local_master_announce(struct subnet_record *subrec, struct packet_s
struct server_record *servrec;
char *source_name = dgram->source_name.name;
+ START_PROFILE(local_master_announce);
comment[43] = 0;
DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \
@@ -278,7 +285,7 @@ void process_local_master_announce(struct subnet_record *subrec, struct packet_s
DEBUG(0,("process_local_master_announce: incorrect name type for destination from IP %s \
(was %02x) should be 0x1e. Ignoring packet.\n",
inet_ntoa(p->ip), dgram->dest_name.name_type));
- return;
+ goto done;
}
/* Filter servertype to remove impossible bits. */
@@ -291,11 +298,11 @@ void process_local_master_announce(struct subnet_record *subrec, struct packet_s
{
/* Don't bother adding if it's a local master release announce. */
if(servertype == 0)
- return;
+ goto done;
/* We have no record of this workgroup. Add it. */
if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- return;
+ goto done;
}
/* If we think we're the local master browser for this workgroup,
@@ -322,7 +329,7 @@ a local master browser for workgroup %s and we think we are master. Forcing elec
/* The actual election requests are handled in
nmbd_election.c */
- return;
+ goto done;
}
/* Find the server record on this workgroup. If it doesn't exist, add it. */
@@ -361,6 +368,8 @@ a local master browser for workgroup %s and we think we are master. Forcing elec
}
subrec->work_changed = True;
+done:
+ END_PROFILE(local_master_announce);
}
/*******************************************************************
@@ -377,6 +386,7 @@ void process_master_browser_announce(struct subnet_record *subrec,
struct work_record *work;
struct browse_cache_record *browrec;
+ START_PROFILE(master_browser_announce);
local_master_name[15] = 0;
DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n",
@@ -386,21 +396,21 @@ void process_master_browser_announce(struct subnet_record *subrec,
{
DEBUG(0,("process_master_browser_announce: Not configured as domain \
master - ignoring master announce.\n"));
- return;
+ goto done;
}
if((work = find_workgroup_on_subnet(subrec, global_myworkgroup)) == NULL)
{
DEBUG(0,("process_master_browser_announce: Cannot find workgroup %s on subnet %s\n",
global_myworkgroup, subrec->subnet_name));
- return;
+ goto done;
}
if(!AM_DOMAIN_MASTER_BROWSER(work))
{
DEBUG(0,("process_master_browser_announce: Local master announce made to us from \
%s IP %s and we are not a domain master browser.\n", local_master_name, inet_ntoa(p->ip)));
- return;
+ goto done;
}
/* Add this host as a local master browser entry on the browse lists.
@@ -414,6 +424,8 @@ master - ignoring master announce.\n"));
}
else
update_browser_death_time(browrec);
+done:
+ END_PROFILE(master_browser_announce);
}
/*******************************************************************
@@ -435,6 +447,7 @@ void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct
pstring comment;
char *s = buf+9;
+ START_PROFILE(lm_host_announce);
s = skip_string(s,1);
StrnCpy(comment, s, 43);
@@ -451,7 +464,7 @@ void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct
originate from OS/2 Warp client. Ignoring packet.\n"));
/* Could have been from a Windows machine (with its LM Announce enabled),
or a Samba server. Then don't disrupt the current browse list. */
- return;
+ goto done;
}
/* Filter servertype to remove impossible bits. */
@@ -497,7 +510,7 @@ originate from OS/2 Warp client. Ignoring packet.\n"));
{
/* We have no record of this workgroup. Add it. */
if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL)
- return;
+ goto done;
}
if((servrec = find_server_in_workgroup( work, announce_name))==NULL)
@@ -531,6 +544,8 @@ originate from OS/2 Warp client. Ignoring packet.\n"));
subrec->work_changed = True;
found_lm_clients = True;
+done:
+ END_PROFILE(lm_host_announce);
}
/****************************************************************************
@@ -643,6 +658,7 @@ void process_get_backup_list_request(struct subnet_record *subrec,
char *workgroup_name = dgram->dest_name.name;
struct subnet_record *search_subrec = subrec;
+ START_PROFILE(get_backup_list);
DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
nmb_namestr(&dgram->dest_name)));
@@ -655,14 +671,14 @@ void process_get_backup_list_request(struct subnet_record *subrec,
{
DEBUG(7,("process_get_backup_list_request: Ignoring announce request for workgroup %s.\n",
workgroup_name));
- return;
+ goto done;
}
if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL)
{
DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \
subnet %s.\n", workgroup_name, search_subrec->subnet_name));
- return;
+ goto done;
}
/*
@@ -680,7 +696,7 @@ subnet %s.\n", workgroup_name, search_subrec->subnet_name));
{
DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
and I am not a domain master browser.\n", workgroup_name));
- return;
+ goto done;
}
search_subrec = unicast_subnet;
@@ -694,18 +710,20 @@ and I am not a domain master browser.\n", workgroup_name));
{
DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \
and I am not a local master browser.\n", workgroup_name));
- return;
+ goto done;
}
}
else
{
DEBUG(0,("process_get_backup_list_request: Invalid name type %x - should be 0x1b or 0x1d.\n",
name_type));
- return;
+ goto done;
}
send_backup_list_response(subrec, work, &dgram->source_name,
max_number_requested, token, p->ip, p->port);
+done:
+ END_PROFILE(get_backup_list);
}
/*******************************************************************
@@ -725,6 +743,7 @@ void process_reset_browser(struct subnet_record *subrec,
int state = CVAL(buf,0);
struct subnet_record *sr;
+ START_PROFILE(reset_browser);
DEBUG(1,("process_reset_browser: received diagnostic browser reset \
request from %s IP %s state=0x%X\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip), state));
@@ -761,6 +780,7 @@ request from %s IP %s state=0x%X\n",
/* Request to stop browsing altogether. */
if (state & 0x4)
DEBUG(1,("process_reset_browser: ignoring request to stop being a browser.\n"));
+ END_PROFILE(reset_browser);
}
/*******************************************************************
@@ -777,6 +797,7 @@ void process_announce_request(struct subnet_record *subrec, struct packet_struct
struct work_record *work;
char *workgroup_name = dgram->dest_name.name;
+ START_PROFILE(announce_request);
DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
nmb_namestr(&dgram->dest_name)));
@@ -786,17 +807,19 @@ void process_announce_request(struct subnet_record *subrec, struct packet_struct
{
DEBUG(7,("process_announce_request: Ignoring announce request for workgroup %s.\n",
workgroup_name));
- return;
+ goto done;
}
if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
{
DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
workgroup_name));
- return;
+ goto done;
}
work->needannounce = True;
+done:
+ END_PROFILE(lm_host_announce);
}
/*******************************************************************
@@ -813,6 +836,7 @@ void process_lm_announce_request(struct subnet_record *subrec, struct packet_str
struct dgram_packet *dgram = &p->packet.dgram;
char *workgroup_name = dgram->dest_name.name;
+ START_PROFILE(lm_announce_request);
DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
nmb_namestr(&dgram->dest_name)));
@@ -822,15 +846,17 @@ void process_lm_announce_request(struct subnet_record *subrec, struct packet_str
{
DEBUG(7,("process_lm_announce_request: Ignoring announce request for workgroup %s.\n",
workgroup_name));
- return;
+ goto done;
}
if(find_workgroup_on_subnet(subrec, workgroup_name) == NULL)
{
DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n",
workgroup_name));
- return;
+ goto done;
}
found_lm_clients = True;
+done:
+ END_PROFILE(lm_host_announce);
}
diff --git a/source/nmbd/nmbd_incomingrequests.c b/source/nmbd/nmbd_incomingrequests.c
index c59c045bad4..82cda38c7f8 100644
--- a/source/nmbd/nmbd_incomingrequests.c
+++ b/source/nmbd/nmbd_incomingrequests.c
@@ -68,6 +68,7 @@ void process_name_release_request(struct subnet_record *subrec,
struct name_record *namerec;
int rcode = 0;
+ START_PROFILE(name_release);
putip((char *)&owner_ip,&nmb->additional->rdata[2]);
if(!bcast)
@@ -84,7 +85,7 @@ received for name %s from IP %s on subnet %s. Error - should be sent to WINS ser
nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name));
send_name_release_response(FMT_ERR, p);
- return;
+ goto done;
}
DEBUG(3,("process_name_release_request: Name release on name %s, \
@@ -94,7 +95,7 @@ subnet %s from owner IP %s\n",
/* If someone is releasing a broadcast group name, just ignore it. */
if( group && !ismyip(owner_ip) )
- return;
+ goto done;
/*
* Code to work around a bug in FTP OnNet software NBT implementation.
@@ -108,7 +109,7 @@ subnet %s from owner IP %s\n",
DEBUG(6,("process_name_release_request: FTP OnNet bug workaround. Ignoring \
group release name %s from IP %s on subnet %s with no group bit set.\n",
nmb_namestr(question), inet_ntoa(owner_ip), subrec->subnet_name ));
- return;
+ goto done;
}
namerec = find_name_on_subnet(subrec, &nmb->question.question_name, FIND_ANY_NAME);
@@ -125,10 +126,12 @@ on subnet %s being rejected as it is one of our names.\n",
}
if(rcode == 0)
- return;
+ goto done;
/* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
send_name_release_response(rcode, p);
+done:
+ END_PROFILE(name_release);
}
/****************************************************************************
@@ -164,6 +167,7 @@ void process_name_refresh_request(struct subnet_record *subrec,
BOOL bcast = nmb->header.nm_flags.bcast;
struct in_addr from_ip;
+ START_PROFILE(name_refresh);
putip((char *)&from_ip,&nmb->additional->rdata[2]);
if(!bcast)
@@ -181,7 +185,7 @@ received for name %s from IP %s on subnet %s.\n",
DEBUG(0,("Error - should be sent to WINS server\n"));
send_name_registration_response(FMT_ERR, 0, p);
- return;
+ goto done;
}
/* Just log a message. We really don't care about broadcast name
@@ -190,6 +194,8 @@ received for name %s from IP %s on subnet %s.\n",
DEBUG(3,("process_name_refresh_request: Name refresh for name %s \
IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
+done:
+ END_PROFILE(name_refresh);
}
/****************************************************************************
@@ -208,6 +214,7 @@ void process_name_registration_request(struct subnet_record *subrec,
int ttl = nmb->additional->ttl;
struct in_addr from_ip;
+ START_PROFILE(name_registration);
putip((char *)&from_ip,&nmb->additional->rdata[2]);
if(!bcast)
@@ -224,7 +231,7 @@ received for name %s from IP %s on subnet %s. Error - should be sent to WINS ser
nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
send_name_registration_response(FMT_ERR, 0, p);
- return;
+ goto done;
}
DEBUG(3,("process_name_registration_request: Name registration for name %s \
@@ -258,7 +265,7 @@ IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet
register a name that's a group name as a unique name */
send_name_registration_response(ACT_ERR, 0, p);
- return;
+ goto done;
}
else if(namerec != NULL)
{
@@ -268,7 +275,7 @@ IP %s on subnet %s\n", nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet
DEBUG(3,("process_name_registration_request: Updated name record %s \
with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subrec->subnet_name));
- return;
+ goto done;
}
}
else
@@ -282,9 +289,11 @@ with IP %s on subnet %s\n",nmb_namestr(&namerec->name),inet_ntoa(from_ip), subre
{
/* Disallow group names when we have a unique name. */
send_name_registration_response(ACT_ERR, 0, p);
- return;
+ goto done;
}
}
+done:
+ END_PROFILE(name_registration);
}
/****************************************************************************
@@ -328,6 +337,7 @@ void process_node_status_request(struct subnet_record *subrec, struct packet_str
int names_added,i;
struct name_record *namerec;
+ START_PROFILE(node_status);
DEBUG(3,("process_node_status_request: status request for name %s from IP %s on \
subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
subrec->subnet_name));
@@ -339,7 +349,7 @@ subnet %s.\n", nmb_namestr(&nmb->question.question_name), inet_ntoa(p->ip),
subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
inet_ntoa(p->ip), subrec->subnet_name));
- return;
+ goto done;
}
/* this is not an exact calculation. the 46 is for the stats buffer
@@ -436,6 +446,8 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
0, /* ttl. */
rdata, /* data to send. */
PTR_DIFF(buf,rdata)); /* data length. */
+done:
+ END_PROFILE(node_status);
}
@@ -464,6 +476,7 @@ void process_name_query_request(struct subnet_record *subrec, struct packet_stru
int reply_data_len = 0;
int i;
+ START_PROFILE(name_query);
DEBUG(3,("process_name_query_request: Name query from %s on subnet %s for name %s\n",
inet_ntoa(p->ip), subrec->subnet_name, nmb_namestr(question)));
@@ -530,7 +543,7 @@ void process_name_query_request(struct subnet_record *subrec, struct packet_stru
DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also \
on the same subnet (%s) as the requestor. Not replying.\n",
nmb_namestr(&namerec->name), subrec->subnet_name ));
- return;
+ goto done;
}
}
}
@@ -549,7 +562,7 @@ on the same subnet (%s) as the requestor. Not replying.\n",
if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
{
DEBUG(0,("process_name_query_request: malloc fail !\n"));
- return;
+ goto done;
}
}
@@ -576,14 +589,14 @@ on the same subnet (%s) as the requestor. Not replying.\n",
bcast && (subrec != remote_broadcast_subnet))
{
make_wins_proxy_name_query_request( subrec, p, question );
- return;
+ goto done;
}
if (!success && bcast)
{
if((prdata != rdata) && (prdata != NULL))
free(prdata);
- return; /* Never reply with a negative response to broadcasts. */
+ goto done; /* Never reply with a negative response to broadcasts. */
}
/*
@@ -596,7 +609,7 @@ on the same subnet (%s) as the requestor. Not replying.\n",
{
if((prdata != rdata) && (prdata != NULL))
free(prdata);
- return;
+ goto done;
}
if (success)
@@ -622,4 +635,6 @@ on the same subnet (%s) as the requestor. Not replying.\n",
if((prdata != rdata) && (prdata != NULL))
free(prdata);
+done:
+ END_PROFILE(name_query);
}
diff --git a/source/nmbd/nmbd_mynames.c b/source/nmbd/nmbd_mynames.c
index 432a4736a47..7672417786a 100644
--- a/source/nmbd/nmbd_mynames.c
+++ b/source/nmbd/nmbd_mynames.c
@@ -219,8 +219,8 @@ void refresh_my_names(time_t t)
*/
if( !is_refresh_already_queued( subrec, namerec) )
refresh_name( subrec, namerec, NULL, NULL, NULL );
- namerec->data.death_time += lp_max_ttl();
- namerec->data.refresh_time += MIN(lp_max_ttl(), MAX_REFRESH_TIME);
+ namerec->data.death_time = t + lp_max_ttl();
+ namerec->data.refresh_time = t + MIN(lp_max_ttl(), MAX_REFRESH_TIME);
}
}
}
diff --git a/source/nmbd/nmbd_namequery.c b/source/nmbd/nmbd_namequery.c
index 66af796b6f6..b497526475e 100644
--- a/source/nmbd/nmbd_namequery.c
+++ b/source/nmbd/nmbd_namequery.c
@@ -121,9 +121,9 @@ static void query_name_response( struct subnet_record *subrec,
}
if(success && rrec->success_fn)
- (*rrec->success_fn)(subrec, rrec->userdata, question_name, answer_ip, nmb->answers);
+ (*(query_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, answer_ip, nmb->answers);
else if( rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec, question_name, nmb->header.rcode);
+ (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, nmb->header.rcode);
}
@@ -156,7 +156,7 @@ static void query_name_timeout_response(struct subnet_record *subrec,
dbgtext( "on subnet %s.\n", subrec->subnet_name );
}
if(rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec, question_name, 0);
+ (*(query_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name, 0);
}
remove_response_record(subrec, rrec);
@@ -242,7 +242,7 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type,
/* Call the success function directly. */
if(success_fn)
- (*success_fn)(subrec, userdata, &nmbname, namerec->data.ip[0], &rrec);
+ (*(query_name_success_function)success_fn)(subrec, userdata, &nmbname, namerec->data.ip[0], &rrec);
return False;
}
diff --git a/source/nmbd/nmbd_nameregister.c b/source/nmbd/nmbd_nameregister.c
index 88057287372..6154f06edde 100644
--- a/source/nmbd/nmbd_nameregister.c
+++ b/source/nmbd/nmbd_nameregister.c
@@ -144,12 +144,12 @@ name %s on subnet %s.\n", inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->su
the success function. */
standard_success_register(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
if( rrec->success_fn)
- (*rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
+ (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, registered_ip);
}
else
{
if( rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec, question_name);
+ (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
/* Remove the name. */
standard_fail_register( subrec, rrec, question_name);
}
@@ -211,6 +211,7 @@ responding.\n", inet_ntoa(rrec->packet->ip)));
if(rrec->repeat_interval > (5 * 60))
rrec->repeat_interval = (5 * 60);
rrec->repeat_time = time(NULL) + rrec->repeat_interval;
+ rrec->in_expiration_processing = False;
DEBUG(5,("register_name_timeout_response: increasing WINS timeout to %d seconds.\n",
(int)rrec->repeat_interval));
@@ -226,12 +227,12 @@ responding.\n", inet_ntoa(rrec->packet->ip)));
the success function. */
standard_success_register(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
if( rrec->success_fn)
- (*rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
+ (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
}
else
{
if( rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec, question_name);
+ (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
/* Remove the name. */
standard_fail_register( subrec, rrec, question_name);
}
diff --git a/source/nmbd/nmbd_namerelease.c b/source/nmbd/nmbd_namerelease.c
index 2e3b4e8c6ac..0f693c63d02 100644
--- a/source/nmbd/nmbd_namerelease.c
+++ b/source/nmbd/nmbd_namerelease.c
@@ -99,14 +99,14 @@ name %s on subnet %s.\n", inet_ntoa(p->ip), nmb_namestr(answer_name), subrec->su
putip((char*)&released_ip ,&nmb->answers->rdata[2]);
if(rrec->success_fn)
- (*rrec->success_fn)(subrec, rrec->userdata, answer_name, released_ip);
+ (*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, released_ip);
standard_success_release( subrec, rrec->userdata, answer_name, released_ip);
}
else
{
/* We have no standard_fail_release - maybe we should add one ? */
if(rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec, answer_name);
+ (*(release_name_fail_function)rrec->fail_fn)(subrec, rrec, answer_name);
}
remove_response_record(subrec, rrec);
@@ -174,14 +174,14 @@ responding.\n", inet_ntoa(rrec->packet->ip)));
if(success && rrec->success_fn)
{
if(rrec->success_fn)
- (*rrec->success_fn)(subrec, rrec->userdata, question_name, released_ip);
+ (*(release_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, released_ip);
standard_success_release( subrec, rrec->userdata, question_name, released_ip);
}
else
{
/* We have no standard_fail_release - maybe we should add one ? */
if( rrec->fail_fn)
- (*rrec->fail_fn)(subrec, rrec, question_name);
+ (*(release_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
}
remove_response_record(subrec, rrec);
diff --git a/source/nmbd/nmbd_nodestatus.c b/source/nmbd/nmbd_nodestatus.c
index d78f8a5547a..d28ea1cff4e 100644
--- a/source/nmbd/nmbd_nodestatus.c
+++ b/source/nmbd/nmbd_nodestatus.c
@@ -52,7 +52,7 @@ name %s.\n", nmb_namestr(answer_name), nmb_namestr(question_name)));
/* Just send the whole answer resource record for the success function
to parse. */
if(rrec->success_fn)
- (*rrec->success_fn)(subrec, rrec->userdata, nmb->answers, p->ip);
+ (*(node_status_success_function)rrec->success_fn)(subrec, rrec->userdata, nmb->answers, p->ip);
/* Ensure we don't retry. */
remove_response_record(subrec, rrec);
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c
index 5e554ceae2a..3699754c885 100644
--- a/source/nmbd/nmbd_processlogon.c
+++ b/source/nmbd/nmbd_processlogon.c
@@ -54,13 +54,14 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len,
pstring ascuser;
char *unicomp; /* Unicode computer name. */
+ START_PROFILE(domain_logon);
memset(outbuf, 0, sizeof(outbuf));
if (!lp_domain_logons())
{
DEBUG(3,("process_logon_packet: Logon packet received from IP %s and domain \
logons are not enabled.\n", inet_ntoa(p->ip) ));
- return;
+ goto done;
}
pstrcpy(my_name, global_myname);
@@ -113,6 +114,12 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
char *q = buf + 2;
char *machine = q;
+ if (!lp_domain_master())
+ {
+ /* We're not Primary Domain Controller -- ignore this */
+ goto done;
+ }
+
getdc = skip_string(machine,1);
q = skip_string(getdc,1);
q = ALIGN2(q, buf);
@@ -186,7 +193,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
dgram->source_name.name,
dgram->source_name.name_type,
p->ip, *iface_ip(p->ip), p->port);
- return;
+ goto done;
}
case SAMLOGON:
@@ -281,7 +288,9 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
default:
{
DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
- return;
+ goto done;
}
}
+done:
+ END_PROFILE(domain_logon);
}
diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c
index 23cbc01b889..4afb730519a 100644
--- a/source/nmbd/nmbd_synclists.c
+++ b/source/nmbd/nmbd_synclists.c
@@ -135,14 +135,17 @@ void sync_browse_lists(struct work_record *work,
struct sync_record *s;
static int counter;
+ START_PROFILE(sync_browse_lists);
/* Check we're not trying to sync with ourselves. This can
happen if we are a domain *and* a local master browser. */
if (ismyip(ip)) {
+done:
+ END_PROFILE(sync_browse_lists);
return;
}
s = (struct sync_record *)malloc(sizeof(*s));
- if (!s) return;
+ if (!s) goto done;
ZERO_STRUCTP(s);
@@ -157,7 +160,7 @@ void sync_browse_lists(struct work_record *work,
DLIST_ADD(syncs, s);
/* the parent forks and returns, leaving the child to do the
- actual sync */
+ actual sync and call END_PROFILE*/
CatchChild();
if ((s->pid = sys_fork())) return;
@@ -167,12 +170,16 @@ void sync_browse_lists(struct work_record *work,
work->work_group, name, inet_ntoa(ip)));
fp = sys_fopen(s->fname,"w");
- if (!fp) _exit(1);
+ if (!fp) {
+ END_PROFILE(sync_browse_lists);
+ _exit(1);
+ }
sync_child(name, nm_type, work->work_group, ip, local, servers,
s->fname);
fclose(fp);
+ END_PROFILE(sync_browse_lists);
_exit(0);
}
diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
index a8410f85086..b3dea202c2c 100644
--- a/source/nsswitch/pam_winbind.c
+++ b/source/nsswitch/pam_winbind.c
@@ -5,33 +5,7 @@
largely based on pam_userdb by Christian Gafton <gafton@redhat.com>
*/
-#include <features.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define MODULE_NAME "pam_winbind"
-#define PAM_SM_AUTH
-#define PAM_SM_ACCOUNT
-#ifdef HAVE_SECURITY_PAM_MODULES_H
-#include <security/pam_modules.h>
-#endif
-#ifdef HAVE_SECURITY__PAM_MACROS_H
-#include <security/_pam_macros.h>
-#endif
-
-#define PAM_DEBUG_ARG (1<<0)
-#define PAM_USE_AUTHTOK_ARG (1<<1)
-#define PAM_UNKNOWN_OK_ARG (1<<2)
-
-#include "winbind_nss_config.h"
-#include "winbindd_nss.h"
+#include "pam_winbind.h"
/* prototypes from common.c */
void init_request(struct winbindd_request *req,int rq_type);
@@ -73,38 +47,78 @@ static int _pam_parse(int argc, const char **argv)
return ctrl;
}
-
-/* talk to winbindd */
-static int winbind_request(int req_type, const char *user, const char *pass)
+static int winbind_request(enum winbindd_cmd req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
{
- struct winbindd_request request;
- struct winbindd_response response;
-
- ZERO_STRUCT(request);
-
- strncpy(request.data.auth.user, user, sizeof(request.data.auth.user)-1);
- strncpy(request.data.auth.pass, pass, sizeof(request.data.auth.pass)-1);
-
/* Fill in request and send down pipe */
- init_request(&request, req_type);
+ init_request(request, req_type);
- if (write_sock(&request, sizeof(request)) == -1) {
+ if (write_sock(request, sizeof(*request)) == -1) {
return -2;
}
/* Wait for reply */
- if (read_reply(&response) == -1) {
+ if (read_reply(response) == -1) {
return -2;
}
/* Copy reply data from socket */
- if (response.result != WINBINDD_OK) {
+ if (response->result != WINBINDD_OK) {
return 1;
}
return 0;
}
+/* talk to winbindd */
+static int winbind_auth_request(const char *user, const char *pass)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+
+ ZERO_STRUCT(request);
+
+ strncpy(request.data.auth.user, user,
+ sizeof(request.data.auth.user)-1);
+
+ strncpy(request.data.auth.pass, pass,
+ sizeof(request.data.auth.pass)-1);
+
+ return winbind_request(WINBINDD_PAM_AUTH, &request, &response);
+}
+
+/* talk to winbindd */
+static int winbind_chauthtok_request(const char *user, const char *oldpass,
+ const char *newpass)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+
+ ZERO_STRUCT(request);
+
+ if (request.data.chauthtok.user == NULL) return -2;
+
+ strncpy(request.data.chauthtok.user, user,
+ sizeof(request.data.chauthtok.user) - 1);
+
+ if (oldpass != NULL) {
+ strncpy(request.data.chauthtok.oldpass, oldpass,
+ sizeof(request.data.chauthtok.oldpass) - 1);
+ } else {
+ request.data.chauthtok.oldpass[0] = '\0';
+ }
+
+ if (newpass != NULL) {
+ strncpy(request.data.chauthtok.newpass, newpass,
+ sizeof(request.data.chauthtok.newpass) - 1);
+ } else {
+ request.data.chauthtok.newpass[0] = '\0';
+ }
+
+ return winbind_request(WINBINDD_PAM_CHAUTHTOK, &request, &response);
+}
+
/*
* Looks up an user name and checks the password
*
@@ -116,7 +130,7 @@ static int winbind_request(int req_type, const char *user, const char *pass)
*/
static int user_lookup(const char *user, const char *pass)
{
- return winbind_request(WINBINDD_PAM_AUTH, user, pass);
+ return winbind_auth_request(user, pass);
}
/*
@@ -135,11 +149,9 @@ static int valid_user(const char *user)
/* --- authentication management functions --- */
-/*
- * dummy conversation function sending exactly one prompt
- * and expecting exactly one response from the other party
- */
-static int converse(pam_handle_t *pamh,
+/* Attempt a conversation */
+
+static int converse(pam_handle_t *pamh, int nargs,
struct pam_message **message,
struct pam_response **response)
{
@@ -147,9 +159,10 @@ static int converse(pam_handle_t *pamh,
struct pam_conv *conv;
retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv ) ;
- if (retval == PAM_SUCCESS)
- retval = conv->conv(1, (const struct pam_message **)message,
+ if (retval == PAM_SUCCESS) {
+ retval = conv->conv(nargs, (const struct pam_message **)message,
response, conv->appdata_ptr);
+ }
return retval; /* propagate error status */
}
@@ -165,20 +178,20 @@ static char *_pam_delete(register char *xx)
/*
* This is a conversation function to obtain the user's password
*/
-static int conversation(pam_handle_t *pamh)
+static int auth_conversation(pam_handle_t *pamh)
{
- struct pam_message msg[2],*pmsg[2];
+ struct pam_message msg, *pmsg;
struct pam_response *resp;
int retval;
- char * token;
+ char * token = NULL;
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = "Password: ";
+ pmsg = &msg;
+ msg.msg_style = PAM_PROMPT_ECHO_OFF;
+ msg.msg = "Password: ";
/* so call the conversation expecting i responses */
resp = NULL;
- retval = converse(pamh, pmsg, &resp);
+ retval = converse(pamh, 1, &pmsg, &resp);
if (resp != NULL) {
char * const item;
@@ -207,7 +220,6 @@ static int conversation(pam_handle_t *pamh)
return retval;
}
-
PAM_EXTERN
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char **argv)
@@ -229,7 +241,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
if ((ctrl & PAM_USE_AUTHTOK_ARG) == 0) {
/* Converse just to be sure we have the password */
- retval = conversation(pamh);
+ retval = auth_conversation(pamh);
if (retval != PAM_SUCCESS) {
_pam_log(LOG_ERR, "could not obtain password for `%s'",
username);
@@ -340,24 +352,134 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
}
+PAM_EXTERN
+int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval;
+ char *newpw, *oldpw;
+ const char *user;
+
+ /* Get name of a user */
+
+ retval = pam_get_user(pamh, &user, "Username: ");
+
+ if (retval != PAM_SUCCESS) {
+ return retval;
+ }
+
+ /* XXX check in domain format */
+
+ /* Perform preliminary check and store requested password for updating
+ later on */
+
+ if (flags & PAM_PRELIM_CHECK) {
+ struct pam_message msg[3], *pmsg[3];
+ struct pam_response *resp;
+
+ /* Converse to ensure we have the current password */
+
+ retval = auth_conversation(pamh);
+
+ if (retval != PAM_SUCCESS) {
+ return retval;
+ }
+
+ /* Obtain and verify current password */
+
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_TEXT_INFO;
+ msg[0].msg = "Changing password for user %s";
+
+ pmsg[1] = &msg[1];
+ msg[1].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[1].msg = "New NT password: ";
+
+ pmsg[2] = &msg[2];
+ msg[2].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[2].msg = "Retype new NT password: ";
+
+ resp = NULL;
+
+ retval = converse(pamh, 3, pmsg, &resp);
+
+ if (resp != NULL) {
+
+ if (retval == PAM_SUCCESS) {
+
+ /* Check password entered correctly */
+
+ if (strcmp(resp[1].resp, resp[2].resp) != 0) {
+ struct pam_response *resp2;
+
+ msg[0].msg_style = PAM_ERROR_MSG;
+ msg[0].msg = "Sorry, passwords do not match";
+
+ converse(pamh, 1, pmsg, &resp2);
+
+ _pam_drop_reply(resp, 3);
+ _pam_drop_reply(resp2, 1);
+
+ return PAM_AUTHTOK_RECOVER_ERR;
+ }
+
+ /* Store passwords */
+
+ retval = pam_set_item(pamh, PAM_OLDAUTHTOK, resp[1].resp);
+ _pam_drop_reply(resp, 3);
+ }
+ }
+
+ /* XXX What happens if root? */
+ /* XXX try first pass and use first pass args */
+
+ return retval;
+ }
+
+ if (flags & PAM_UPDATE_AUTHTOK) {
+
+ retval = pam_get_item(pamh, PAM_OLDAUTHTOK, (const void **)&newpw);
+ if (retval != PAM_SUCCESS) {
+ return PAM_AUTHTOK_ERR;
+ }
+
+ retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&oldpw);
+ if (retval != PAM_SUCCESS) {
+ return PAM_AUTHTOK_ERR;
+ }
+
+ fprintf(stderr, "oldpw = %s, newpw = %s\n", oldpw, newpw);
+
+ if (retval == PAM_SUCCESS &&
+ winbind_chauthtok_request(user, oldpw, newpw) == 0) {
+ return PAM_SUCCESS;
+ }
+
+ return PAM_AUTHTOK_ERR;
+ }
+
+ return PAM_SERVICE_ERR;
+}
+
#ifdef PAM_STATIC
/* static module data */
-struct pam_module _pam_userdb_modstruct = {
+struct pam_module _pam_winbind_modstruct = {
MODULE_NAME,
pam_sm_authenticate,
pam_sm_setcred,
pam_sm_acct_mgmt,
NULL,
NULL,
- NULL,
+ pam_sm_chauthtok
};
#endif
/*
* Copyright (c) Andrew Tridgell <tridge@samba.org> 2000
+ * Copyright (c) Tim Potter <tpot@samba.org> 2000
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c
index 71a21a97207..6ade637c8c2 100644
--- a/source/nsswitch/wb_client.c
+++ b/source/nsswitch/wb_client.c
@@ -25,6 +25,32 @@
#include "includes.h"
+NSS_STATUS winbindd_request(int req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+
+/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
+ form DOMAIN/user into a domain and a user */
+
+static void parse_domain_user(char *domuser, fstring domain, fstring user)
+{
+ char *p;
+ char *sep = lp_winbind_separator();
+ if (!sep) sep = "\\";
+ p = strchr(domuser,*sep);
+ if (!p) p = strchr(domuser,'\\');
+ if (!p) {
+ fstrcpy(domain,"");
+ fstrcpy(user, domuser);
+ return;
+ }
+
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ strupper(domain);
+}
+
/* Call winbindd to convert a name to a sid */
BOOL winbind_lookup_name(const char *name, DOM_SID *sid, enum SID_NAME_USE *name_type)
@@ -42,7 +68,8 @@ BOOL winbind_lookup_name(const char *name, DOM_SID *sid, enum SID_NAME_USE *name
ZERO_STRUCT(response);
fstrcpy(request.data.name, name);
- if ((result = (NSS_STATUS)winbindd_request(WINBINDD_LOOKUPNAME, &request,
+
+ if ((result = winbindd_request(WINBINDD_LOOKUPNAME, &request,
&response)) == NSS_STATUS_SUCCESS) {
string_to_sid(sid, response.data.sid.sid);
*name_type = (enum SID_NAME_USE)response.data.sid.type;
@@ -70,7 +97,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_N
/* Make request */
- result = (NSS_STATUS)winbindd_request(WINBINDD_LOOKUPSID, &request, &response);
+ result = winbindd_request(WINBINDD_LOOKUPSID, &request, &response);
/* Copy out result */
@@ -171,7 +198,7 @@ BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid)
/* Make request */
- result = winbindd_request(WINBINDD_SID_TO_UID, &request, &response);
+ result = winbindd_request(WINBINDD_SID_TO_GID, &request, &response);
/* Copy out result */
@@ -252,7 +279,7 @@ static int wb_getgroups(char *user, gid_t **groups)
int winbind_initgroups(char *user, gid_t gid)
{
- gid_t *groups = NULL;
+ gid_t *tgr, *groups = NULL;
int result;
char *sep;
@@ -284,13 +311,14 @@ int winbind_initgroups(char *user, gid_t gid)
/* Add group to list if necessary */
if (!is_member) {
- groups = Realloc(groups, sizeof(gid_t) * ngroups + 1);
+ tgr = (gid_t *)Realloc(groups, sizeof(gid_t) * ngroups + 1);
- if (!groups) {
+ if (!tgr) {
errno = ENOMEM;
result = -1;
goto done;
- }
+ } else
+ groups = tgr;
groups[ngroups] = gid;
ngroups++;
diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c
index 243f05825b7..7fb2bc2cf54 100644
--- a/source/nsswitch/wb_common.c
+++ b/source/nsswitch/wb_common.c
@@ -29,6 +29,17 @@
/* Global variables. These are effectively the client state information */
static int established_socket = -1; /* fd for winbindd socket */
+static char *excluded_domain;
+
+/*
+ smbd needs to be able to exclude lookups for its own domain
+*/
+void winbind_exclude_domain(const char *domain)
+{
+ if (excluded_domain) free(excluded_domain);
+ excluded_domain = strdup(domain);
+}
+
/* Initialise a request structure */
@@ -99,7 +110,8 @@ static int open_pipe_sock(void)
return -1;
}
- if (!S_ISDIR(st.st_mode) || (st.st_uid != 0)) {
+ if (!S_ISDIR(st.st_mode) ||
+ (st.st_uid != 0 && st.st_uid != geteuid())) {
return -1;
}
@@ -128,7 +140,8 @@ static int open_pipe_sock(void)
/* Check permissions on unix socket file */
- if (!S_ISSOCK(st.st_mode) || (st.st_uid != 0)) {
+ if (!S_ISSOCK(st.st_mode) ||
+ (st.st_uid != 0 && st.st_uid != geteuid())) {
return -1;
}
@@ -169,6 +182,7 @@ int write_sock(void *buffer, int count)
while(nwritten < count) {
struct timeval tv;
fd_set r_fds;
+ int selret;
/* Catch pipe close on other end by checking if a read()
call would not block by calling select(). */
@@ -177,8 +191,8 @@ int write_sock(void *buffer, int count)
FD_SET(established_socket, &r_fds);
ZERO_STRUCT(tv);
- if (select(established_socket + 1, &r_fds,
- NULL, NULL, &tv) == -1) {
+ if ((selret = select(established_socket + 1, &r_fds,
+ NULL, NULL, &tv)) == -1) {
close_sock();
return -1; /* Select error */
}
@@ -318,6 +332,12 @@ NSS_STATUS winbindd_request(int req_type,
return NSS_STATUS_NOTFOUND;
}
+ /* smbd may have excluded this domain */
+ if (excluded_domain &&
+ strcasecmp(excluded_domain, request->domain) == 0) {
+ return NSS_STATUS_NOTFOUND;
+ }
+
if (!response) {
ZERO_STRUCT(lresponse);
response = &lresponse;
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index f20e1b16144..d29b144147d 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -22,15 +22,14 @@
*/
#include "includes.h"
-#include "winbind_nss_config.h"
#include "winbindd.h"
#include "debug.h"
-/* Prototypes from common.h - only needed #if TNG */
+/* Prototypes from common.h */
NSS_STATUS winbindd_request(int req_type,
- struct winbindd_request *request,
- struct winbindd_response *response);
+ struct winbindd_request *request,
+ struct winbindd_response *response);
/* List groups a user is a member of */
@@ -38,7 +37,8 @@ static BOOL wbinfo_get_usergroups(char *user)
{
struct winbindd_request request;
struct winbindd_response response;
- int result, i;
+ NSS_STATUS result;
+ int i;
ZERO_STRUCT(response);
@@ -53,7 +53,7 @@ static BOOL wbinfo_get_usergroups(char *user)
}
for (i = 0; i < response.data.num_entries; i++) {
- printf("%d\n", ((gid_t *)response.extra_data)[i]);
+ printf("%d\n", (int)((gid_t *)response.extra_data)[i]);
}
return True;
@@ -70,8 +70,8 @@ static BOOL wbinfo_list_domains(void)
/* Send request */
- if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -127,8 +127,8 @@ static BOOL wbinfo_uid_to_sid(uid_t uid)
/* Send request */
request.data.uid = uid;
- if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -152,8 +152,8 @@ static BOOL wbinfo_gid_to_sid(gid_t gid)
/* Send request */
request.data.gid = gid;
- if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -177,14 +177,14 @@ static BOOL wbinfo_sid_to_uid(char *sid)
/* Send request */
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
/* Display response */
- printf("%d\n", response.data.uid);
+ printf("%d\n", (int)response.data.uid);
return True;
}
@@ -200,14 +200,14 @@ static BOOL wbinfo_sid_to_gid(char *sid)
/* Send request */
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
/* Display response */
- printf("%d\n", response.data.gid);
+ printf("%d\n", (int)response.data.gid);
return True;
}
@@ -225,8 +225,8 @@ static BOOL wbinfo_lookupsid(char *sid)
/* Send off request */
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -250,8 +250,8 @@ static BOOL wbinfo_lookupname(char *name)
ZERO_STRUCT(response);
fstrcpy(request.data.name, name);
- if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -262,6 +262,85 @@ static BOOL wbinfo_lookupname(char *name)
return True;
}
+/* Authenticate a user with a plaintext password */
+
+static BOOL wbinfo_auth(char *username)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ NSS_STATUS result;
+ char *p;
+
+ /* Send off request */
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ p = strchr(username, '%');
+
+ if (p) {
+ *p = 0;
+ fstrcpy(request.data.auth.user, username);
+ fstrcpy(request.data.auth.pass, p + 1);
+ *p = '%';
+ } else
+ fstrcpy(request.data.auth.user, username);
+
+ result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
+
+ /* Display response */
+
+ printf("plaintext password authentication %s\n",
+ (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+
+ return result == NSS_STATUS_SUCCESS;
+}
+
+/* Authenticate a user with a challenge/response */
+
+static BOOL wbinfo_auth_crap(char *username)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ NSS_STATUS result;
+ fstring pass;
+ char *p;
+
+ /* Send off request */
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ p = strchr(username, '%');
+
+ if (p) {
+ *p = 0;
+ fstrcpy(request.data.auth_crap.user, username);
+ fstrcpy(pass, p + 1);
+ *p = '%';
+ } else
+ fstrcpy(request.data.auth_crap.user, username);
+
+ generate_random_buffer(request.data.auth_crap.chal, 8, False);
+
+ SMBencrypt((uchar *)pass, request.data.auth_crap.chal,
+ (uchar *)request.data.auth_crap.lm_resp);
+ SMBNTencrypt((uchar *)pass, request.data.auth_crap.chal,
+ (uchar *)request.data.auth_crap.nt_resp);
+
+ request.data.auth_crap.lm_resp_len = 24;
+ request.data.auth_crap.nt_resp_len = 24;
+
+ result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
+
+ /* Display response */
+
+ printf("challenge/response password authentication %s\n",
+ (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+
+ return result == NSS_STATUS_SUCCESS;
+}
+
/* Print domain users */
static BOOL print_domain_users(void)
@@ -273,8 +352,8 @@ static BOOL print_domain_users(void)
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -301,8 +380,8 @@ static BOOL print_domain_groups(void)
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -324,18 +403,20 @@ static BOOL print_domain_groups(void)
static void usage(void)
{
- printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm\n");
- printf("\t-u\tlists all domain users\n");
- printf("\t-g\tlists all domain groups\n");
- printf("\t-n name\tconverts name to sid\n");
- printf("\t-s sid\tconverts sid to name\n");
- printf("\t-U uid\tconverts uid to sid\n");
- printf("\t-G gid\tconverts gid to sid\n");
- printf("\t-S sid\tconverts sid to uid\n");
- printf("\t-Y sid\tconverts sid to gid\n");
- printf("\t-t\tcheck shared secret\n");
- printf("\t-m\tlist trusted domains\n");
- printf("\t-r user\tget user groups\n");
+ printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
+ "| -a user%%password\n");
+ printf("\t-u\t\t\tlists all domain users\n");
+ printf("\t-g\t\t\tlists all domain groups\n");
+ printf("\t-n name\t\t\tconverts name to sid\n");
+ printf("\t-s sid\t\t\tconverts sid to name\n");
+ printf("\t-U uid\t\t\tconverts uid to sid\n");
+ printf("\t-G gid\t\t\tconverts gid to sid\n");
+ printf("\t-S sid\t\t\tconverts sid to uid\n");
+ printf("\t-Y sid\t\t\tconverts sid to gid\n");
+ printf("\t-t\t\t\tcheck shared secret\n");
+ printf("\t-m\t\t\tlist trusted domains\n");
+ printf("\t-r user\t\t\tget user groups\n");
+ printf("\t-a user%%password\tauthenticate user\n");
}
/* Main program */
@@ -358,14 +439,12 @@ int main(int argc, char **argv)
}
TimeInit();
- charset_initialise();
if (!lp_load(CONFIGFILE, True, False, False)) {
DEBUG(0, ("error opening config file\n"));
exit(1);
}
- codepage_initialise(lp_client_code_page());
load_interfaces();
/* Parse command line options */
@@ -375,7 +454,7 @@ int main(int argc, char **argv)
return 1;
}
- while ((opt = getopt(argc, argv, "ugs:n:U:G:S:Y:tmr:")) != EOF) {
+ while ((opt = getopt(argc, argv, "ugs:n:U:G:S:Y:tmr:a:")) != EOF) {
switch (opt) {
case 'u':
if (!print_domain_users()) {
@@ -448,7 +527,26 @@ int main(int argc, char **argv)
return 1;
}
break;
+ case 'a': {
+ BOOL got_error = False;
+
+ if (!wbinfo_auth(optarg)) {
+ printf("Could not authenticate user %s with "
+ "plaintext password\n", optarg);
+ got_error = True;
+ }
+
+ if (!wbinfo_auth_crap(optarg)) {
+ printf("Could not authenticate user %s with "
+ "challenge/response\n", optarg);
+ got_error = True;
+ }
+
+ if (got_error)
+ return 1;
+ break;
+ }
/* Invalid option */
default:
diff --git a/source/nsswitch/winbind_nss.c b/source/nsswitch/winbind_nss.c
index 04b576a7a53..a2816bfdd3f 100644
--- a/source/nsswitch/winbind_nss.c
+++ b/source/nsswitch/winbind_nss.c
@@ -73,33 +73,27 @@ static char *get_static(char **buffer, int *buflen, int len)
lib/util_str.c as I really don't want to have to link in any other
objects if I can possibly avoid it. */
-static char *last_ptr = NULL;
-
-BOOL next_token(char **ptr, char *buff, char *sep, size_t bufsize)
+BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
{
char *s;
BOOL quoted;
size_t len=1;
-
- if (!ptr) ptr = &last_ptr;
+
if (!ptr) return(False);
-
+
s = *ptr;
-
+
/* default to simple separators */
if (!sep) sep = " \t\n\r";
-
+
/* find the first non sep char */
- while(*s && strchr(sep,*s)) s++;
-
+ while (*s && strchr(sep,*s)) s++;
+
/* nothing left? */
if (! *s) return(False);
-
+
/* copy over the token */
- for (quoted = False;
- len < bufsize && *s && (quoted || !strchr(sep,*s));
- s++) {
-
+ for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) {
if (*s == '\"') {
quoted = !quoted;
} else {
@@ -107,14 +101,14 @@ BOOL next_token(char **ptr, char *buff, char *sep, size_t bufsize)
*buff++ = *s;
}
}
-
+
*ptr = (*s) ? s+1 : s;
*buff = 0;
- last_ptr = *ptr;
-
+
return(True);
}
+
/* Fill a pwent structure from a winbindd_response structure. We use
the static data passed to us by libc to put strings and stuff in.
Return NSS_STATUS_TRYAGAIN if we run out of memory. */
@@ -632,8 +626,8 @@ _nss_winbind_getgrent_r(struct group *result,
num_gr_cache * sizeof(struct winbindd_gr);
ret = fill_grent(result, &gr_cache[ndx_gr_cache],
- (char *)(getgrent_response.extra_data +
- mem_ofs), &buffer, &buflen);
+ ((char *)getgrent_response.extra_data)+mem_ofs,
+ &buffer, &buflen);
/* Out of memory - try again */
diff --git a/source/nsswitch/winbind_nss_config.h b/source/nsswitch/winbind_nss_config.h
index 5c09a5dd1bc..88561ee8084 100644
--- a/source/nsswitch/winbind_nss_config.h
+++ b/source/nsswitch/winbind_nss_config.h
@@ -22,23 +22,13 @@
Boston, MA 02111-1307, USA.
*/
-#ifndef _NTDOM_CONFIG_H
-#define _NTDOM_CONFIG_H
+#ifndef _WINBIND_NSS_CONFIG_H
+#define _WINBIND_NSS_CONFIG_H
/* Include header files from data in config.h file */
#include <config.h>
-#ifdef RELIANTUNIX
-/*
- * <unistd.h> has to be included before any other to get
- * large file support on Reliant UNIX. Yes, it's broken :-).
- */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#endif /* RELIANTUNIX */
-
#include <stdio.h>
#ifdef HAVE_STDLIB_H
@@ -53,7 +43,7 @@
#include <sys/socket.h>
#endif
-#ifdef HAVE_SYS_UN_H
+#ifdef HAVE_UNIXSOCKET
#include <sys/un.h>
#endif
@@ -65,43 +55,15 @@
#include <grp.h>
#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <pwd.h>
-
-#ifdef HAVE_NSS_COMMON_H
-/* Sun Solaris */
-
-#include <nss_common.h>
-#include <nss_dbdefs.h>
-#include <nsswitch.h>
-
-typedef nss_status_t NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-#elif HAVE_NSS_H
-/* GNU */
-
-#include <nss.h>
-
-typedef enum nss_status NSS_STATUS;
-
-#else /* Nothing's defined. Neither gnu nor sun */
-
-typedef enum
-{
- NSS_STATUS_SUCCESS,
- NSS_STATUS_NOTFOUND,
- NSS_STATUS_UNAVAIL,
- NSS_STATUS_TRYAGAIN
-} NSS_STATUS;
-
-#endif
+#include "nsswitch/nss.h"
/* Declarations for functions in winbind_nss.c
needed in winbind_nss_solaris.c (solaris wrapper to nss) */
@@ -178,6 +140,7 @@ typedef int BOOL;
#ifndef S_IFSOCK
#define S_IFSOCK S_IFIFO
#endif
+
#ifndef S_ISSOCK
#define S_ISSOCK(mode) ((mode & S_IFSOCK) == S_IFSOCK)
#endif
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index acb251950ad..1a76396d9c6 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -23,17 +23,29 @@
#include "winbindd.h"
+pstring servicesf = CONFIGFILE;
+
/* List of all connected clients */
-static struct winbindd_cli_state *client_list;
+struct winbindd_cli_state *client_list;
+static int num_clients;
/* Reload configuration */
-static BOOL reload_services_file(void)
+static BOOL reload_services_file(BOOL test)
{
- pstring servicesf = CONFIGFILE;
BOOL ret;
+ if (lp_loaded()) {
+ pstring fname;
+
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
reopen_logs();
ret = lp_load(servicesf,False,False,True);
@@ -43,61 +55,75 @@ static BOOL reload_services_file(void)
return(ret);
}
-/* Print client information */
-
-static void do_print_client_info(void)
+void winbindd_dump_status(void)
{
- struct winbindd_cli_state *client;
- int i;
-
- if (client_list == NULL) {
- DEBUG(0, ("no clients in list\n"));
- return;
- }
+ struct winbindd_cli_state *tmp;
+
+ DEBUG(0, ("Global status for winbindd:\n"));
+
+ /* Print client state information */
+
+ DEBUG(0, ("\t%d clients currently active\n", num_clients));
+
+ if (DEBUGLEVEL >= 2) {
+ DEBUG(2, ("\tclient list:\n"));
+ for(tmp = client_list; tmp; tmp = tmp->next) {
+ DEBUG(2, ("\t\tpid %d, sock %d, rbl %d, wbl %d\n",
+ tmp->pid, tmp->sock, tmp->read_buf_len,
+ tmp->write_buf_len));
+ }
+ }
+}
- DEBUG(0, ("client list is:\n"));
+/* Print winbindd status to log file */
- for (client = client_list, i = 0; client; client = client->next) {
- DEBUG(0, ("client %3d: pid = %5d fd = %d read = %4d write = %4d\n",
- i, client->pid, client->sock, client->read_buf_len,
- client->write_buf_len));
- i++;
- }
+static void do_print_winbindd_status(void)
+{
+ winbindd_dump_status();
+ winbindd_idmap_dump_status();
+ winbindd_cache_dump_status();
}
/* Flush client cache */
static void do_flush_caches(void)
{
- /* Clear cached user and group enumation info */
-
- winbindd_flush_cache();
+ /* Clear cached user and group enumation info */
+
+ winbindd_flush_cache();
}
/* Handle the signal by unlinking socket and exiting */
static void termination_handler(int signum)
{
- pstring path;
-
- /* Remove socket file */
+ pstring path;
+
+ /* Remove socket file */
+
+ snprintf(path, sizeof(path), "%s/%s",
+ WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
+ unlink(path);
+
+ exit(0);
+}
- slprintf(path, sizeof(path)-1, "%s/%s",
- WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
- unlink(path);
+static BOOL print_winbindd_status;
- exit(0);
+static void sigusr1_handler(int signum)
+{
+ BlockSignals(True, SIGUSR1);
+ print_winbindd_status = True;
+ BlockSignals(False, SIGUSR1);
}
-static BOOL print_client_info;
-
-static BOOL flush_cache;
+static BOOL do_sighup;
static void sighup_handler(int signum)
{
- BlockSignals(True, SIGHUP);
- flush_cache = True;
- BlockSignals(False, SIGHUP);
+ BlockSignals(True, SIGHUP);
+ do_sighup = True;
+ BlockSignals(False, SIGHUP);
}
/* Create winbindd socket */
@@ -120,14 +146,14 @@ static int create_sock(void)
if (mkdir(WINBINDD_SOCKET_DIR, 0755) == -1) {
DEBUG(0, ("error creating socket directory %s: %s\n",
- WINBINDD_SOCKET_DIR, sys_errlist[errno]));
+ WINBINDD_SOCKET_DIR, strerror(errno)));
return -1;
}
} else {
DEBUG(0, ("lstat failed on socket directory %s: %s\n",
- WINBINDD_SOCKET_DIR, sys_errlist[errno]));
+ WINBINDD_SOCKET_DIR, strerror(errno)));
return -1;
}
@@ -141,7 +167,7 @@ static int create_sock(void)
return -1;
}
- if ((st.st_uid != 0) || ((st.st_mode & 0777) != 0755)) {
+ if ((st.st_mode & 0777) != 0755) {
DEBUG(0, ("invalid permissions on socket directory %s\n",
WINBINDD_SOCKET_DIR));
return -1;
@@ -159,7 +185,7 @@ static int create_sock(void)
return -1;
}
- slprintf(path, sizeof(path)-1, "%s/%s",
+ snprintf(path, sizeof(path), "%s/%s",
WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
unlink(path);
@@ -170,7 +196,7 @@ static int create_sock(void)
if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
DEBUG(0, ("bind failed on winbind socket %s: %s\n",
path,
- sys_errlist[errno]));
+ strerror(errno)));
close(sock);
return -1;
}
@@ -178,7 +204,7 @@ static int create_sock(void)
if (listen(sock, 5) == -1) {
DEBUG(0, ("listen failed on winbind socket %s: %s\n",
path,
- sys_errlist[errno]));
+ strerror(errno)));
close(sock);
return -1;
}
@@ -190,378 +216,421 @@ static int create_sock(void)
return sock;
}
-static void process_request(struct winbindd_cli_state *state)
-{
- /* Process command */
+struct dispatch_table {
+ enum winbindd_cmd cmd;
+ enum winbindd_result (*fn)(struct winbindd_cli_state *state);
+};
- state->response.result = WINBINDD_ERROR;
- state->response.length = sizeof(struct winbindd_response);
+static struct dispatch_table dispatch_table[] = {
+
+ /* User functions */
- DEBUG(3,("processing command %s from pid %d\n",
- winbindd_cmd_to_string(state->request.cmd), state->pid));
+ { WINBINDD_GETPWNAM_FROM_USER, winbindd_getpwnam_from_user },
+ { WINBINDD_GETPWNAM_FROM_UID, winbindd_getpwnam_from_uid },
+ { WINBINDD_SETPWENT, winbindd_setpwent },
+ { WINBINDD_ENDPWENT, winbindd_endpwent },
+ { WINBINDD_GETPWENT, winbindd_getpwent },
+ { WINBINDD_GETGROUPS, winbindd_getgroups },
- if (!server_state.lsa_handle_open) return;
+ /* Group functions */
- switch(state->request.cmd) {
-
- /* User functions */
-
- case WINBINDD_GETPWNAM_FROM_USER:
- state->response.result = winbindd_getpwnam_from_user(state);
- break;
-
- case WINBINDD_GETPWNAM_FROM_UID:
- state->response.result = winbindd_getpwnam_from_uid(state);
- break;
-
- case WINBINDD_SETPWENT:
- state->response.result = winbindd_setpwent(state);
- break;
-
- case WINBINDD_ENDPWENT:
- state->response.result = winbindd_endpwent(state);
- break;
-
- case WINBINDD_GETPWENT:
- state->response.result = winbindd_getpwent(state);
- break;
+ { WINBINDD_GETGRNAM_FROM_GROUP, winbindd_getgrnam_from_group },
+ { WINBINDD_GETGRNAM_FROM_GID, winbindd_getgrnam_from_gid },
+ { WINBINDD_SETGRENT, winbindd_setgrent },
+ { WINBINDD_ENDGRENT, winbindd_endgrent },
+ { WINBINDD_GETGRENT, winbindd_getgrent },
- /* Group functions */
-
- case WINBINDD_GETGRNAM_FROM_GROUP:
- state->response.result = winbindd_getgrnam_from_group(state);
- break;
-
- case WINBINDD_GETGRNAM_FROM_GID:
- state->response.result = winbindd_getgrnam_from_gid(state);
- break;
-
- case WINBINDD_SETGRENT:
- state->response.result = winbindd_setgrent(state);
- break;
-
- case WINBINDD_ENDGRENT:
- state->response.result = winbindd_endgrent(state);
- break;
-
- case WINBINDD_GETGRENT:
- state->response.result = winbindd_getgrent(state);
- break;
+ /* PAM auth functions */
- /* pam auth functions */
- case WINBINDD_PAM_AUTH:
- state->response.result = winbindd_pam_auth(state);
- break;
+ { WINBINDD_PAM_AUTH, winbindd_pam_auth },
+ { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok },
- /* Oops */
-
- default:
- DEBUG(0, ("oops - unknown winbindd command %d\n", state->request.cmd));
- break;
- }
-}
+ /* Enumeration functions */
-/* Process a new connection by adding it to the client connection list */
+ { WINBINDD_LIST_USERS, winbindd_list_users },
+ { WINBINDD_LIST_GROUPS, winbindd_list_groups },
+ { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains },
-static void new_connection(int accept_sock)
-{
- struct sockaddr_un sunaddr;
- struct winbindd_cli_state *state;
- socklen_t len
- int sock;
-
- /* Accept connection */
-
- len = sizeof(sunaddr);
- if ((sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len))
- == -1) {
-
- return;
- }
+ /* SID related functions */
- DEBUG(6,("accepted socket %d\n", sock));
+ { WINBINDD_LOOKUPSID, winbindd_lookupsid },
+ { WINBINDD_LOOKUPNAME, winbindd_lookupname },
- /* Create new connection structure */
+ /* S*RS related functions */
- if ((state = (struct winbindd_cli_state *)
- malloc(sizeof(*state))) == NULL) {
+ { WINBINDD_SID_TO_UID, winbindd_sid_to_uid },
+ { WINBINDD_SID_TO_GID, winbindd_sid_to_gid },
+ { WINBINDD_GID_TO_SID, winbindd_gid_to_sid },
+ { WINBINDD_UID_TO_SID, winbindd_uid_to_sid },
- return;
- }
+ /* Miscellaneous */
- ZERO_STRUCTP(state);
- state->sock = sock;
+ { WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct },
- /* Add to connection list */
+ /* End of list */
- DLIST_ADD(client_list, state);
-}
+ { WINBINDD_NUM_CMDS, NULL }
+};
-/* Remove a client connection from client connection list */
-
-static void remove_client(struct winbindd_cli_state *state)
+static void process_request(struct winbindd_cli_state *state)
{
- /* It's a dead client - hold a funeral */
+ struct dispatch_table *table = dispatch_table;
- if (state != NULL) {
+ /* Free response data - we may be interrupted and receive another
+ command before being able to send this data off. */
- /* Close socket */
+ safe_free(state->response.extra_data);
- close(state->sock);
+ ZERO_STRUCT(state->response);
- /* Free any getent state */
+ state->response.result = WINBINDD_ERROR;
+ state->response.length = sizeof(struct winbindd_response);
- free_getent_state(state->getpwent_state);
- free_getent_state(state->getgrent_state);
+ /* Process command */
- /* Free any extra data */
+ if (!server_state.lsa_handle_open) return;
- safe_free(state->response.extra_data);
+ for (table = dispatch_table; table->fn; table++) {
+ if (state->request.cmd == table->cmd) {
+ state->response.result = table->fn(state);
+ break;
+ }
+ }
- /* Remove from list and free */
+ /* In case extra data pointer is NULL */
- DLIST_REMOVE(client_list, state);
- free(state);
- }
+ if (!state->response.extra_data) {
+ state->response.length = sizeof(struct winbindd_response);
+ }
}
-/* Process a complete received packet from a client */
+/* Process a new connection by adding it to the client connection list */
-static void process_packet(struct winbindd_cli_state *state)
+static void new_connection(int accept_sock)
{
- /* Process request */
+ struct sockaddr_un sunaddr;
+ struct winbindd_cli_state *state;
+ socklen_t len;
+ int sock;
+
+ /* Accept connection */
+
+ len = sizeof(sunaddr);
+ if ((sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len))
+ == -1) {
+
+ return;
+ }
+
+ DEBUG(6,("accepted socket %d\n", sock));
+
+ /* Create new connection structure */
+
+ if ((state = (struct winbindd_cli_state *)
+ malloc(sizeof(*state))) == NULL) {
+
+ return;
+ }
+
+ ZERO_STRUCTP(state);
+ state->sock = sock;
+
+ /* Add to connection list */
+
+ DLIST_ADD(client_list, state);
+ num_clients++;
+}
- state->pid = state->request.pid;
+/* Remove a client connection from client connection list */
- process_request(state);
+static void remove_client(struct winbindd_cli_state *state)
+{
+ /* It's a dead client - hold a funeral */
+
+ if (state != NULL) {
+
+ /* Close socket */
+
+ close(state->sock);
+
+ /* Free any getent state */
+
+ free_getent_state(state->getpwent_state);
+ free_getent_state(state->getgrent_state);
+
+ /* We may have some extra data that was not freed if the
+ client was killed unexpectedly */
+
+ safe_free(state->response.extra_data);
+
+ /* Remove from list and free */
+
+ DLIST_REMOVE(client_list, state);
+ free(state);
+ num_clients--;
+ }
+}
- /* Update client state */
+/* Process a complete received packet from a client */
- state->read_buf_len = 0;
- state->write_buf_len = sizeof(state->response);
+static void process_packet(struct winbindd_cli_state *state)
+{
+ /* Process request */
+
+ state->pid = state->request.pid;
+
+ process_request(state);
+
+ /* Update client state */
+
+ state->read_buf_len = 0;
+ state->write_buf_len = sizeof(struct winbindd_response);
}
/* Read some data from a client connection */
static void client_read(struct winbindd_cli_state *state)
{
- int n;
+ int n;
- /* Read data */
-
- n = read(state->sock, state->read_buf_len + (char *)&state->request,
- sizeof(state->request) - state->read_buf_len);
-
- /* Read failed, kill client */
-
- if (n == -1 || n == 0) {
- DEBUG(5,("read failed on sock %d, pid %d: %s\n",
- state->sock, state->pid,
- (n == -1) ? sys_errlist[errno] : "EOF"));
-
- state->finished = True;
- return;
- }
-
- /* Update client state */
-
- state->read_buf_len += n;
+ /* Read data */
+
+ n = read(state->sock, state->read_buf_len + (char *)&state->request,
+ sizeof(state->request) - state->read_buf_len);
+
+ /* Read failed, kill client */
+
+ if (n == -1 || n == 0) {
+ DEBUG(5,("read failed on sock %d, pid %d: %s\n",
+ state->sock, state->pid,
+ (n == -1) ? strerror(errno) : "EOF"));
+
+ state->finished = True;
+ return;
+ }
+
+ /* Update client state */
+
+ state->read_buf_len += n;
}
/* Write some data to a client connection */
static void client_write(struct winbindd_cli_state *state)
{
- char *data;
- int n;
-
- /* Write data */
-
- if (state->write_extra_data) {
-
- /* Write extra data */
-
- data = (char *)state->response.extra_data +
- state->response.length - sizeof(struct winbindd_response) -
- state->write_buf_len;
-
- } else {
-
- /* Write response structure */
-
- data = (char *)&state->response + sizeof(state->response) -
- state->write_buf_len;
- }
-
- n = write(state->sock, data, state->write_buf_len);
-
- /* Write failed, kill cilent */
-
- if (n == -1 || n == 0) {
-
- DEBUG(3,("write failed on sock %d, pid %d: %s\n",
- state->sock, state->pid,
- (n == -1) ? sys_errlist[errno] : "EOF"));
-
- state->finished = True;
- return;
- }
-
- /* Update client state */
-
- state->write_buf_len -= n;
-
- /* Have we written all data? */
+ char *data;
+ int num_written;
+
+ /* Write some data */
+
+ if (!state->write_extra_data) {
+
+ /* Write response structure */
+
+ data = (char *)&state->response + sizeof(state->response) -
+ state->write_buf_len;
+
+ } else {
+
+ /* Write extra data */
+
+ data = (char *)state->response.extra_data +
+ state->response.length -
+ sizeof(struct winbindd_response) -
+ state->write_buf_len;
+ }
+
+ num_written = write(state->sock, data, state->write_buf_len);
+
+ /* Write failed, kill cilent */
+
+ if (num_written == -1 || num_written == 0) {
+
+ DEBUG(3,("write failed on sock %d, pid %d: %s\n",
+ state->sock, state->pid,
+ (num_written == -1) ? strerror(errno) : "EOF"));
+
+ state->finished = True;
+
+ safe_free(state->response.extra_data);
+ state->response.extra_data = NULL;
+
+ return;
+ }
+
+ /* Update client state */
+
+ state->write_buf_len -= num_written;
+
+ /* Have we written all data? */
+
+ if (state->write_buf_len == 0) {
+
+ /* Take care of extra data */
+
+ if (state->write_extra_data) {
+
+ safe_free(state->response.extra_data);
+ state->response.extra_data = NULL;
+
+ state->write_extra_data = False;
+
+ } else if (state->response.length >
+ sizeof(struct winbindd_response)) {
+
+ /* Start writing extra data */
+
+ state->write_buf_len =
+ state->response.length -
+ sizeof(struct winbindd_response);
+
+ state->write_extra_data = True;
+ }
+ }
+}
- if (state->write_buf_len == 0) {
+/* Process incoming clients on accept_sock. We use a tricky non-blocking,
+ non-forking, non-threaded model which allows us to handle many
+ simultaneous connections while remaining impervious to many denial of
+ service attacks. */
- /* Take care of extra data */
+static void process_loop(int accept_sock)
+{
+ /* We'll be doing this a lot */
- if (state->response.length > sizeof(struct winbindd_response)) {
+ while (1) {
+ struct winbindd_cli_state *state;
+ fd_set r_fds, w_fds;
+ int maxfd = accept_sock, selret;
+ struct timeval timeout;
- if (state->write_extra_data) {
+ /* Free up temporary memory */
- /* Already written extra data - free it */
+ lp_talloc_free();
- safe_free(state->response.extra_data);
- state->response.extra_data = NULL;
- state->write_extra_data = False;
+ /* Do any connection establishment that is needed */
- } else {
+ establish_connections(False); /* Honour timeout */
- /* Start writing extra data */
+ /* Initialise fd lists for select() */
- state->write_buf_len = state->response.length -
- sizeof(struct winbindd_response);
- state->write_extra_data = True;
- }
- }
- }
-}
+ FD_ZERO(&r_fds);
+ FD_ZERO(&w_fds);
+ FD_SET(accept_sock, &r_fds);
-/* Process incoming clients on accept_sock. We use a tricky non-blocking,
- non-forking, non-threaded model which allows us to handle many
- simultaneous connections while remaining impervious to many denial of
- service attacks. */
+ timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
+ timeout.tv_usec = 0;
-static void process_loop(int accept_sock)
-{
- /* We'll be doing this a lot */
+ /* Set up client readers and writers */
- while (1) {
- struct winbindd_cli_state *state;
- fd_set r_fds, w_fds;
- int maxfd = accept_sock, selret;
- struct timeval timeout;
+ state = client_list;
- /* do any connection establishment that is needed */
- establish_connections();
+ while (state) {
- /* Initialise fd lists for select() */
+ /* Dispose of client connection if it is marked as
+ finished */
- FD_ZERO(&r_fds);
- FD_ZERO(&w_fds);
- FD_SET(accept_sock, &r_fds);
+ if (state->finished) {
+ struct winbindd_cli_state *next = state->next;
- timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
- timeout.tv_usec = 0;
+ remove_client(state);
+ state = next;
+ continue;
+ }
- /* Set up client readers and writers */
+ /* Select requires we know the highest fd used */
- state = client_list;
+ if (state->sock > maxfd) maxfd = state->sock;
- while (state) {
- /* Dispose of client connection if it is marked as finished */
+ /* Add fd for reading */
- if (state->finished) {
- struct winbindd_cli_state *next = state->next;
+ if (state->read_buf_len != sizeof(state->request)) {
+ FD_SET(state->sock, &r_fds);
+ }
- remove_client(state);
- state = next;
- continue;
- }
+ /* Add fd for writing */
- /* Select requires we know the highest fd used */
+ if (state->write_buf_len) {
+ FD_SET(state->sock, &w_fds);
+ }
- if (state->sock > maxfd) maxfd = state->sock;
+ state = state->next;
+ }
- /* Add fd for reading */
+ /* Check signal handling things */
- if (state->read_buf_len != sizeof(state->request)) {
- FD_SET(state->sock, &r_fds);
- }
+ if (do_sighup) {
- /* Add fd for writing */
+ /* Flush winbindd cache */
- if (state->write_buf_len) {
- FD_SET(state->sock, &w_fds);
- }
+ do_flush_caches();
+ reload_services_file(True);
- state = state->next;
- }
+ /* Close and re-open all connections. This will also
+ refresh the trusted domains list */
- /* Check signal handling things */
+ winbindd_kill_all_connections();
+ establish_connections(True); /* Force re-establish */
- if (flush_cache) {
- do_flush_caches();
- reload_services_file();
- flush_cache = False;
- }
+ do_sighup = False;
+ }
- if (print_client_info) {
- do_print_client_info();
- print_client_info = False;
- }
+ if (print_winbindd_status) {
+ do_print_winbindd_status();
+ print_winbindd_status = False;
+ }
- /* Call select */
+ /* Call select */
- selret = select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
+ selret = select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
- if (selret == 0) continue;
+ if (selret == 0) continue;
- if ((selret == -1 && errno != EINTR) || selret == 0) {
+ if ((selret == -1 && errno != EINTR) || selret == 0) {
- /* Select error, something is badly wrong */
+ /* Select error, something is badly wrong */
- perror("select");
- exit(1);
- }
+ perror("select");
+ exit(1);
+ }
- /* Create a new connection if accept_sock readable */
+ /* Create a new connection if accept_sock readable */
- if (selret > 0) {
+ if (selret > 0) {
- if (FD_ISSET(accept_sock, &r_fds)) {
- new_connection(accept_sock);
- }
+ if (FD_ISSET(accept_sock, &r_fds)) {
+ new_connection(accept_sock);
+ }
- /* Process activity on client connections */
+ /* Process activity on client connections */
- for (state = client_list; state ; state = state->next) {
+ for (state = client_list; state; state = state->next) {
- /* Data available for reading */
+ /* Data available for reading */
- if (FD_ISSET(state->sock, &r_fds)) {
+ if (FD_ISSET(state->sock, &r_fds)) {
- /* Read data */
+ /* Read data */
- client_read(state);
+ client_read(state);
- /* A request packet might be complete */
+ /* A request packet might be
+ complete */
- if (state->read_buf_len == sizeof(state->request)) {
- process_packet(state);
- }
- }
+ if (state->read_buf_len ==
+ sizeof(state->request)) {
+ process_packet(state);
+ }
+ }
- /* Data available for writing */
+ /* Data available for writing */
- if (FD_ISSET(state->sock, &w_fds)) {
- client_write(state);
- }
- }
- }
- }
+ if (FD_ISSET(state->sock, &w_fds)) {
+ client_write(state);
+ }
+ }
+ }
+ }
}
/* Main function */
@@ -570,87 +639,129 @@ struct winbindd_state server_state; /* Server state information */
int main(int argc, char **argv)
{
- extern pstring global_myname;
- extern pstring debugf;
- int accept_sock;
- BOOL interactive = False;
- int opt;
-
- while ((opt = getopt(argc, argv, "i")) != EOF) {
- switch (opt) {
+ extern pstring global_myname;
+ extern pstring debugf;
+ int accept_sock;
+ BOOL interactive = False;
+ int opt, new_debuglevel = -1;
+ extern fstring global_myworkgroup;
+
+ sec_init();
+
+ /* Set environment variable so we don't recursively call ourselves.
+ This may also be useful interactively. */
+ SETENV(WINBINDD_DONT_ENV, "1", 1);
+
+ /* Initialise samba/rpc client stuff */
+
+ while ((opt = getopt(argc, argv, "id:s:")) != EOF) {
+ switch (opt) {
+
+ /* Don't become a daemon */
+
case 'i':
interactive = True;
break;
+
+ /* Run with specified debug level */
+
+ case 'd':
+ new_debuglevel = atoi(optarg);
+ break;
+
+ /* Load a different smb.conf file */
+
+ case 's':
+ pstrcpy(servicesf,optarg);
+ break;
+
default:
- printf("Unknown option %c (%d)\n", (char)opt, opt);
+ printf("Unknown option %c\n", (char)opt);
exit(1);
}
- }
+ }
- /* Initialise samba/rpc client stuff */
- slprintf(debugf, sizeof(debugf)-1, "%s/log.winbindd", LOGFILEBASE);
- setup_logging("winbindd", interactive);
- reopen_logs();
+ snprintf(debugf, sizeof(debugf), "%s/log.winbindd", LOGFILEBASE);
+ setup_logging("winbindd", interactive);
+ reopen_logs();
- if (!*global_myname) {
- char *p;
+ if (!*global_myname) {
+ char *p;
- fstrcpy(global_myname, myhostname());
- p = strchr(global_myname, '.');
- if (p) {
- *p = 0;
- }
- }
+ fstrcpy(global_myname, myhostname());
+ p = strchr(global_myname, '.');
+ if (p) {
+ *p = 0;
+ }
+ }
- TimeInit();
- charset_initialise();
- codepage_initialise(lp_client_code_page());
+ TimeInit();
+ charset_initialise();
- if (!lp_load(CONFIGFILE, True, False, False)) {
- DEBUG(0, ("error opening config file\n"));
- exit(1);
- }
+ if (!reload_services_file(False)) {
+ DEBUG(0, ("error opening config file\n"));
+ exit(1);
+ }
- if (!interactive) {
- become_daemon();
- }
- load_interfaces();
+ if (new_debuglevel != -1) {
+ DEBUGLEVEL = new_debuglevel;
+ }
- secrets_init();
+ codepage_initialise(lp_client_code_page());
+ fstrcpy(global_myworkgroup, lp_workgroup());
- ZERO_STRUCT(server_state);
+ if (!interactive) {
+ become_daemon();
+ }
- /* Winbind daemon initialisation */
- if (!winbindd_param_init()) {
- return 1;
- }
+ load_interfaces();
- if (!winbindd_idmap_init()) {
- return 1;
- }
+ secrets_init();
- winbindd_cache_init();
+ ZERO_STRUCT(server_state);
- /* Setup signal handlers */
+ /* Winbind daemon initialisation */
- CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */
- CatchSignal(SIGQUIT, termination_handler);
- CatchSignal(SIGTERM, termination_handler);
+ if (!winbindd_param_init()) {
+ return 1;
+ }
- CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
+ if (!winbindd_idmap_init()) {
+ return 1;
+ }
- CatchSignal(SIGHUP, sighup_handler);
+ winbindd_cache_init();
- /* Create UNIX domain socket */
+ /* Unblock all signals we are interested in as they may have been
+ blocked by the parent process. */
- if ((accept_sock = create_sock()) == -1) {
- DEBUG(0, ("failed to create socket\n"));
- return 1;
- }
+ BlockSignals(False, SIGINT);
+ BlockSignals(False, SIGQUIT);
+ BlockSignals(False, SIGTERM);
+ BlockSignals(False, SIGUSR1);
+ BlockSignals(False, SIGHUP);
+
+ /* Setup signal handlers */
+
+ CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */
+ CatchSignal(SIGQUIT, termination_handler);
+ CatchSignal(SIGTERM, termination_handler);
+
+ CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
+
+ CatchSignal(SIGUSR1, sigusr1_handler); /* Debugging sigs */
+ CatchSignal(SIGHUP, sighup_handler);
+
+ /* Create UNIX domain socket */
+
+ if ((accept_sock = create_sock()) == -1) {
+ DEBUG(0, ("failed to create socket\n"));
+ return 1;
+ }
- /* Loop waiting for requests */
+ /* Loop waiting for requests */
- process_loop(accept_sock);
+ process_loop(accept_sock);
- return 0;
+ return 0;
}
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index d333b32bcfc..f7e86a8a435 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -49,12 +49,24 @@ struct winbindd_cli_state {
struct getent_state *getgrent_state; /* State for getgrent() */
};
+/* State between get{pw,gr}ent() calls */
+
struct getent_state {
- struct getent_state *prev, *next;
- struct acct_info *sam_entries;
- uint32 sam_entry_index, num_sam_entries;
- struct winbindd_domain *domain;
- BOOL got_sam_entries;
+ struct getent_state *prev, *next;
+ void *sam_entries;
+ uint32 sam_entry_index, num_sam_entries;
+ uint32 dispinfo_ndx;
+ uint32 grp_query_start_ndx;
+ BOOL got_all_sam_entries, got_sam_entries;
+ struct winbindd_domain *domain;
+};
+
+/* Storage for cached getpwent() user entries */
+
+struct getpwent_user {
+ fstring name; /* Account name */
+ fstring gecos; /* User information */
+ uint32 user_rid, group_rid; /* NT user and group rids */
};
/* Server state structure */
@@ -68,7 +80,7 @@ struct winbindd_state {
gid_t gid_low, gid_high; /* Range of gids to allocate */
/* Cached handle to lsa pipe */
- POLICY_HND lsa_handle;
+ CLI_POLICY_HND lsa_handle;
BOOL lsa_handle_open;
BOOL pwdb_initialised;
};
@@ -79,19 +91,21 @@ extern struct winbindd_state server_state; /* Server information */
struct winbindd_domain {
- /* Domain information */
-
- fstring name; /* Domain name */
- fstring controller; /* NetBIOS name of DC */
-
- DOM_SID sid; /* SID for this domain */
- BOOL got_domain_info; /* Got controller and sid */
+ /* Domain information */
- /* Cached handles to samr pipe */
- POLICY_HND sam_handle, sam_dom_handle;
- BOOL sam_handle_open, sam_dom_handle_open;
-
- struct winbindd_domain *prev, *next; /* Linked list info */
+ fstring name; /* Domain name */
+ fstring controller; /* NetBIOS name of DC */
+
+ DOM_SID sid; /* SID for this domain */
+ BOOL got_domain_info; /* Got controller and sid */
+
+ /* Cached handles to samr pipe */
+
+ CLI_POLICY_HND sam_handle, sam_dom_handle;
+ BOOL sam_handle_open, sam_dom_handle_open;
+ time_t last_check;
+
+ struct winbindd_domain *prev, *next; /* Linked list info */
};
extern struct winbindd_domain *domain_list; /* List of domains we know */
@@ -99,8 +113,23 @@ extern struct winbindd_domain *domain_list; /* List of domains we know */
#include "winbindd_proto.h"
#include "rpc_parse.h"
+#include "rpc_client.h"
#define WINBINDD_ESTABLISH_LOOP 30
#define DOM_SEQUENCE_NONE ((uint32)-1)
+/* SETENV */
+#if HAVE_SETENV
+#define SETENV(name, value, overwrite) setenv(name,value,overwrite)
+#elif HAVE_PUTENV
+#define SETENV(name, value, overwrite) \
+{ \
+ fstring envvar; \
+ slprintf(envvar, sizeof(fstring), "%s=%s", name, value); \
+ putenv(envvar); \
+}
+#else
+#define SETENV(name, value, overwrite) ;
+#endif
+
#endif /* _WINBINDD_H */
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index bc519430f3a..07b1cab5830 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -38,10 +38,10 @@ struct cache_rec {
void winbindd_cache_init(void)
{
/* Open tdb cache */
- unlink(lock_path("winbindd_cache.tdb"));
+
if (!(cache_tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 0,
- TDB_NOLOCK,
- O_RDWR | O_CREAT, 0600))) {
+ TDB_NOLOCK, O_RDWR | O_CREAT | O_TRUNC,
+ 0600))) {
DEBUG(0, ("Unable to open tdb cache - user and group caching "
"disabled\n"));
}
@@ -55,8 +55,7 @@ static uint32 cached_sequence_number(char *domain_name)
struct cache_rec rec;
time_t t = time(NULL);
- slprintf(keystr, sizeof(keystr)-1, "CACHESEQ/%s", domain_name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ snprintf(keystr, sizeof(keystr), "CACHESEQ/%s", domain_name);
dbuf = tdb_fetch_by_string(cache_tdb, keystr);
if (!dbuf.dptr || dbuf.dsize != sizeof(rec)) {
goto refetch;
@@ -65,7 +64,7 @@ static uint32 cached_sequence_number(char *domain_name)
free(dbuf.dptr);
if (t < (rec.mod_time + lp_winbind_cache_time())) {
- DEBUG(4,("cached sequence number for %s is %u\n",
+ DEBUG(3,("cached sequence number for %s is %u\n",
domain_name, (unsigned)rec.seq_num));
return rec.seq_num;
}
@@ -82,54 +81,56 @@ static uint32 cached_sequence_number(char *domain_name)
static BOOL cache_domain_expired(char *domain_name, uint32 seq_num)
{
if (cached_sequence_number(domain_name) != seq_num) {
- DEBUG(4,("seq %u for %s has expired\n", (unsigned)seq_num, domain_name));
+ DEBUG(3,("seq %u for %s has expired\n", (unsigned)seq_num,
+ domain_name));
return True;
}
return False;
}
-static void set_cache_sequence_number(char *domain_name, char *cache_type, char *subkey)
+static void set_cache_sequence_number(char *domain_name, char *cache_type,
+ char *subkey)
{
fstring keystr;
- slprintf(keystr,sizeof(keystr)-1,"CACHESEQ %s/%s/%s",
+
+ snprintf(keystr, sizeof(keystr),"CACHESEQ %s/%s/%s",
domain_name, cache_type, subkey?subkey:"");
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+
tdb_store_int(cache_tdb, keystr, cached_sequence_number(domain_name));
}
-static uint32 get_cache_sequence_number(char *domain_name, char *cache_type, char *subkey)
+static uint32 get_cache_sequence_number(char *domain_name, char *cache_type,
+ char *subkey)
{
fstring keystr;
uint32 seq_num;
- slprintf(keystr,sizeof(keystr)-1,"CACHESEQ %s/%s/%s",
+
+ snprintf(keystr, sizeof(keystr), "CACHESEQ %s/%s/%s",
domain_name, cache_type, subkey?subkey:"");
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
seq_num = (uint32)tdb_fetch_int(cache_tdb, keystr);
- DEBUG(4,("%s is %u\n", keystr, (unsigned)seq_num));
+
+ DEBUG(3,("%s is %u\n", keystr, (unsigned)seq_num));
+
return seq_num;
}
/* Fill the user or group cache with supplied data */
-static void fill_cache(char *domain_name, char *cache_type,
- struct acct_info *sam_entries,
- int num_sam_entries)
+
+static void store_cache(char *domain_name, char *cache_type,
+ void *sam_entries, int buflen)
{
fstring keystr;
if (lp_winbind_cache_time() == 0) return;
/* Error check */
- if (!sam_entries || (num_sam_entries == 0)) return;
-
- DEBUG(4, ("filling %s cache for domain %s with %d entries\n",
- cache_type, domain_name, num_sam_entries));
+ if (!sam_entries || buflen == 0) return;
/* Store data as a mega-huge chunk in the tdb */
- slprintf(keystr, sizeof(keystr)-1, "%s CACHE DATA/%s", cache_type,
+ snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
domain_name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
- tdb_store_by_string(cache_tdb, keystr,
- sam_entries, sizeof(struct acct_info) * num_sam_entries);
+
+ tdb_store_by_string(cache_tdb, keystr, sam_entries, buflen);
/* Stamp cache with current seq number */
set_cache_sequence_number(domain_name, cache_type, NULL);
@@ -137,97 +138,124 @@ static void fill_cache(char *domain_name, char *cache_type,
/* Fill the user cache with supplied data */
-void winbindd_fill_user_cache(char *domain_name,
- struct acct_info *sam_entries,
- int num_sam_entries)
+void winbindd_store_user_cache(char *domain,
+ struct getpwent_user *sam_entries,
+ int num_sam_entries)
{
- fill_cache(domain_name, CACHE_TYPE_USER, sam_entries, num_sam_entries);
+ DEBUG(3, ("storing user cache %s/%d entries\n", domain,
+ num_sam_entries));
+
+ store_cache(domain, CACHE_TYPE_USER, sam_entries,
+ num_sam_entries * sizeof(struct getpwent_user));
}
/* Fill the group cache with supplied data */
-void winbindd_fill_group_cache(char *domain_name,
- struct acct_info *sam_entries,
- int num_sam_entries)
+void winbindd_store_group_cache(char *domain,
+ struct acct_info *sam_entries,
+ int num_sam_entries)
{
- fill_cache(domain_name, CACHE_TYPE_GROUP, sam_entries, num_sam_entries);
+ DEBUG(0, ("storing group cache %s/%d entries\n", domain,
+ num_sam_entries));
+
+ store_cache(domain, CACHE_TYPE_GROUP, sam_entries,
+ num_sam_entries * sizeof(struct acct_info));
}
-static void fill_cache_entry(char *domain, char *cache_type, char *name, void *buf, int len)
+static void store_cache_entry(char *domain, char *cache_type, char *name,
+ void *buf, int len)
{
fstring keystr;
/* Create key for store */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s", cache_type, domain, name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
-
- DEBUG(4, ("filling cache entry %s\n", keystr));
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain, name);
/* Store it */
tdb_store_by_string(cache_tdb, keystr, buf, len);
}
/* Fill a user info cache entry */
-void winbindd_fill_user_cache_entry(char *domain, char *user_name,
- struct winbindd_pw *pw)
+
+void winbindd_store_user_cache_entry(char *domain, char *user_name,
+ struct winbindd_pw *pw)
{
if (lp_winbind_cache_time() == 0) return;
- fill_cache_entry(domain, CACHE_TYPE_USER, user_name, pw, sizeof(struct winbindd_pw));
+ store_cache_entry(domain, CACHE_TYPE_USER, user_name, pw,
+ sizeof(struct winbindd_pw));
+
set_cache_sequence_number(domain, CACHE_TYPE_USER, user_name);
}
/* Fill a user uid cache entry */
-void winbindd_fill_uid_cache_entry(char *domain, uid_t uid,
+
+void winbindd_store_uid_cache_entry(char *domain, uid_t uid,
struct winbindd_pw *pw)
{
fstring uidstr;
if (lp_winbind_cache_time() == 0) return;
- slprintf(uidstr, sizeof(uidstr)-1, "#%u", (unsigned)uid);
- fill_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw, sizeof(struct winbindd_pw));
+ snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
+
+ DEBUG(3, ("storing uid cache entry %s/%s\n", domain, uidstr));
+
+ store_cache_entry(domain, CACHE_TYPE_USER, uidstr, pw,
+ sizeof(struct winbindd_pw));
+
set_cache_sequence_number(domain, CACHE_TYPE_USER, uidstr);
}
/* Fill a group info cache entry */
-void winbindd_fill_group_cache_entry(char *domain, char *group_name,
- struct winbindd_gr *gr, void *extra_data,
- int extra_data_len)
+void winbindd_store_group_cache_entry(char *domain, char *group_name,
+ struct winbindd_gr *gr, void *extra_data,
+ int extra_data_len)
{
fstring keystr;
if (lp_winbind_cache_time() == 0) return;
+ DEBUG(3, ("storing group cache entry %s/%s\n", domain, group_name));
+
/* Fill group data */
- fill_cache_entry(domain, CACHE_TYPE_GROUP, group_name, gr, sizeof(struct winbindd_gr));
+
+ store_cache_entry(domain, CACHE_TYPE_GROUP, group_name, gr,
+ sizeof(struct winbindd_gr));
/* Fill extra data */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s DATA", CACHE_TYPE_GROUP, domain, group_name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain, group_name);
tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
set_cache_sequence_number(domain, CACHE_TYPE_GROUP, group_name);
}
/* Fill a group info cache entry */
-void winbindd_fill_gid_cache_entry(char *domain, gid_t gid,
- struct winbindd_gr *gr, void *extra_data,
- int extra_data_len)
+
+void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
+ struct winbindd_gr *gr, void *extra_data,
+ int extra_data_len)
{
fstring keystr;
fstring gidstr;
- slprintf(gidstr, sizeof(gidstr)-1, "#%u", (unsigned)gid);
+ snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
if (lp_winbind_cache_time() == 0) return;
+ DEBUG(3, ("storing gid cache entry %s/%s\n", domain, gidstr));
+
/* Fill group data */
- fill_cache_entry(domain, CACHE_TYPE_GROUP, gidstr, gr, sizeof(struct winbindd_gr));
+
+ store_cache_entry(domain, CACHE_TYPE_GROUP, gidstr, gr,
+ sizeof(struct winbindd_gr));
/* Fill extra data */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s DATA", CACHE_TYPE_GROUP, domain, gidstr);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain, gidstr);
+
tdb_store_by_string(cache_tdb, keystr, extra_data, extra_data_len);
set_cache_sequence_number(domain, CACHE_TYPE_GROUP, gidstr);
@@ -235,7 +263,7 @@ void winbindd_fill_gid_cache_entry(char *domain, gid_t gid,
/* Fetch some cached user or group data */
static BOOL fetch_cache(char *domain_name, char *cache_type,
- struct acct_info **sam_entries, int *num_sam_entries)
+ void **sam_entries, int *buflen)
{
TDB_DATA data;
fstring keystr;
@@ -243,20 +271,21 @@ static BOOL fetch_cache(char *domain_name, char *cache_type,
if (lp_winbind_cache_time() == 0) return False;
/* Parameter check */
- if (!sam_entries || !num_sam_entries) {
+ if (!sam_entries || !buflen) {
return False;
}
/* Check cache data is current */
if (cache_domain_expired(domain_name,
- get_cache_sequence_number(domain_name, cache_type, NULL))) {
+ get_cache_sequence_number(domain_name,
+ cache_type,
+ NULL))) {
return False;
}
/* Create key */
- slprintf(keystr, sizeof(keystr)-1, "%s CACHE DATA/%s", cache_type,
+ snprintf(keystr, sizeof(keystr), "%s CACHE DATA/%s", cache_type,
domain_name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
/* Fetch cache information */
data = tdb_fetch_by_string(cache_tdb, keystr);
@@ -268,10 +297,7 @@ static BOOL fetch_cache(char *domain_name, char *cache_type,
be freed by the end{pw,gr}ent() function. */
*sam_entries = (struct acct_info *)data.dptr;
- *num_sam_entries = data.dsize / sizeof(struct acct_info);
-
- DEBUG(4, ("fetched %d cached %s entries for domain %s\n",
- *num_sam_entries, cache_type, domain_name));
+ *buflen = data.dsize;
return True;
}
@@ -279,40 +305,58 @@ static BOOL fetch_cache(char *domain_name, char *cache_type,
/* Return cached entries for a domain. Return false if there are no cached
entries, or the cached information has expired for the domain. */
-BOOL winbindd_fetch_user_cache(char *domain_name,
- struct acct_info **sam_entries,
+BOOL winbindd_fetch_user_cache(char *domain_name,
+ struct getpwent_user **sam_entries,
int *num_entries)
{
- return fetch_cache(domain_name, CACHE_TYPE_USER, sam_entries,
- num_entries);
+ BOOL result;
+ int buflen;
+
+ result = fetch_cache(domain_name, CACHE_TYPE_USER,
+ (void **)sam_entries, &buflen);
+
+ *num_entries = buflen / sizeof(struct getpwent_user);
+
+ DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
+ domain_name));
+
+ return result;
}
/* Return cached entries for a domain. Return false if there are no cached
entries, or the cached information has expired for the domain. */
-BOOL winbindd_fetch_group_cache(char *domain_name,
- struct acct_info **sam_entries,
+BOOL winbindd_fetch_group_cache(char *domain_name,
+ struct acct_info **sam_entries,
int *num_entries)
{
- return fetch_cache(domain_name, CACHE_TYPE_GROUP, sam_entries,
- num_entries);
+ BOOL result;
+ int buflen;
+
+ result = fetch_cache(domain_name, CACHE_TYPE_GROUP,
+ (void **)sam_entries, &buflen);
+
+ *num_entries = buflen / sizeof(struct acct_info);
+
+ DEBUG(3, ("fetched %d cache entries for %s\n", *num_entries,
+ domain_name));
+
+ return result;
}
-static BOOL fetch_cache_entry(char *domain, char *cache_type, char *name, void *buf, int len)
+static BOOL fetch_cache_entry(char *domain, char *cache_type, char *name,
+ void *buf, int len)
{
TDB_DATA data;
fstring keystr;
/* Create key for lookup */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s", cache_type, domain, name);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s", cache_type, domain, name);
/* Look up cache entry */
data = tdb_fetch_by_string(cache_tdb, keystr);
if (!data.dptr) return False;
- DEBUG(4, ("returning cached entry for %s\\%s\n", domain, name));
-
/* Copy found entry into buffer */
memcpy((char *)buf, data.dptr, len < data.dsize ? len : data.dsize);
free(data.dptr);
@@ -327,10 +371,12 @@ BOOL winbindd_fetch_user_cache_entry(char *domain_name, char *user,
if (lp_winbind_cache_time() == 0) return False;
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER, user);
+ seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER,
+ user);
if (cache_domain_expired(domain_name, seq_num)) return False;
- return fetch_cache_entry(domain_name, CACHE_TYPE_USER, user, pw, sizeof(struct winbindd_pw));
+ return fetch_cache_entry(domain_name, CACHE_TYPE_USER, user, pw,
+ sizeof(struct winbindd_pw));
}
/* Fetch an individual uid cache entry */
@@ -342,11 +388,13 @@ BOOL winbindd_fetch_uid_cache_entry(char *domain_name, uid_t uid,
if (lp_winbind_cache_time() == 0) return False;
- slprintf(uidstr, sizeof(uidstr)-1, "#%u", (unsigned)uid);
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER, uidstr);
+ snprintf(uidstr, sizeof(uidstr), "#%u", (unsigned)uid);
+ seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_USER,
+ uidstr);
if (cache_domain_expired(domain_name, seq_num)) return False;
- return fetch_cache_entry(domain_name, CACHE_TYPE_USER, uidstr, pw, sizeof(struct winbindd_pw));
+ return fetch_cache_entry(domain_name, CACHE_TYPE_USER, uidstr, pw,
+ sizeof(struct winbindd_pw));
}
/* Fetch an individual group cache entry. This function differs from the
@@ -362,15 +410,21 @@ BOOL winbindd_fetch_group_cache_entry(char *domain_name, char *group,
if (lp_winbind_cache_time() == 0) return False;
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP, group);
+ seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP,
+ group);
+
if (cache_domain_expired(domain_name, seq_num)) return False;
/* Fetch group data */
- if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP, group, gr, sizeof(struct winbindd_gr))) return False;
+ if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP, group, gr,
+ sizeof(struct winbindd_gr))) {
+ return False;
+ }
/* Fetch extra data */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s DATA", CACHE_TYPE_GROUP, domain_name, group);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain_name, group);
+
data = tdb_fetch_by_string(cache_tdb, keystr);
if (!data.dptr) return False;
@@ -395,20 +449,24 @@ BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
fstring gidstr;
uint32 seq_num;
- slprintf(gidstr, sizeof(gidstr)-1, "#%u", (unsigned)gid);
+ snprintf(gidstr, sizeof(gidstr), "#%u", (unsigned)gid);
if (lp_winbind_cache_time() == 0) return False;
- seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP, gidstr);
+ seq_num = get_cache_sequence_number(domain_name, CACHE_TYPE_GROUP,
+ gidstr);
+
if (cache_domain_expired(domain_name, seq_num)) return False;
/* Fetch group data */
if (!fetch_cache_entry(domain_name, CACHE_TYPE_GROUP,
- gidstr, gr, sizeof(struct winbindd_gr))) return False;
+ gidstr, gr, sizeof(struct winbindd_gr))) {
+ return False;
+ }
/* Fetch extra data */
- slprintf(keystr, sizeof(keystr)-1, "%s/%s/%s DATA", CACHE_TYPE_GROUP, domain_name, gidstr);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ snprintf(keystr, sizeof(keystr), "%s/%s/%s DATA", CACHE_TYPE_GROUP,
+ domain_name, gidstr);
data = tdb_fetch_by_string(cache_tdb, keystr);
if (!data.dptr) return False;
@@ -425,3 +483,8 @@ void winbindd_flush_cache(void)
tdb_close(cache_tdb);
winbindd_cache_init();
}
+
+/* Print cache status information */
+void winbindd_cache_dump_status(void)
+{
+}
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index 77825cd5798..4ebf15a8655 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -25,741 +25,964 @@
/* Fill a grent structure from various other information */
-static void winbindd_fill_grent(struct winbindd_gr *gr, char *gr_name,
- gid_t unix_gid)
+static BOOL fill_grent(struct winbindd_gr *gr, char *gr_name,
+ gid_t unix_gid)
{
- /* Fill in uid/gid */
+ /* Fill in uid/gid */
- gr->gr_gid = unix_gid;
-
- /* Group name and password */
+ gr->gr_gid = unix_gid;
+
+ /* Group name and password */
+
+ safe_strcpy(gr->gr_name, gr_name, sizeof(gr->gr_name) - 1);
+ safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1);
- safe_strcpy(gr->gr_name, gr_name, sizeof(gr->gr_name) - 1);
- safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1);
+ return True;
}
-/* Fill in group membership */
-
-struct grent_mem_group {
- uint32 rid;
- enum SID_NAME_USE name_type;
- fstring domain_name;
- struct winbindd_domain *domain;
- struct grent_mem_group *prev, *next;
-};
+/* Fill in the group membership field of a NT group given by group_rid */
-struct grent_mem_list {
- fstring name;
- struct grent_mem_list *prev, *next;
-};
-
-/* Name comparison function for qsort() */
-
-static int name_comp(struct grent_mem_list *n1, struct grent_mem_list *n2)
+static BOOL fill_grent_mem(struct winbindd_domain *domain,
+ uint32 group_rid,
+ enum SID_NAME_USE group_name_type,
+ int *num_gr_mem, char **gr_mem, int *gr_mem_len)
{
- /* Silly cases */
-
- if (!n1 && !n2) return 0;
- if (!n1) return -1;
- if (!n2) return 1;
-
- return strcmp(n1->name, n2->name);
+ uint32 *rid_mem = NULL, num_names = 0;
+ enum SID_NAME_USE *name_types = NULL;
+ int buf_len, buf_ndx, i;
+ char **names = NULL, *buf;
+ BOOL result = False;
+
+ if (!num_gr_mem || !gr_mem || !gr_mem_len) return False;
+
+ /* Initialise group membership information */
+
+ DEBUG(10, ("fill_grent_mem(): group %s rid 0x%x\n",
+ domain ? domain->name : "NULL", group_rid));
+
+ *num_gr_mem = 0;
+
+ if (group_name_type != SID_NAME_DOM_GRP) {
+ DEBUG(1, ("fill_grent_mem(): rid %d in domain %s isn't a "
+ "domain group\n", group_rid, domain->name));
+ return False;
+ }
+
+ /* Lookup group members */
+
+ if (!winbindd_lookup_groupmem(domain, group_rid, &num_names,
+ &rid_mem, &names, &name_types)) {
+
+ DEBUG(1, ("fill_grent_mem(): could not lookup membership "
+ "for group rid %d in domain %s\n",
+ group_rid, domain->name));
+
+ return False;
+ }
+
+ DEBUG(10, ("fill_grent_mem(): looked up %d names\n", num_names));
+
+ if (DEBUGLEVEL >= 10) {
+ for (i = 0; i < num_names; i++) {
+ DEBUG(10, ("\t%20s %x %d\n", names[i], rid_mem[i],
+ name_types[i]));
+ }
+ }
+
+ /* Add members to list */
+
+ buf = NULL;
+ buf_len = buf_ndx = 0;
+
+ again:
+
+ for (i = 0; i < num_names; i++) {
+ char *the_name;
+ fstring name;
+ int len;
+
+ the_name = names[i];
+
+ DEBUG(10, ("fill_grent_mem(): processing name %s\n", the_name));
+
+ /* Only add domain users */
+
+ if (name_types[i] != SID_NAME_USER) {
+ DEBUG(3, ("fill_grent_mem(): name %s isn't a domain "
+ "user\n", the_name));
+ continue;
+ }
+
+ /* Don't bother with machine accounts */
+
+ if (the_name[strlen(the_name) - 1] == '$') {
+ DEBUG(10, ("fill_grent_mem(): %s is machine account\n",
+ the_name));
+ continue;
+ }
+
+ /* Append domain name */
+
+ snprintf(name, sizeof(name), "%s%s%s", domain->name,
+ lp_winbind_separator(), the_name);
+
+ len = strlen(name);
+
+ /* Add to list or calculate buffer length */
+
+ if (!buf) {
+ buf_len += len + 1; /* List is comma separated */
+ (*num_gr_mem)++;
+ DEBUG(10, ("fill_grent_mem(): buf_len + %d = %d\n", len + 1,
+ buf_len));
+ } else {
+ DEBUG(10, ("fill_grent_mem(): appending %s at index %d\n",
+ name, len));
+ safe_strcpy(&buf[buf_ndx], name, len);
+ buf_ndx += len;
+ buf[buf_ndx] = ',';
+ buf_ndx++;
+ }
+ }
+
+ /* Allocate buffer */
+
+ if (!buf) {
+ if (!(buf = malloc(buf_len))) {
+ DEBUG(1, ("fill_grent_mem(): out of memory\n"));
+ result = False;
+ goto cleanup;
+ }
+ memset(buf, 0, buf_len);
+ goto again;
+ }
+
+ if (buf && buf_ndx > 0) {
+ buf[buf_ndx - 1] = '\0';
+ }
+
+ *gr_mem = buf;
+ *gr_mem_len = buf_len;
+
+ DEBUG(10, ("fill_grent_mem(): num_mem = %d, len = %d, mem = %s\n", *num_gr_mem,
+ buf_len, buf));
+
+ result = True;
+
+ cleanup:
+
+ /* Free memory allocated in winbindd_lookup_groupmem() */
+
+ safe_free(name_types);
+ safe_free(rid_mem);
+
+ free_char_array(num_names, names);
+
+ DEBUG(10, ("fill_grent_mem(): returning %d\n", result));
+
+ return result;
}
-static struct grent_mem_list *sort_groupmem_list(struct grent_mem_list *list,
- int num_gr_mem)
-{
- struct grent_mem_list *groupmem_array, *temp;
- int i;
-
- /* Allocate and zero an array to hold sorted entries */
-
- if ((groupmem_array = malloc(num_gr_mem *
- sizeof(struct grent_mem_list))) == NULL) {
- return NULL;
- }
-
- memset((char *)groupmem_array, 0, num_gr_mem *
- sizeof(struct grent_mem_list));
-
- /* Copy list to array */
-
- for(temp = list, i = 0; temp && i < num_gr_mem; temp = temp->next, i++) {
- fstrcpy(groupmem_array[i].name, temp->name);
- }
-
- /* Sort array */
-
- qsort(groupmem_array, num_gr_mem, sizeof(struct grent_mem_list),
- name_comp);
-
- /* Fix up resulting array to a linked list and return it */
-
- for(i = 0; i < num_gr_mem; i++) {
-
- /* Fix up previous link */
-
- if (i != 0) {
- groupmem_array[i].prev = &groupmem_array[i - 1];
- }
-
- /* Fix up next link */
-
- if (i != (num_gr_mem - 1)) {
- groupmem_array[i].next = &groupmem_array[i + 1];
- }
- }
-
- return groupmem_array;
-}
+/* Return a group structure from a group name */
-static BOOL winbindd_fill_grent_mem(struct winbindd_domain *domain,
- uint32 group_rid,
- enum SID_NAME_USE group_name_type,
- struct winbindd_response *response)
+enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
+ *state)
{
- struct grent_mem_group *done_groups = NULL, *todo_groups = NULL;
- struct grent_mem_group *temp_group;
- struct grent_mem_list *groupmem_list = NULL;
- struct winbindd_gr *gr;
-
- if (response) {
- gr = &response->data.gr;
- } else {
- return False;
- }
-
- /* Initialise group membership information */
-
- gr->num_gr_mem = 0;
+ DOM_SID group_sid;
+ struct winbindd_domain *domain;
+ enum SID_NAME_USE name_type;
+ uint32 group_rid;
+ fstring name_domain, name_group, name;
+ char *tmp, *gr_mem;
+ gid_t gid;
+ int extra_data_len, gr_mem_len;
+
+ DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
+ state->request.data.groupname));
+
+ /* Parse domain and groupname */
+
+ memset(name_group, 0, sizeof(fstring));
+
+ tmp = state->request.data.groupname;
+ parse_domain_user(tmp, name_domain, name_group);
+
+ /* Reject names that don't have a domain - i.e name_domain contains
+ the entire name. */
+
+ if (strequal(name_group, "")) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Get info for the domain */
+
+ if ((domain = find_domain_from_name(name_domain)) == NULL) {
+ DEBUG(0, ("getgrname_from_group(): could not get domain "
+ "sid for domain %s\n", name_domain));
+ return WINBINDD_ERROR;
+ }
+
+ if (!domain_handles_open(domain)) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Check for cached group entry */
+
+ if (winbindd_fetch_group_cache_entry(name_domain, name_group,
+ &state->response.data.gr,
+ &state->response.extra_data,
+ &extra_data_len)) {
+ state->response.length += extra_data_len;
+ return WINBINDD_OK;
+ }
+
+ snprintf(name, sizeof(name), "%s\\%s", name_domain, name_group);
+
+ /* Get rid and name type from name */
+
+ if (!winbindd_lookup_sid_by_name(name, &group_sid, &name_type)) {
+ DEBUG(1, ("group %s in domain %s does not exist\n",
+ name_group, name_domain));
+ return WINBINDD_ERROR;
+ }
- /* Add first group to todo_groups list */
+ if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
+ DEBUG(1, ("from_group: name '%s' is not a local or domain "
+ "group: %d\n", name_group, name_type));
+ return WINBINDD_ERROR;
+ }
- if ((temp_group =
- (struct grent_mem_group *)malloc(sizeof(*temp_group))) == NULL) {
- return False;
- }
+ /* Fill in group structure */
- ZERO_STRUCTP(temp_group);
+ sid_split_rid(&group_sid, &group_rid);
- temp_group->rid = group_rid;
- temp_group->name_type = group_name_type;
- temp_group->domain = domain;
- fstrcpy(temp_group->domain_name, domain->name);
+ if (!winbindd_idmap_get_gid_from_rid(domain->name, group_rid, &gid)) {
+ DEBUG(1, ("error sursing unix gid for sid\n"));
+ return WINBINDD_ERROR;
+ }
- DLIST_ADD(todo_groups, temp_group);
-
- /* Iterate over all groups to find members of */
+ if (!fill_grent(&state->response.data.gr,
+ state->request.data.groupname, gid) ||
+ !fill_grent_mem(domain, group_rid, name_type,
+ &state->response.data.gr.num_gr_mem,
+ &gr_mem, &gr_mem_len)) {
+ return WINBINDD_ERROR;
+ }
- while(todo_groups != NULL) {
- struct grent_mem_group *current_group = todo_groups;
- uint32 num_names = 0, *rid_mem = NULL;
- enum SID_NAME_USE *name_types = NULL;
+ /* Group membership lives at start of extra data */
- DOM_SID **sids = NULL;
- char **names = NULL;
- BOOL done_group;
- int i;
+ state->response.data.gr.gr_mem_ofs = 0;
- /* Check we haven't looked up this group before */
+ state->response.length += gr_mem_len;
+ state->response.extra_data = gr_mem;
- done_group = 0;
+ /* Update cached group info */
- for (temp_group = done_groups; temp_group != NULL;
- temp_group = temp_group->next) {
+ winbindd_store_group_cache_entry(name_domain, name_group,
+ &state->response.data.gr,
+ state->response.extra_data,
+ gr_mem_len);
- if ((temp_group->rid == current_group->rid) &&
- (strcmp(temp_group->domain_name,
- current_group->domain_name) == 0)) {
-
- done_group = 1;
- }
- }
+ return WINBINDD_OK;
+}
- if (done_group) goto cleanup;
+/* Return a group structure from a gid number */
- /* Lookup group membership for the current group */
+enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
+ *state)
+{
+ struct winbindd_domain *domain;
+ DOM_SID group_sid;
+ enum SID_NAME_USE name_type;
+ fstring group_name;
+ uint32 group_rid;
+ int extra_data_len, gr_mem_len;
+ char *gr_mem;
- if (current_group->name_type == SID_NAME_DOM_GRP) {
+ /* Bug out if the gid isn't in the winbind range */
- if (!winbindd_lookup_groupmem(current_group->domain,
- current_group->rid, &num_names,
- &rid_mem, &names, &name_types)) {
+ if ((state->request.data.gid < server_state.gid_low) ||
+ (state->request.data.gid > server_state.gid_high)) {
+ return WINBINDD_ERROR;
+ }
- DEBUG(1, ("fill_grent_mem(): could not lookup membership "
- "for group rid %d in domain %s\n",
- current_group->rid,
- current_group->domain->name));
+ DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid,
+ state->request.data.gid));
- /* Exit if we cannot lookup the membership for the group
- this function was called to look at */
+ /* Get rid from gid */
- if (current_group->rid == group_rid) {
- return False;
- } else {
- goto cleanup;
- }
- }
- }
+ if (!winbindd_idmap_get_rid_from_gid(state->request.data.gid,
+ &group_rid, &domain)) {
+ DEBUG(1, ("Could not convert gid %d to rid\n",
+ state->request.data.gid));
+ return WINBINDD_ERROR;
+ }
- if (current_group->name_type == SID_NAME_ALIAS) {
+ if (!domain_handles_open(domain)) {
+ return WINBINDD_ERROR;
+ }
- if (!winbindd_lookup_aliasmem(current_group->domain,
- current_group->rid, &num_names,
- &sids, &names, &name_types)) {
+ /* Try a cached entry */
- DEBUG(1, ("fill_grent_mem(): group rid %d not a local group\n",
- group_rid));
+ if (winbindd_fetch_gid_cache_entry(domain->name,
+ state->request.data.gid,
+ &state->response.data.gr,
+ &state->response.extra_data,
+ &extra_data_len)) {
+ state->response.length += extra_data_len;
+ return WINBINDD_OK;
+ }
- /* Exit if we cannot lookup the membership for the group
- this function was called to look at */
+ /* Get sid from gid */
- if (current_group->rid == group_rid) {
- return False;
- } else {
- goto cleanup;
- }
- }
- }
+ sid_copy(&group_sid, &domain->sid);
+ sid_append_rid(&group_sid, group_rid);
- /* Now for each member of the group, add it to the group list if it
- is a user, otherwise push it onto the todo_group list if it is a
- group or an alias. */
-
- for (i = 0; i < num_names; i++) {
- enum SID_NAME_USE name_type;
- fstring name_part1, name_part2;
- char *name_dom, *name_user, *the_name;
- struct winbindd_domain *name_domain;
-
- /* Lookup name */
+ if (!winbindd_lookup_name_by_sid(&group_sid, group_name, &name_type)) {
+ DEBUG(1, ("Could not lookup sid\n"));
+ return WINBINDD_ERROR;
+ }
- ZERO_STRUCT(name_part1);
- ZERO_STRUCT(name_part2);
+ if (strcmp(lp_winbind_separator(),"\\")) {
+ string_sub(group_name, "\\", lp_winbind_separator(),
+ sizeof(fstring));
+ }
- the_name = names[i];
- parse_domain_user(the_name, name_part1, name_part2);
+ if (!((name_type == SID_NAME_ALIAS) ||
+ (name_type == SID_NAME_DOM_GRP))) {
+ DEBUG(1, ("from_gid: name '%s' is not a local or domain "
+ "group: %d\n", group_name, name_type));
+ return WINBINDD_ERROR;
+ }
- if (strcmp(name_part1, "") != 0) {
- name_dom = name_part1;
- name_user = name_part2;
+ /* Fill in group structure */
- if ((name_domain = find_domain_from_name(name_dom)) == NULL) {
- DEBUG(0, ("unable to look up domain record for domain "
- "%s\n", name_dom));
- continue;
- }
+ if (!fill_grent(&state->response.data.gr, group_name,
+ state->request.data.gid) ||
+ !fill_grent_mem(domain, group_rid, name_type,
+ &state->response.data.gr.num_gr_mem,
+ &gr_mem, &gr_mem_len)) {
+ return WINBINDD_ERROR;
+ }
- } else {
- name_dom = current_group->domain->name;
- name_user = name_part2;
- name_domain = current_group->domain;
- }
- if (winbindd_lookup_sid_by_name(name_domain, name_user, NULL,
- &name_type) == WINBINDD_OK) {
+ /* Group membership lives at start of extra data */
- /* Check name type */
+ state->response.data.gr.gr_mem_ofs = 0;
- if (name_type == SID_NAME_USER) {
- struct grent_mem_list *entry;
+ state->response.length += gr_mem_len;
+ state->response.extra_data = gr_mem;
- /* Add to group membership list */
-
- if ((entry = (struct grent_mem_list *)
- malloc(sizeof(*entry))) != NULL) {
+ /* Update cached group info */
- /* Create name */
- slprintf(entry->name, sizeof(entry->name)-1,
- "%s%s%s", name_dom, lp_winbind_separator(), name_user);
-
- /* Add to list */
+ winbindd_store_gid_cache_entry(domain->name, state->request.data.gid,
+ &state->response.data.gr,
+ state->response.extra_data,
+ gr_mem_len);
- DLIST_ADD(groupmem_list, entry);
- gr->num_gr_mem++;
- }
+ return WINBINDD_OK;
+}
- } else {
- struct grent_mem_group *todo_group;
- DOM_SID todo_sid;
- uint32 todo_rid;
+/*
+ * set/get/endgrent functions
+ */
- /* Add group to todo list */
+/* "Rewind" file pointer for group database enumeration */
- if (winbindd_lookup_sid_by_name(name_domain, names[i],
- &todo_sid, &name_type)
- == WINBINDD_OK) {
+enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
+{
+ struct winbindd_domain *tmp;
+
+ DEBUG(3, ("[%5d]: setgrent\n", state->pid));
+
+ if (state == NULL) return WINBINDD_ERROR;
+
+ /* Check user has enabled this */
+
+ if (!lp_winbind_enum_groups()) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Free old static data if it exists */
+
+ if (state->getgrent_state != NULL) {
+ free_getent_state(state->getgrent_state);
+ state->getgrent_state = NULL;
+ }
+
+ /* Create sam pipes for each domain we know about */
+
+ for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ struct getent_state *domain_state;
+
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, tmp->name)) {
+ continue;
+ }
+
+ /* Create a state record for this domain */
+
+ if ((domain_state = (struct getent_state *)
+ malloc(sizeof(struct getent_state))) == NULL) {
+
+ return WINBINDD_ERROR;
+ }
+
+ ZERO_STRUCTP(domain_state);
+
+ /* Add to list of open domains */
+
+ domain_state->domain = tmp;
+ DLIST_ADD(state->getgrent_state, domain_state);
+ }
+
+ return WINBINDD_OK;
+}
- /* Fill in group entry */
+/* Close file pointer to ntdom group database */
- sid_split_rid(&todo_sid, &todo_rid);
+enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state)
+{
+ DEBUG(3, ("[%5d]: endgrent\n", state->pid));
- if ((todo_group = (struct grent_mem_group *)
- malloc(sizeof(*todo_group))) != NULL) {
-
- ZERO_STRUCTP(todo_group);
+ if (state == NULL) return WINBINDD_ERROR;
- todo_group->rid = todo_rid;
- todo_group->name_type = name_type;
- todo_group->domain = name_domain;
+ free_getent_state(state->getgrent_state);
+ state->getgrent_state = NULL;
+
+ return WINBINDD_OK;
+}
- fstrcpy(todo_group->domain_name, name_dom);
+/* Get the list of domain groups and domain aliases for a domain. We fill in
+ the sam_entries and num_sam_entries fields with domain group information.
+ The dispinfo_ndx field is incremented to the index of the next group to
+ fetch. Return True if some groups were returned, False otherwise. */
- DLIST_ADD(todo_groups, todo_group);
- }
- }
- }
- }
- }
+#define MAX_FETCH_SAM_ENTRIES 100
- cleanup:
+static BOOL get_sam_group_entries(struct getent_state *ent)
+{
+ uint32 status, num_entries;
+ struct acct_info *name_list = NULL, *tnl;
- /* Remove group from todo list and add to done_groups list */
-
- DLIST_REMOVE(todo_groups, current_group);
- DLIST_ADD(done_groups, current_group);
-
- /* Free memory allocated in winbindd_lookup_{alias,group}mem() */
-
- safe_free(name_types);
- safe_free(rid_mem);
-
- free_char_array(num_names, names);
- free_sid_array(num_names, sids);
- }
-
- /* Free done groups list */
-
- temp_group = done_groups;
-
- if (temp_group != NULL) {
- while (temp_group != NULL) {
- struct grent_mem_group *next;
-
- DLIST_REMOVE(done_groups, temp_group);
- next = temp_group->next;
-
- free(temp_group);
- temp_group = next;
- }
- }
-
- /* Remove duplicates from group member list. */
-
- if (gr->num_gr_mem > 0) {
- struct grent_mem_list *sorted_groupmem_list, *temp;
- int extra_data_len = 0;
- fstring prev_name;
- char *head;
+ if (ent->got_all_sam_entries) {
+ return False;
+ }
+
+#if 0
+ if (winbindd_fetch_group_cache(ent->domain->name,
+ &ent->sam_entries,
+ &ent->num_sam_entries)) {
+ return True;
+ }
+#endif
+
+ /* Fetch group entries */
+
+ if (!domain_handles_open(ent->domain)) {
+ return False;
+ }
+
+ /* Free any existing group info */
+
+ if (ent->sam_entries) {
+ free(ent->sam_entries);
+ ent->sam_entries = NULL;
+ ent->num_sam_entries = 0;
+ }
+
+ /* Enumerate domain groups */
+
+ do {
+ struct acct_info *sam_grp_entries = NULL;
+
+ num_entries = 0;
+
+ status = wb_samr_enum_dom_groups(&ent->domain->sam_dom_handle,
+ &ent->grp_query_start_ndx,
+ 0x8000, /* buffer size? */
+ (struct acct_info **)
+ &sam_grp_entries,
+ &num_entries);
+
+ /* Copy entries into return buffer */
+
+ if (num_entries) {
+
+ tnl = Realloc(name_list,
+ sizeof(struct acct_info) *
+ (ent->num_sam_entries + num_entries));
+ if(tnl == NULL) {
+ DEBUG(0,("get_sam_group_entries: unable ro realloc a structure!\n"));
+ SAFE_FREE(name_list);
+ return False;
+ }
+ else
+ name_list = tnl;
+
+ memcpy(&name_list[ent->num_sam_entries],
+ sam_grp_entries,
+ num_entries * sizeof(struct acct_info));
+
+ safe_free(sam_grp_entries);
+ }
+
+ ent->num_sam_entries += num_entries;
+
+ if (status != STATUS_MORE_ENTRIES)
+ break;
+
+ } while (ent->num_sam_entries < MAX_FETCH_SAM_ENTRIES);
+
+#if 0
+ /* Fill cache with received entries */
+
+ winbindd_store_group_cache(ent->domain->name, ent->sam_entries,
+ ent->num_sam_entries);
+#endif
+
+ /* Fill in remaining fields */
+
+ ent->sam_entries = name_list;
+ ent->sam_entry_index = 0;
+ ent->got_all_sam_entries = (status != STATUS_MORE_ENTRIES);
+
+ return ent->num_sam_entries > 0;
+}
- /* Sort list */
+/* Fetch next group entry from ntdom database */
- sorted_groupmem_list = sort_groupmem_list(groupmem_list,
- gr->num_gr_mem);
- /* Remove duplicates by iteration */
+#define MAX_GETGRENT_GROUPS 500
- fstrcpy(prev_name, "");
+enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
+{
+ struct getent_state *ent;
+ struct winbindd_gr *group_list = NULL;
+ int num_groups, group_list_ndx = 0, i, gr_mem_list_len = 0;
+ char *sep, *new_extra_data, *gr_mem_list = NULL;
- for(temp = sorted_groupmem_list; temp; temp = temp->next) {
- if (strequal(temp->name, prev_name)) {
+ DEBUG(3, ("[%5d]: getgrent\n", state->pid));
- /* Got a duplicate name - delete it. Don't panic as we're
- only adjusting the prev and next pointers so memory
- allocation is not messed up. */
+ if (state == NULL) return WINBINDD_ERROR;
- DLIST_REMOVE(sorted_groupmem_list, temp);
- gr->num_gr_mem--;
+ /* Check user has enabled this */
- } else {
+ if (!lp_winbind_enum_groups()) {
+ return WINBINDD_ERROR;
+ }
- /* Got a unique name - count how long it is */
+ num_groups = MIN(MAX_GETGRENT_GROUPS, state->request.data.num_entries);
- extra_data_len += strlen(temp->name) + 1;
- }
- }
+ if ((state->response.extra_data =
+ malloc(num_groups * sizeof(struct winbindd_gr))) == NULL) {
+ return WINBINDD_ERROR;
+ }
- extra_data_len++; /* Don't forget null a terminator */
+ state->response.data.num_entries = 0;
- /* Convert sorted list into extra data field to send back to ntdom
- client. Add one to extra_data_len for null termination */
+ group_list = (struct winbindd_gr *)state->response.extra_data;
+ sep = lp_winbind_separator();
- if ((response->extra_data = malloc(extra_data_len))) {
+ if (!(ent = state->getgrent_state)) {
+ return WINBINDD_ERROR;
+ }
- /* Initialise extra data */
+ /* Start sending back groups */
- memset(response->extra_data, 0, extra_data_len);
+ for (i = 0; i < num_groups; i++) {
+ struct acct_info *name_list = NULL;
+ fstring domain_group_name;
+ uint32 result;
+ gid_t group_gid;
+
+ /* Do we need to fetch another chunk of groups? */
- head = response->extra_data;
+ tryagain:
- /* Fill in extra data */
+ DEBUG(10, ("getgrent(): entry_index = %d, num_entries = %d\n",
+ ent->sam_entry_index, ent->num_sam_entries));
- for(temp = sorted_groupmem_list; temp; temp = temp->next) {
- int len = strlen(temp->name) + 1;
-
- safe_strcpy(head, temp->name, len);
- head[len - 1] = ',';
- head += len;
- }
-
- *head = '\0';
+ if (ent->num_sam_entries == ent->sam_entry_index) {
- /* Update response length */
+ while(ent && !get_sam_group_entries(ent)) {
+ struct getent_state *next_ent;
- response->length = sizeof(struct winbindd_response) +
- extra_data_len;
- }
+ DEBUG(10, ("getgrent(): freeing state info for "
+ "domain %s\n", ent->domain->name));
- /* Free memory for sorted_groupmem_list. It was allocated as an
- array in sort_groupmem_list() so can be freed in one go. */
+ /* Free state information for this domain */
- free(sorted_groupmem_list);
+ safe_free(ent->sam_entries);
+ ent->sam_entries = NULL;
- /* Free groupmem_list */
+ next_ent = ent->next;
+ DLIST_REMOVE(state->getgrent_state, ent);
+
+ free(ent);
+ ent = next_ent;
+ }
- temp = groupmem_list;
+ /* No more domains */
- while (temp != NULL) {
- struct grent_mem_list *next;
-
- DLIST_REMOVE(groupmem_list, temp);
- next = temp->next;
-
- free(temp);
- temp = next;
- }
- }
+ if (!ent) break;
+ }
+
+ name_list = ent->sam_entries;
+
+ /* Lookup group info */
+
+ if (!winbindd_idmap_get_gid_from_rid(
+ ent->domain->name,
+ name_list[ent->sam_entry_index].rid,
+ &group_gid)) {
+
+ DEBUG(1, ("getgrent(): could not look up gid for group %s\n",
+ name_list[ent->sam_entry_index].acct_name));
- return True;
-}
+ ent->sam_entry_index++;
+ goto tryagain;
+ }
-/* Return a group structure from a group name */
+ DEBUG(10, ("getgrent(): got gid %d for group %x\n", group_gid,
+ name_list[ent->sam_entry_index].rid));
+
+ /* Fill in group entry */
-enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state *state)
-{
- DOM_SID group_sid;
- struct winbindd_domain *domain;
- enum SID_NAME_USE name_type;
- uint32 group_rid;
- fstring name_domain, name_group, name;
- char *tmp;
- gid_t gid;
- int extra_data_len;
+ slprintf(domain_group_name, sizeof(domain_group_name) - 1,
+ "%s%s%s", ent->domain->name, lp_winbind_separator(),
+ name_list[ent->sam_entry_index].acct_name);
+
+ result = fill_grent(&group_list[group_list_ndx],
+ domain_group_name, group_gid);
- /* Parse domain and groupname */
+ /* Fill in group membership entry */
- memset(name_group, 0, sizeof(fstring));
+ if (result) {
+ int gr_mem_len;
+ char *gr_mem, *new_gr_mem_list;
- tmp = state->request.data.groupname;
- parse_domain_user(tmp, name_domain, name_group);
+ /* Get group membership */
- /* Reject names that don't have a domain - i.e name_domain contains the
- entire name. */
+ result = fill_grent_mem(
+ ent->domain,
+ name_list[ent->sam_entry_index].rid,
+ SID_NAME_DOM_GRP,
+ &group_list[group_list_ndx].num_gr_mem,
+ &gr_mem, &gr_mem_len);
- if (strequal(name_group, "")) {
- return WINBINDD_ERROR;
- }
+ /* Append to group membership list */
- /* Get info for the domain */
+ new_gr_mem_list = Realloc(
+ gr_mem_list,
+ gr_mem_list_len + gr_mem_len);
- if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("getgrname_from_group(): could not get domain sid for "
- "domain %s\n", name_domain));
- return WINBINDD_ERROR;
- }
+ if (!new_gr_mem_list && (group_list[group_list_ndx].num_gr_mem != 0)) {
+ DEBUG(0, ("getgrent(): out of memory\n"));
+ free(gr_mem_list);
+ gr_mem_list_len = 0;
+ break;
+ }
- /* Check for cached user entry */
+ DEBUG(10, ("getgrent(): list_len = %d, mem_len = %d\n",
+ gr_mem_list_len, gr_mem_len));
- if (winbindd_fetch_group_cache_entry(name_domain, name_group,
- &state->response.data.gr,
- &state->response.extra_data,
- &extra_data_len)) {
- state->response.length += extra_data_len;
- return WINBINDD_OK;
- }
+ gr_mem_list = new_gr_mem_list;
- slprintf(name, sizeof(name)-1, "%s\\%s", name_domain, name_group);
+ memcpy(&gr_mem_list[gr_mem_list_len], gr_mem,
+ gr_mem_len);
- /* Get rid and name type from name */
-
- if (!winbindd_lookup_sid_by_name(domain, name, &group_sid,
- &name_type)) {
- DEBUG(1, ("group %s in domain %s does not exist\n", name_group,
- name_domain));
- return WINBINDD_ERROR;
- }
-
- if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
- DEBUG(1, ("from_group: name '%s' is not a local or domain group: %d\n",
- name_group, name_type));
- return WINBINDD_ERROR;
- }
-
- /* Fill in group structure */
-
- sid_split_rid(&group_sid, &group_rid);
-
- if (!winbindd_idmap_get_gid_from_rid(domain->name, group_rid, &gid)) {
- DEBUG(1, ("error sursing unix gid for sid\n"));
- return WINBINDD_ERROR;
- }
-
- winbindd_fill_grent(&state->response.data.gr,
- state->request.data.groupname, gid);
-
- if (!winbindd_fill_grent_mem(domain, group_rid, name_type,
- &state->response)) {
- return WINBINDD_ERROR;
- }
+ safe_free(gr_mem);
- /* Update cached group info */
+ group_list[group_list_ndx].gr_mem_ofs =
+ gr_mem_list_len;
- winbindd_fill_group_cache_entry(name_domain, name_group,
- &state->response.data.gr,
- state->response.extra_data,
- state->response.length -
- sizeof(struct winbindd_response));
+ gr_mem_list_len += gr_mem_len;
+ }
- return WINBINDD_OK;
-}
+ ent->sam_entry_index++;
+
+ /* Add group to return list */
+
+ if (result) {
-/* Return a group structure from a gid number */
+ DEBUG(10, ("getgrent(): adding group num_entries = %d\n",
+ state->response.data.num_entries));
-enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
- *state)
-{
- struct winbindd_domain *domain;
- DOM_SID group_sid;
- enum SID_NAME_USE name_type;
- fstring group_name;
- uint32 group_rid;
- int extra_data_len;
-
- /* Get rid from gid */
- if (!winbindd_idmap_get_rid_from_gid(state->request.data.gid, &group_rid,
- &domain)) {
- DEBUG(1, ("Could not convert gid %d to rid\n",
- state->request.data.gid));
- return WINBINDD_ERROR;
- }
-
- /* try a cached entry */
- if (winbindd_fetch_gid_cache_entry(domain->name, state->request.data.gid,
- &state->response.data.gr,
- &state->response.extra_data,
- &extra_data_len)) {
- state->response.length += extra_data_len;
- return WINBINDD_OK;
- }
-
- /* Get sid from gid */
-
- sid_copy(&group_sid, &domain->sid);
- sid_append_rid(&group_sid, group_rid);
-
- if (!winbindd_lookup_name_by_sid(domain, &group_sid, group_name,
- &name_type)) {
- DEBUG(1, ("Could not lookup sid\n"));
- return WINBINDD_ERROR;
- }
-
- if (strcmp(lp_winbind_separator(),"\\")) {
- string_sub(group_name, "\\", lp_winbind_separator(), sizeof(fstring));
- }
-
- if (!((name_type == SID_NAME_ALIAS) || (name_type == SID_NAME_DOM_GRP))) {
- DEBUG(1, ("from_gid: name '%s' is not a local or domain group: %d\n",
- group_name, name_type));
- return WINBINDD_ERROR;
- }
-
- /* Fill in group structure */
-
- winbindd_fill_grent(&state->response.data.gr, group_name,
- state->request.data.gid);
-
- if (!winbindd_fill_grent_mem(domain, group_rid, name_type,
- &state->response)) {
- return WINBINDD_ERROR;
- }
-
- /* Update cached group info */
- winbindd_fill_gid_cache_entry(domain->name, state->request.data.gid,
- &state->response.data.gr,
- state->response.extra_data,
- state->response.length -
- sizeof(struct winbindd_response));
-
- return WINBINDD_OK;
-}
-
-/*
- * set/get/endgrent functions
- */
-
-/* "Rewind" file pointer for group database enumeration */
-
-enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
-{
- struct winbindd_domain *tmp;
+ group_list_ndx++;
+ state->response.data.num_entries++;
+
+ state->response.length +=
+ sizeof(struct winbindd_gr);
+
+ } else {
+ DEBUG(0, ("could not lookup domain group %s\n",
+ domain_group_name));
+ }
+ }
- if (state == NULL) return WINBINDD_ERROR;
+ /* Copy the list of group memberships to the end of the extra data */
- /* Free old static data if it exists */
+ if (group_list_ndx == 0) {
+ goto done;
+ }
- if (state->getgrent_state != NULL) {
- free_getent_state(state->getgrent_state);
- state->getgrent_state = NULL;
- }
+ new_extra_data = Realloc(
+ state->response.extra_data,
+ group_list_ndx * sizeof(struct winbindd_gr) + gr_mem_list_len);
- /* Create sam pipes for each domain we know about */
+ if (!new_extra_data) {
+ DEBUG(0, ("out of memory\n"));
+ group_list_ndx = 0;
+ safe_free(state->response.extra_data);
+ state->response.extra_data = NULL;
+ safe_free(gr_mem_list);
- for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- struct getent_state *domain_state;
+ return WINBINDD_ERROR;
+ }
- /* Skip domains other than WINBINDD_DOMAIN environment variable */
+ state->response.extra_data = new_extra_data;
- if ((strcmp(state->request.domain, "") != 0) &&
- (strcmp(state->request.domain, tmp->name) != 0)) {
- continue;
- }
+ memcpy(&((char *)state->response.extra_data)
+ [group_list_ndx * sizeof(struct winbindd_gr)],
+ gr_mem_list, gr_mem_list_len);
- /* Create a state record for this domain */
+ safe_free(gr_mem_list);
- if ((domain_state = (struct getent_state *)
- malloc(sizeof(struct getent_state))) == NULL) {
+ state->response.length += gr_mem_list_len;
- return WINBINDD_ERROR;
- }
+ DEBUG(10, ("getgrent(): returning %d groups, length = %d\n",
+ group_list_ndx, gr_mem_list_len));
- ZERO_STRUCTP(domain_state);
+ /* Out of domains */
- /* Add to list of open domains */
-
- domain_state->domain = tmp;
- DLIST_ADD(state->getgrent_state, domain_state);
- }
-
- return WINBINDD_OK;
+ done:
+ return (group_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR;
}
-/* Close file pointer to ntdom group database */
+/* List domain groups without mapping to unix ids */
-enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state)
+enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
{
- if (state == NULL) return WINBINDD_ERROR;
-
- free_getent_state(state->getgrent_state);
- state->getgrent_state = NULL;
-
- return WINBINDD_OK;
+ uint32 total_entries = 0;
+ uint32 num_domain_entries;
+ struct winbindd_domain *domain;
+ struct getent_state groups;
+ char *extra_data = NULL;
+ char *ted = NULL;
+ int extra_data_len = 0, i;
+ char *sam_entries = NULL;
+
+ DEBUG(3, ("[%5d]: list groups\n", state->pid));
+
+ /* Enumerate over trusted domains */
+ ZERO_STRUCT(groups);
+ for (domain = domain_list; domain; domain = domain->next) {
+
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, domain->name)) {
+ continue;
+ }
+
+ /* Get list of sam groups */
+
+ ZERO_STRUCT(groups);
+ groups.domain = domain;
+
+ /*
+ * iterate through all groups
+ * total_entries : maintains a total count over **all domains**
+ * num_domain_entries : is the running count for this domain
+ */
+
+ num_domain_entries = 0;
+ while (get_sam_group_entries(&groups))
+ {
+ int new_size;
+ int offset;
+
+ offset = sizeof(struct acct_info) * num_domain_entries;
+ new_size = sizeof(struct acct_info)
+ * (groups.num_sam_entries + num_domain_entries);
+ sam_entries = Realloc(sam_entries, new_size);
+
+ if (!sam_entries)
+ return WINBINDD_ERROR;
+
+ num_domain_entries += groups.num_sam_entries;
+ memcpy (sam_entries+offset, groups.sam_entries,
+ sizeof(struct acct_info) * groups.num_sam_entries);
+
+ groups.sam_entries = NULL;
+ groups.num_sam_entries = 0;
+ }
+
+ /* skip remainder of loop if we idn;t retrieve any groups */
+
+ if (num_domain_entries == 0)
+ continue;
+
+ /* setup the groups struct to contain all the groups
+ retrieved for this domain */
+
+ groups.num_sam_entries = num_domain_entries;
+ groups.sam_entries = sam_entries;
+
+ /* keep track the of the total number of groups seen so
+ far over all domains */
+
+ total_entries += groups.num_sam_entries;
+
+ /* Allocate some memory for extra data. Note that we limit
+ account names to sizeof(fstring) = 128 characters. */
+
+ ted = Realloc(extra_data, sizeof(fstring) * total_entries);
+
+ if (!ted) {
+ DEBUG(0,("winbindd_list_groups: failed to enlarge buffer!\n"));
+ if (extra_data)
+ free(extra_data);
+ return WINBINDD_ERROR;
+ } else
+ extra_data = ted;
+
+ /* Pack group list into extra data fields */
+
+ for (i = 0; i < groups.num_sam_entries; i++) {
+ char *group_name = ((struct acct_info *)
+ groups.sam_entries)[i].acct_name;
+ fstring name;
+
+ /* Convert unistring to ascii */
+
+ snprintf(name, sizeof(name), "%s%s%s", domain->name,
+ lp_winbind_separator(), group_name);
+
+ /* Append to extra data */
+
+ memcpy(&extra_data[extra_data_len], name, strlen(name));
+ extra_data_len += strlen(name);
+
+ extra_data[extra_data_len++] = ',';
+ }
+ }
+
+ /* Assign extra_data fields in response structure */
+
+ if (extra_data) {
+ extra_data[extra_data_len - 1] = '\0';
+ state->response.extra_data = extra_data;
+ state->response.length += extra_data_len;
+ }
+
+ /* No domains may have responded but that's still OK so don't
+ return an error. */
+
+ return WINBINDD_OK;
}
-/* Fetch next group entry from netdom database */
+/* Get user supplementary groups. This is much quicker than trying to
+ invert the groups database. */
-enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
+enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
{
- if (state == NULL) return WINBINDD_ERROR;
-
- /* Process the current head of the getent_state list */
-
- while(state->getgrent_state != NULL) {
- struct getent_state *ent = state->getgrent_state;
-
- /* Get list of entries if we haven't already got them */
-
- if (!ent->got_sam_entries) {
- uint32 status, start_ndx = 0, start_ndx2 = 0;
-
- if (!winbindd_fetch_group_cache(ent->domain->name,
- &ent->sam_entries,
- &ent->num_sam_entries)) {
-
- /* Fetch group entries */
-
- if (!domain_handles_open(ent->domain)) goto cleanup;
-
- /* Enumerate domain groups */
-
- do {
- status =
- samr_enum_dom_groups(&ent->domain->sam_dom_handle,
- &start_ndx, 0x100000,
- &ent->sam_entries,
- &ent->num_sam_entries);
- } while (status == STATUS_MORE_ENTRIES);
-
- /* Enumerate domain aliases */
-
- do {
- status =
- samr_enum_dom_aliases(&ent->domain->sam_dom_handle,
- &start_ndx2, 0x100000,
- &ent->sam_entries,
- &ent->num_sam_entries);
- } while (status == STATUS_MORE_ENTRIES);
-
- /* Fill cache with received entries */
-
- winbindd_fill_group_cache(ent->domain->name, ent->sam_entries,
- ent->num_sam_entries);
- }
-
- ent->got_sam_entries = True;
- }
-
- /* Send back a group */
-
- while (ent->sam_entry_index < ent->num_sam_entries) {
- enum winbindd_result result;
- fstring domain_group_name;
- char *group_name = (ent->sam_entries)
- [ent->sam_entry_index].acct_name;
-
- /* Prepend domain to name */
-
- slprintf(domain_group_name, sizeof(domain_group_name)-1,
- "%s%s%s", ent->domain->name, lp_winbind_separator(), group_name);
-
- /* Get group entry from group name */
-
- fstrcpy(state->request.data.groupname, domain_group_name);
- result = winbindd_getgrnam_from_group(state);
-
- ent->sam_entry_index++;
-
- if (result == WINBINDD_OK) {
- return result;
- }
-
- /* Try next group */
-
- DEBUG(1, ("could not getgrnam_from_group for group name %s\n",
- domain_group_name));
- }
-
- /* We've exhausted all users for this pipe - close it down and
- start on the next one. */
-
- cleanup:
-
- /* Free mallocated memory for sam entries. The data stored here
- may have been allocated from the cache. */
-
- if (ent->sam_entries != NULL) free(ent->sam_entries);
- ent->sam_entries = NULL;
-
- /* Free state information for this domain */
-
- {
- struct getent_state *old_ent;
-
- old_ent = state->getgrent_state;
- DLIST_REMOVE(state->getgrent_state, state->getgrent_state);
- free(old_ent);
- }
- }
-
- /* Out of pipes so we're done */
-
- return WINBINDD_ERROR;
+ fstring name_domain, name_user, name;
+ DOM_SID user_sid;
+ enum SID_NAME_USE name_type;
+ uint32 user_rid, num_groups, num_gids;
+ DOM_GID *user_groups = NULL;
+ struct winbindd_domain *domain;
+ enum winbindd_result result;
+ gid_t *gid_list;
+ int i;
+
+ DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
+ state->request.data.username));
+
+ if (state == NULL) return WINBINDD_ERROR;
+
+ /* Parse domain and username */
+
+ parse_domain_user(state->request.data.username, name_domain,
+ name_user);
+
+ /* Reject names that don't have a domain - i.e name_domain contains
+ the entire name. */
+
+ if (strequal(name_domain, "")) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Get info for the domain */
+
+ if ((domain = find_domain_from_name(name_domain)) == NULL) {
+ DEBUG(0, ("could not find domain entry for domain %s\n",
+ name_domain));
+ return WINBINDD_ERROR;
+ }
+
+ if (!domain_handles_open(domain)) {
+ return WINBINDD_ERROR;
+ }
+
+ slprintf(name, sizeof(name) - 1, "%s\\%s", name_domain, name_user);
+
+ /* Get rid and name type from name. The following costs 1 packet */
+
+ if (!winbindd_lookup_sid_by_name(name, &user_sid, &name_type)) {
+ DEBUG(1, ("user '%s' does not exist\n", name_user));
+ return WINBINDD_ERROR;
+ }
+
+ if (name_type != SID_NAME_USER) {
+ DEBUG(1, ("name '%s' is not a user name: %d\n", name_user,
+ name_type));
+ return WINBINDD_ERROR;
+ }
+
+ sid_split_rid(&user_sid, &user_rid);
+
+ if (!winbindd_lookup_usergroups(domain, user_rid, &num_groups,
+ &user_groups)) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Copy data back to client */
+
+ num_gids = 0;
+ gid_list = malloc(sizeof(gid_t) * num_groups);
+
+ if (state->response.extra_data) {
+ result = WINBINDD_ERROR;
+ goto done;
+ }
+
+ for (i = 0; i < num_groups; i++) {
+ if (!winbindd_idmap_get_gid_from_rid(
+ domain->name, user_groups[i].g_rid,
+ &gid_list[num_gids])) {
+
+ DEBUG(1, ("unable to convert group rid %d to gid\n",
+ user_groups[i].g_rid));
+ continue;
+ }
+
+ num_gids++;
+ }
+
+ state->response.data.num_entries = num_gids;
+ state->response.extra_data = gid_list;
+ state->response.length += num_gids * sizeof(gid_t);
+
+ result = WINBINDD_OK;
+
+ done:
+ safe_free(user_groups);
+
+ return result;
}
diff --git a/source/nsswitch/winbindd_idmap.c b/source/nsswitch/winbindd_idmap.c
index 891b79c2758..5f667a621bc 100644
--- a/source/nsswitch/winbindd_idmap.c
+++ b/source/nsswitch/winbindd_idmap.c
@@ -34,7 +34,7 @@ static TDB_CONTEXT *idmap_tdb;
/* Allocate either a user or group id from the pool */
-static BOOL allocate_id(int *id, BOOL isgroup)
+static BOOL allocate_id(uid_t *id, BOOL isgroup)
{
int hwm;
@@ -68,17 +68,16 @@ static BOOL allocate_id(int *id, BOOL isgroup)
/* Get an id from a rid */
-static BOOL get_id_from_rid(char *domain_name, uint32 rid, int *id,
+static BOOL get_id_from_rid(char *domain_name, uint32 rid, uid_t *id,
BOOL isgroup)
{
TDB_DATA data, key;
fstring keystr;
- BOOL result;
+ BOOL result = False;
/* Check if rid is present in database */
- slprintf(keystr, sizeof(keystr)-1, "%s/%d", domain_name, rid);
- dos_to_unix(keystr, True); /* Convert key to unix-codepage */
+ slprintf(keystr, sizeof(keystr), "%s/%d", domain_name, rid);
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
@@ -116,7 +115,7 @@ static BOOL get_id_from_rid(char *domain_name, uint32 rid, int *id,
/* Store new id */
- slprintf(keystr2, sizeof(keystr2)-1, "%s %d", isgroup ? "GID" :
+ slprintf(keystr2, sizeof(keystr2), "%s %d", isgroup ? "GID" :
"UID", *id);
data.dptr = keystr2;
@@ -155,7 +154,7 @@ BOOL get_rid_from_id(int id, uint32 *rid, struct winbindd_domain **domain,
fstring keystr;
BOOL result = False;
- slprintf(keystr, sizeof(keystr)-1, "%s %d", isgroup ? "GID" : "UID", id);
+ slprintf(keystr, sizeof(keystr), "%s %d", isgroup ? "GID" : "UID", id);
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
@@ -177,11 +176,17 @@ BOOL get_rid_from_id(int id, uint32 *rid, struct winbindd_domain **domain,
if (domain) {
*domain = find_domain_from_name(domain_name);
+ if (*domain == NULL) {
+ DEBUG(1, ("unknown domain %s for rid %d\n",
+ domain_name, the_rid));
+ result = False;
+ goto done;
+ }
}
result = True;
}
-
+ done:
free(data.dptr);
}
@@ -211,8 +216,7 @@ BOOL winbindd_idmap_init(void)
/* Open tdb cache */
if (!(idmap_tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
- TDB_NOLOCK | TDB_NOMMAP,
- O_RDWR | O_CREAT, 0600))) {
+ TDB_NOLOCK, O_RDWR | O_CREAT, 0600))) {
DEBUG(0, ("Unable to open idmap database\n"));
return False;
}
@@ -235,3 +239,63 @@ BOOL winbindd_idmap_init(void)
return True;
}
+
+/* Dump status information to log file. Display different stuff based on
+ the debug level:
+
+ Debug Level Information Displayed
+ =================================================================
+ 0 Percentage of [ug]id range allocated
+ 0 High water marks (next allocated ids)
+*/
+
+#define DUMP_INFO 0
+
+void winbindd_idmap_dump_status(void)
+{
+ int user_hwm, group_hwm;
+
+ DEBUG(0, ("Status for winbindd idmap:\n"));
+
+ /* Get current high water marks */
+
+ if ((user_hwm = tdb_fetch_int(idmap_tdb, HWM_USER)) == -1) {
+ DEBUG(DUMP_INFO, ("\tCould not get userid high water mark!\n"));
+ }
+
+ if ((group_hwm = tdb_fetch_int(idmap_tdb, HWM_GROUP)) == -1) {
+ DEBUG(DUMP_INFO, ("\tCould not get groupid high water mark!\n"));
+ }
+
+ /* Display next ids to allocate */
+
+ if (user_hwm != -1) {
+ DEBUG(DUMP_INFO, ("\tNext userid to allocate is %d\n", user_hwm));
+ }
+
+ if (group_hwm != -1) {
+ DEBUG(DUMP_INFO, ("\tNext groupid to allocate is %d\n", group_hwm));
+ }
+
+ /* Display percentage of id range already allocated. */
+
+ if (user_hwm != -1) {
+ int num_users = user_hwm - server_state.uid_low;
+ int total_users = server_state.uid_high - server_state.uid_low;
+
+ DEBUG(DUMP_INFO, ("\tUser id range is %d%% full (%d of %d)\n",
+ num_users * 100 / total_users, num_users,
+ total_users));
+ }
+
+ if (group_hwm != -1) {
+ int num_groups = group_hwm - server_state.gid_low;
+ int total_groups = server_state.gid_high - server_state.gid_low;
+
+ DEBUG(DUMP_INFO, ("\tGroup id range is %d%% full (%d of %d)\n",
+ num_groups * 100 / total_groups, num_groups,
+ total_groups));
+ }
+
+ /* Display complete mapping of users and groups to rids */
+}
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index aedbaaf1fd9..ed7a0d4a28b 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -55,6 +55,7 @@ enum winbindd_cmd {
/* PAM authenticate and password change */
WINBINDD_PAM_AUTH,
+ WINBINDD_PAM_AUTH_CRAP,
WINBINDD_PAM_CHAUTHTOK,
/* List various things */
@@ -100,6 +101,14 @@ struct winbindd_request {
fstring pass;
} auth; /* pam_winbind auth module */
struct {
+ unsigned char chal[8];
+ fstring user;
+ fstring lm_resp;
+ uint16 lm_resp_len;
+ fstring nt_resp;
+ uint16 nt_resp_len;
+ } auth_crap;
+ struct {
fstring user;
fstring oldpass;
fstring newpass;
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index c74afd8e291..44d1e0ac99d 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -23,50 +23,100 @@
#include "winbindd.h"
+/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
+ form DOMAIN/user into a domain and a user */
+
+static void parse_domain_user(char *domuser, fstring domain, fstring user)
+{
+ char *p;
+ char *sep = lp_winbind_separator();
+ if (!sep) sep = "\\";
+ p = strchr(domuser,*sep);
+ if (!p) p = strchr(domuser,'\\');
+ if (!p) {
+ fstrcpy(domain,"");
+ fstrcpy(user, domuser);
+ return;
+ }
+
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ strupper(domain);
+}
+
/* Return a password structure from a username. Specify whether cached data
can be returned. */
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
{
- NET_USER_INFO_3 info3;
- uchar ntpw[16];
- uchar lmpw[16];
- uint8 trust_passwd[16];
- uint32 status;
- fstring server;
+ BOOL result, user_exists;
fstring name_domain, name_user;
- extern pstring global_myname;
+ int passlen;
- DEBUG(1,("winbindd_pam_auth user=%s\n",
- state->request.data.auth.user));
+ DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
+ state->request.data.auth.user));
/* Parse domain and username */
- parse_domain_user(state->request.data.auth.user, name_domain, name_user);
- /* don't allow the null domain */
- if (strcmp(name_domain,"") == 0) return WINBINDD_ERROR;
+ parse_domain_user(state->request.data.auth.user, name_domain,
+ name_user);
- ZERO_STRUCT(info3);
+ /* don't allow the null domain */
- if (!secrets_fetch_trust_account_password(lp_workgroup(),
- trust_passwd, NULL)) {
+ if (strcmp(name_domain,"") == 0)
return WINBINDD_ERROR;
- }
-
- nt_lm_owf_gen(state->request.data.auth.pass, ntpw, lmpw);
- slprintf(server, sizeof(server)-1, "\\\\%s", server_state.controller);
+ passlen = strlen(state->request.data.auth.pass);
- status = domain_client_validate_backend(server,
- name_user, name_domain,
- global_myname, SEC_CHAN_WKSTA,
- trust_passwd,
- NULL,
- lmpw, sizeof(lmpw),
- ntpw, sizeof(ntpw), &info3);
+ /* So domain_client_validate() actually opens a new connection
+ for each authentication performed. This can theoretically
+ be optimised to use an already open IPC$ connection. */
- if (status != NT_STATUS_NOPROBLEMO) return WINBINDD_ERROR;
+ result = domain_client_validate(name_user, name_domain,
+ state->request.data.auth.pass,
+ passlen,
+ state->request.data.auth.pass,
+ passlen, &user_exists);
- return WINBINDD_OK;
+ return result ? WINBINDD_OK : WINBINDD_ERROR;
}
+/* Change a user password */
+
+enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
+{
+ char *oldpass, *newpass;
+ fstring domain, user;
+ uchar nt_oldhash[16];
+ uchar lm_oldhash[16];
+
+ DEBUG(3, ("[%5d]: pam chauthtok %s\n", state->pid,
+ state->request.data.chauthtok.user));
+
+ /* Setup crap */
+
+ if (state == NULL) return WINBINDD_ERROR;
+
+ parse_domain_user(state->request.data.chauthtok.user, domain, user);
+
+ oldpass = state->request.data.chauthtok.oldpass;
+ newpass = state->request.data.chauthtok.newpass;
+
+ nt_lm_owf_gen(oldpass, nt_oldhash, lm_oldhash);
+
+ /* Change password */
+
+#if 0
+
+ /* XXX */
+
+ if (!msrpc_sam_ntchange_pwd(server_state.controller, domain, user,
+ lm_oldhash, nt_oldhash, newpass)) {
+ DEBUG(0, ("password change failed for user %s/%s\n", domain, user));
+ return WINBINDD_ERROR;
+ }
+#endif
+
+ return WINBINDD_OK;
+}
diff --git a/source/nsswitch/winbindd_proto.h b/source/nsswitch/winbindd_proto.h
index 774478fea5d..11a3bc4f864 100644
--- a/source/nsswitch/winbindd_proto.h
+++ b/source/nsswitch/winbindd_proto.h
@@ -5,32 +5,33 @@
/*The following definitions come from nsswitch/winbindd.c */
+void winbindd_dump_status(void);
int main(int argc, char **argv);
/*The following definitions come from nsswitch/winbindd_cache.c */
void winbindd_cache_init(void);
-void winbindd_fill_user_cache(char *domain_name,
- struct acct_info *sam_entries,
- int num_sam_entries);
-void winbindd_fill_group_cache(char *domain_name,
- struct acct_info *sam_entries,
- int num_sam_entries);
-void winbindd_fill_user_cache_entry(char *domain, char *user_name,
+void winbindd_store_user_cache(char *domain,
+ struct getpwent_user *sam_entries,
+ int num_sam_entries);
+void winbindd_store_group_cache(char *domain,
+ struct acct_info *sam_entries,
+ int num_sam_entries);
+void winbindd_store_user_cache_entry(char *domain, char *user_name,
+ struct winbindd_pw *pw);
+void winbindd_store_uid_cache_entry(char *domain, uid_t uid,
struct winbindd_pw *pw);
-void winbindd_fill_uid_cache_entry(char *domain, uid_t uid,
- struct winbindd_pw *pw);
-void winbindd_fill_group_cache_entry(char *domain, char *group_name,
- struct winbindd_gr *gr, void *extra_data,
- int extra_data_len);
-void winbindd_fill_gid_cache_entry(char *domain, gid_t gid,
- struct winbindd_gr *gr, void *extra_data,
- int extra_data_len);
-BOOL winbindd_fetch_user_cache(char *domain_name,
- struct acct_info **sam_entries,
+void winbindd_store_group_cache_entry(char *domain, char *group_name,
+ struct winbindd_gr *gr, void *extra_data,
+ int extra_data_len);
+void winbindd_store_gid_cache_entry(char *domain, gid_t gid,
+ struct winbindd_gr *gr, void *extra_data,
+ int extra_data_len);
+BOOL winbindd_fetch_user_cache(char *domain_name,
+ struct getpwent_user **sam_entries,
int *num_entries);
-BOOL winbindd_fetch_group_cache(char *domain_name,
- struct acct_info **sam_entries,
+BOOL winbindd_fetch_group_cache(char *domain_name,
+ struct acct_info **sam_entries,
int *num_entries);
BOOL winbindd_fetch_user_cache_entry(char *domain_name, char *user,
struct winbindd_pw *pw);
@@ -43,15 +44,19 @@ BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
struct winbindd_gr *gr,
void **extra_data, int *extra_data_len);
void winbindd_flush_cache(void);
+void winbindd_cache_dump_status(void);
/*The following definitions come from nsswitch/winbindd_group.c */
-enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
+ *state);
enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_cli_state
*state);
enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_idmap.c */
@@ -66,48 +71,75 @@ BOOL winbindd_idmap_get_rid_from_uid(uid_t uid, uint32 *user_rid,
BOOL winbindd_idmap_get_rid_from_gid(gid_t gid, uint32 *group_rid,
struct winbindd_domain **domain);
BOOL winbindd_idmap_init(void);
+void winbindd_idmap_dump_status(void);
+
+/*The following definitions come from nsswitch/winbindd_misc.c */
+
+BOOL _get_trust_account_password(char *domain, unsigned char *ret_pwd,
+ time_t *pass_last_set_time);
+enum winbindd_result winbindd_check_machine_acct(
+ struct winbindd_cli_state *state);
+enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
+ *state);
/*The following definitions come from nsswitch/winbindd_pam.c */
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) ;
+enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state);
+
+/*The following definitions come from nsswitch/winbindd_sid.c */
+
+enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_user.c */
-enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state *state) ;
+enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
+ *state) ;
enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
*state);
enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state);
enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state);
+enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state);
/*The following definitions come from nsswitch/winbindd_util.c */
+void debug_conn_state(void);
BOOL domain_handles_open(struct winbindd_domain *domain);
-void establish_connections(void) ;
+void winbindd_kill_connections(struct winbindd_domain *domain);
+void winbindd_kill_all_connections(void);
+void establish_connections(BOOL force_reestablish) ;
BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain);
BOOL get_domain_info(struct winbindd_domain *domain);
-BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
- char *name, DOM_SID *sid,
+BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,
enum SID_NAME_USE *type);
-BOOL winbindd_lookup_name_by_sid(struct winbindd_domain *domain,
- DOM_SID *sid, char *name,
+BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,
enum SID_NAME_USE *type);
BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
- uint32 user_rid, SAM_USERINFO_CTR *user_info);
+ uint32 user_rid, SAM_USERINFO_CTR **user_info);
+BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
+ uint32 user_rid, uint32 *num_groups,
+ DOM_GID **user_groups);
BOOL winbindd_lookup_groupinfo(struct winbindd_domain *domain,
uint32 group_rid, GROUP_INFO_CTR *info);
BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
uint32 group_rid, uint32 *num_names,
uint32 **rid_mem, char ***names,
enum SID_NAME_USE **name_types);
-int winbindd_lookup_aliasmem(struct winbindd_domain *domain,
- uint32 alias_rid, uint32 *num_names,
- DOM_SID ***sids, char ***names,
- enum SID_NAME_USE **name_types);
struct winbindd_domain *find_domain_from_name(char *domain_name);
+struct winbindd_domain *find_domain_from_sid(DOM_SID *sid);
void free_getent_state(struct getent_state *state);
BOOL winbindd_param_init(void);
char *winbindd_cmd_to_string(enum winbindd_cmd cmd);
-void parse_domain_user(char *domuser, fstring domain, fstring user);
uint32 domain_sequence_number(char *domain_name);
-#endif /* _WINBINDD_PROTO_H_ */
+uint32 winbindd_query_dispinfo(struct winbindd_domain *domain,
+ uint32 *start_ndx, uint16 info_level,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr);
+BOOL check_domain_env(char *domain_env, char *domain);
+void parse_domain_user(char *domuser, fstring domain, fstring user);
+#endif /* _PROTO_H_ */
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index f3e62d2f7f1..15eb6054f19 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -2,7 +2,7 @@
Unix SMB/Netbios implementation.
Version 2.0
- Winbind daemon - user related function
+ Winbind daemon - user related functions
Copyright (C) Tim Potter 2000
@@ -25,144 +25,161 @@
/* Fill a pwent structure with information we have obtained */
-static void winbindd_fill_pwent(struct winbindd_pw *pw, char *name,
- uid_t unix_uid, gid_t unix_gid,
- char *full_name)
+static BOOL winbindd_fill_pwent(char *domain_name, char *name,
+ uint32 user_rid, uint32 group_rid,
+ char *full_name, struct winbindd_pw *pw)
{
- pstring homedir;
- fstring name_domain, name_user;
-
- if (!pw || !name) {
- return;
- }
-
- /* Fill in uid/gid */
-
- pw->pw_uid = unix_uid;
- pw->pw_gid = unix_gid;
-
- /* Username */
-
- safe_strcpy(pw->pw_name, name, sizeof(pw->pw_name) - 1);
-
- /* Full name (gecos) */
-
- safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1);
-
- /* Home directory and shell - use template config parameters. The
- defaults are /tmp for the home directory and /bin/false for shell. */
-
- parse_domain_user(name, name_domain, name_user);
-
- pstrcpy(homedir, lp_template_homedir());
-
- pstring_sub(homedir, "%U", name_user);
- pstring_sub(homedir, "%D", name_domain);
-
- safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1);
-
- safe_strcpy(pw->pw_shell, lp_template_shell(), sizeof(pw->pw_shell) - 1);
-
- /* Password - set to "x" as we can't generate anything useful here.
- Authentication can be done using the pam_ntdom module. */
-
- safe_strcpy(pw->pw_passwd, "x", sizeof(pw->pw_passwd) - 1);
+ extern userdom_struct current_user_info;
+ fstring name_domain, name_user;
+ pstring homedir;
+
+ if (!pw || !name) {
+ return False;
+ }
+
+ /* Resolve the uid number */
+
+ if (!winbindd_idmap_get_uid_from_rid(domain_name, user_rid,
+ &pw->pw_uid)) {
+ DEBUG(1, ("error getting user id for rid %d\n", user_rid));
+ return False;
+ }
+
+ /* Resolve the gid number */
+
+ if (!winbindd_idmap_get_gid_from_rid(domain_name, group_rid,
+ &pw->pw_gid)) {
+ DEBUG(1, ("error getting group id for rid %d\n", group_rid));
+ return False;
+ }
+
+ /* Username */
+
+ safe_strcpy(pw->pw_name, name, sizeof(pw->pw_name) - 1);
+
+ /* Full name (gecos) */
+
+ safe_strcpy(pw->pw_gecos, full_name, sizeof(pw->pw_gecos) - 1);
+
+ /* Home directory and shell - use template config parameters. The
+ defaults are /tmp for the home directory and /bin/false for
+ shell. */
+
+ parse_domain_user(name, name_domain, name_user);
+
+ /* The substitution of %U and %D in the 'template homedir' is done
+ by lp_string() calling standard_sub_basic(). */
+
+ fstrcpy(current_user_info.smb_name, name_user);
+ fstrcpy(current_user_info.domain, name_domain);
+
+ pstrcpy(homedir, lp_template_homedir());
+
+ safe_strcpy(pw->pw_dir, homedir, sizeof(pw->pw_dir) - 1);
+
+ safe_strcpy(pw->pw_shell, lp_template_shell(),
+ sizeof(pw->pw_shell) - 1);
+
+ /* Password - set to "x" as we can't generate anything useful here.
+ Authentication can be done using the pam_ntdom module. */
+
+ safe_strcpy(pw->pw_passwd, "x", sizeof(pw->pw_passwd) - 1);
+
+ return True;
}
/* Return a password structure from a username. Specify whether cached data
can be returned. */
-enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state *state)
+enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
+ *state)
{
- uint32 name_type, user_rid, group_rid;
- SAM_USERINFO_CTR user_info;
- DOM_SID user_sid;
- fstring name_domain, name_user, name, gecos_name;
- struct winbindd_domain *domain;
- uid_t uid;
- gid_t gid;
-
- /* Parse domain and username */
- parse_domain_user(state->request.data.username, name_domain, name_user);
-
- /* Reject names that don't have a domain - i.e name_domain contains the
- entire name. */
+ uint32 user_rid, group_rid;
+ SAM_USERINFO_CTR *user_info;
+ DOM_SID user_sid;
+ fstring name_domain, name_user, name, gecos_name;
+ struct winbindd_domain *domain;
+ enum SID_NAME_USE name_type;
+
+ DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
+ state->request.data.username));
+
+ /* Parse domain and username */
+
+ parse_domain_user(state->request.data.username, name_domain,
+ name_user);
+
+ /* Reject names that don't have a domain - i.e name_domain contains
+ the entire name. */
- if (strequal(name_domain, "")) {
- return WINBINDD_ERROR;
- }
-
- /* Get info for the domain */
-
- if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("could not find domain entry for domain %s\n", name_domain));
- return WINBINDD_ERROR;
- }
-
- /* Check for cached user entry */
-
- if (winbindd_fetch_user_cache_entry(name_domain, name_user,
- &state->response.data.pw)) {
- return WINBINDD_OK;
- }
-
- slprintf(name,sizeof(name)-1,"%s\\%s", name_domain, name_user);
-
- /* Get rid and name type from name */
- /* the following costs 1 packet */
- if (!winbindd_lookup_sid_by_name(domain, name, &user_sid, &name_type)) {
- DEBUG(1, ("user '%s' does not exist\n", name_user));
- return WINBINDD_ERROR;
- }
-
- if (name_type != SID_NAME_USER) {
- DEBUG(1, ("name '%s' is not a user name: %d\n", name_user, name_type));
- return WINBINDD_ERROR;
- }
-
- /* Get some user info. Split the user rid from the sid obtained from
- the winbind_lookup_by_name() call and use it in a
- winbind_lookup_userinfo() */
+ if (strequal(name_domain, "")) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Get info for the domain */
+
+ if ((domain = find_domain_from_name(name_domain)) == NULL) {
+ DEBUG(0, ("could not find domain entry for domain %s\n",
+ name_domain));
+ return WINBINDD_ERROR;
+ }
+
+ if (!domain_handles_open(domain)) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Check for cached user entry */
+
+ if (winbindd_fetch_user_cache_entry(name_domain, name_user,
+ &state->response.data.pw)) {
+ return WINBINDD_OK;
+ }
+
+ slprintf(name, sizeof(name) - 1, "%s\\%s", name_domain, name_user);
+
+ /* Get rid and name type from name. The following costs 1 packet */
+
+ if (!winbindd_lookup_sid_by_name(name, &user_sid, &name_type)) {
+ DEBUG(1, ("user '%s' does not exist\n", name_user));
+ return WINBINDD_ERROR;
+ }
+
+ if (name_type != SID_NAME_USER) {
+ DEBUG(1, ("name '%s' is not a user name: %d\n", name_user,
+ name_type));
+ return WINBINDD_ERROR;
+ }
+
+ /* Get some user info. Split the user rid from the sid obtained
+ from the winbind_lookup_by_name() call and use it in a
+ winbind_lookup_userinfo() */
- sid_split_rid(&user_sid, &user_rid);
-
- /* the following costs 3 packets */
- if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) {
- DEBUG(1, ("pwnam_from_user(): error getting user info for user '%s'\n",
- name_user));
- return WINBINDD_ERROR;
- }
+ sid_split_rid(&user_sid, &user_rid);
+
+ /* The following costs 3 packets */
+
+ if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) {
+ DEBUG(1, ("pwnam_from_user(): error getting user info for "
+ "user '%s'\n", name_user));
+ return WINBINDD_ERROR;
+ }
- group_rid = user_info.info.id21->group_rid;
- unistr2_to_ascii(gecos_name, &user_info.info.id21->uni_full_name,
- sizeof(gecos_name) - 1);
-
- free_samr_userinfo_ctr(&user_info);
-
- /* Resolve the uid number */
-
- if (!winbindd_idmap_get_uid_from_rid(domain->name, user_rid, &uid)) {
- DEBUG(1, ("error getting user id for user %s\n", name_user));
- return WINBINDD_ERROR;
- }
-
- /* Resolve the gid number */
-
- if (!winbindd_idmap_get_gid_from_rid(domain->name, group_rid, &gid)) {
- DEBUG(1, ("error getting group id for user %s\n", name_user));
- return WINBINDD_ERROR;
- }
-
- /* Now take all this information and fill in a passwd structure */
-
- winbindd_fill_pwent(&state->response.data.pw,
- state->request.data.username, uid, gid,
- gecos_name);
-
- winbindd_fill_user_cache_entry(name_domain, name_user,
- &state->response.data.pw);
-
- return WINBINDD_OK;
+ group_rid = user_info->info.id21->group_rid;
+ unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name,
+ sizeof(gecos_name) - 1);
+
+ /* Now take all this information and fill in a passwd structure */
+
+ if (!winbindd_fill_pwent(domain->name, state->request.data.username,
+ user_rid, group_rid, gecos_name,
+ &state->response.data.pw)) {
+ return WINBINDD_ERROR;
+ }
+
+ winbindd_store_user_cache_entry(name_domain, name_user,
+ &state->response.data.pw);
+
+ return WINBINDD_OK;
}
/* Return a password structure given a uid number */
@@ -170,77 +187,93 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state *stat
enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
*state)
{
- DOM_SID user_sid;
- struct winbindd_domain *domain;
- uint32 user_rid, group_rid;
- fstring user_name, gecos_name;
- enum SID_NAME_USE name_type;
- SAM_USERINFO_CTR user_info;
- gid_t gid;
-
- /* Get rid from uid */
- if (!winbindd_idmap_get_rid_from_uid(state->request.data.uid, &user_rid,
- &domain)) {
- DEBUG(1, ("Could not convert uid %d to rid\n",
- state->request.data.uid));
- return WINBINDD_ERROR;
- }
-
- /* Check for cached uid entry */
- if (winbindd_fetch_uid_cache_entry(domain->name, state->request.data.uid,
- &state->response.data.pw)) {
- return WINBINDD_OK;
- }
-
-
- /* Get name and name type from rid */
-
- sid_copy(&user_sid, &domain->sid);
- sid_append_rid(&user_sid, user_rid);
-
- if (!winbindd_lookup_name_by_sid(domain, &user_sid, user_name,
- &name_type)) {
- fstring temp;
-
- sid_to_string(temp, &user_sid);
- DEBUG(1, ("Could not lookup sid %s\n", temp));
- return WINBINDD_ERROR;
- }
-
- if (strcmp("\\", lp_winbind_separator())) {
- string_sub(user_name, "\\", lp_winbind_separator(), sizeof(fstring));
- }
-
- /* Get some user info */
-
- if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) {
- DEBUG(1, ("pwnam_from_uid(): error getting user info for user '%s'\n",
- user_name));
- return WINBINDD_ERROR;
- }
-
- group_rid = user_info.info.id21->group_rid;
- unistr2_to_ascii(gecos_name, &user_info.info.id21->uni_full_name,
- sizeof(gecos_name) - 1);
-
- free_samr_userinfo_ctr(&user_info);
-
- /* Resolve gid number */
-
- if (!winbindd_idmap_get_gid_from_rid(domain->name, group_rid, &gid)) {
- DEBUG(1, ("error getting group id for user %s\n", user_name));
- return WINBINDD_ERROR;
- }
-
- /* Fill in password structure */
-
- winbindd_fill_pwent(&state->response.data.pw, user_name,
- state->request.data.uid, gid, gecos_name);
-
- winbindd_fill_uid_cache_entry(domain->name, state->request.data.uid,
- &state->response.data.pw);
-
- return WINBINDD_OK;
+ DOM_SID user_sid;
+ struct winbindd_domain *domain;
+ uint32 user_rid, group_rid;
+ fstring user_name, gecos_name;
+ enum SID_NAME_USE name_type;
+ SAM_USERINFO_CTR *user_info;
+ gid_t gid;
+
+ /* Bug out if the uid isn't in the winbind range */
+
+ if ((state->request.data.uid < server_state.uid_low ) ||
+ (state->request.data.uid > server_state.uid_high)) {
+ return WINBINDD_ERROR;
+ }
+
+ DEBUG(3, ("[%5d]: getpwuid %d\n", state->pid,
+ state->request.data.uid));
+
+ /* Get rid from uid */
+
+ if (!winbindd_idmap_get_rid_from_uid(state->request.data.uid,
+ &user_rid, &domain)) {
+ DEBUG(1, ("Could not convert uid %d to rid\n",
+ state->request.data.uid));
+ return WINBINDD_ERROR;
+ }
+
+ if (!domain_handles_open(domain)) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Check for cached uid entry */
+
+ if (winbindd_fetch_uid_cache_entry(domain->name,
+ state->request.data.uid,
+ &state->response.data.pw)) {
+ return WINBINDD_OK;
+ }
+
+ /* Get name and name type from rid */
+
+ sid_copy(&user_sid, &domain->sid);
+ sid_append_rid(&user_sid, user_rid);
+
+ if (!winbindd_lookup_name_by_sid(&user_sid, user_name, &name_type)) {
+ fstring temp;
+
+ sid_to_string(temp, &user_sid);
+ DEBUG(1, ("Could not lookup sid %s\n", temp));
+ return WINBINDD_ERROR;
+ }
+
+ if (strcmp("\\", lp_winbind_separator())) {
+ string_sub(user_name, "\\", lp_winbind_separator(),
+ sizeof(fstring));
+ }
+
+ /* Get some user info */
+
+ if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) {
+ DEBUG(1, ("pwnam_from_uid(): error getting user info for "
+ "user '%s'\n", user_name));
+ return WINBINDD_ERROR;
+ }
+
+ group_rid = user_info->info.id21->group_rid;
+ unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name,
+ sizeof(gecos_name) - 1);
+
+ /* Resolve gid number */
+
+ if (!winbindd_idmap_get_gid_from_rid(domain->name, group_rid, &gid)) {
+ DEBUG(1, ("error getting group id for user %s\n", user_name));
+ return WINBINDD_ERROR;
+ }
+
+ /* Fill in password structure */
+
+ if (!winbindd_fill_pwent(domain->name, user_name, user_rid, group_rid,
+ gecos_name, &state->response.data.pw)) {
+ return WINBINDD_ERROR;
+ }
+
+ winbindd_store_uid_cache_entry(domain->name, state->request.data.uid,
+ &state->response.data.pw);
+
+ return WINBINDD_OK;
}
/*
@@ -253,8 +286,16 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
{
struct winbindd_domain *tmp;
+ DEBUG(3, ("[%5d]: setpwent\n", state->pid));
+
if (state == NULL) return WINBINDD_ERROR;
+ /* Check user has enabled this */
+
+ if (!lp_winbind_enum_users()) {
+ return WINBINDD_ERROR;
+ }
+
/* Free old static data if it exists */
if (state->getpwent_state != NULL) {
@@ -270,7 +311,7 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
/* Skip domains other than WINBINDD_DOMAIN environment variable */
if ((strcmp(state->request.domain, "") != 0) &&
- (strcmp(state->request.domain, tmp->name) != 0)) {
+ !check_domain_env(state->request.domain, tmp->name)) {
continue;
}
@@ -297,6 +338,8 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state)
{
+ DEBUG(3, ("[%5d]: endpwent\n", state->pid));
+
if (state == NULL) return WINBINDD_ERROR;
free_getent_state(state->getpwent_state);
@@ -305,110 +348,353 @@ enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state)
return WINBINDD_OK;
}
+/* Get partial list of domain users for a domain. We fill in the sam_entries,
+ and num_sam_entries fields with domain user information. The dispinfo_ndx
+ field is incremented to the index of the next user to fetch. Return True if
+ some users were returned, False otherwise. */
+
+#define MAX_FETCH_SAM_ENTRIES 100
+
+static BOOL get_sam_user_entries(struct getent_state *ent)
+{
+ uint32 status, num_entries;
+ SAM_DISPINFO_1 info1;
+ SAM_DISPINFO_CTR ctr;
+ struct getpwent_user *name_list = NULL;
+ uint32 group_rid;
+
+ if (ent->got_all_sam_entries) {
+ return False;
+ }
+
+ ZERO_STRUCT(info1);
+ ZERO_STRUCT(ctr);
+
+ ctr.sam.info1 = &info1;
+
+#if 0
+ /* Look in cache for entries, else get them direct */
+
+ if (winbindd_fetch_user_cache(ent->domain->name,
+ (struct getpwent_user **)
+ &ent->sam_entries,
+ &ent->num_sam_entries)) {
+ return True;
+ }
+#endif
+
+ /* For the moment we set the primary group for every user to be the
+ Domain Users group. There are serious problems with determining
+ the actual primary group for large domains. This should really
+ be made into a 'winbind force group' smb.conf parameter or
+ something like that. */
+
+ group_rid = DOMAIN_GROUP_RID_USERS;
+
+ if (!domain_handles_open(ent->domain)) {
+ return WINBINDD_ERROR;
+ }
+
+ /* Free any existing user info */
+
+ if (ent->sam_entries) {
+ free(ent->sam_entries);
+ ent->sam_entries = NULL;
+ ent->num_sam_entries = 0;
+ }
+
+ /* Call query_dispinfo to get a list of usernames and user rids */
+
+ do {
+ int i;
+
+ num_entries = 0;
+
+ status = winbindd_query_dispinfo(ent->domain,
+ &ent->dispinfo_ndx, 1,
+ &num_entries, &ctr);
+
+ if (num_entries) {
+ struct getpwent_user *tnl;
+
+ tnl = (struct getpwent_user *)Realloc(name_list,
+ sizeof(struct getpwent_user) *
+ (ent->num_sam_entries +
+ num_entries));
+
+ if (!tnl) {
+ DEBUG(0,("get_sam_user_entries: Realloc failed.\n"));
+ if (name_list)
+ free(name_list);
+ return WINBINDD_ERROR;
+ } else
+ name_list = tnl;
+ }
+
+ for (i = 0; i < num_entries; i++) {
+
+ /* Store account name and gecos */
+
+ unistr2_to_ascii(
+ name_list[ent->num_sam_entries + i].name,
+ &info1.str[i].uni_acct_name,
+ sizeof(fstring));
+
+ unistr2_to_ascii(
+ name_list[ent->num_sam_entries + i].gecos,
+ &info1.str[i].uni_full_name,
+ sizeof(fstring));
+
+ /* User and group ids */
+
+ name_list[ent->num_sam_entries + i].user_rid =
+ info1.sam[i].rid_user;
+
+ name_list[ent->num_sam_entries + i].
+ group_rid = group_rid;
+ }
+
+ ent->num_sam_entries += num_entries;
+
+ if (status != STATUS_MORE_ENTRIES) {
+ break;
+ }
+
+ } while (ent->num_sam_entries < MAX_FETCH_SAM_ENTRIES);
+
+#if 0
+ /* Fill cache with received entries */
+
+ winbindd_store_user_cache(ent->domain->name, ent->sam_entries,
+ ent->num_sam_entries);
+#endif
+
+ /* Fill in remaining fields */
+
+ ent->sam_entries = name_list;
+ ent->sam_entry_index = 0;
+ ent->got_all_sam_entries = (status != STATUS_MORE_ENTRIES);
+
+ return ent->num_sam_entries > 0;
+}
+
/* Fetch next passwd entry from ntdom database */
+#define MAX_GETPWENT_USERS 500
+
enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
{
- if (state == NULL) return WINBINDD_ERROR;
+ struct getent_state *ent;
+ struct winbindd_pw *user_list;
+ int num_users, user_list_ndx = 0, i;
+ char *sep;
- /* Process the current head of the getent_state list */
+ DEBUG(3, ("[%5d]: getpwent\n", state->pid));
- while(state->getpwent_state != NULL) {
- struct getent_state *ent = state->getpwent_state;
+ if (state == NULL) return WINBINDD_ERROR;
- /* Get list of user entries for this pipe */
+ /* Check user has enabled this */
- if (!ent->got_sam_entries) {
- uint32 status, start_ndx = 0;
+ if (!lp_winbind_enum_users()) {
+ return WINBINDD_ERROR;
+ }
- /* Look in cache for entries, else get them direct */
+ /* Allocate space for returning a chunk of users */
- if (!winbindd_fetch_user_cache(ent->domain->name,
- &ent->sam_entries,
- &ent->num_sam_entries)) {
+ num_users = MIN(MAX_GETPWENT_USERS, state->request.data.num_entries);
+
+ if ((state->response.extra_data =
+ malloc(num_users * sizeof(struct winbindd_pw))) == NULL) {
+ return WINBINDD_ERROR;
+ }
- /* Fetch the user entries */
+ memset(state->response.extra_data, 0, num_users *
+ sizeof(struct winbindd_pw));
- if (!domain_handles_open(ent->domain)) goto cleanup;
+ user_list = (struct winbindd_pw *)state->response.extra_data;
+ sep = lp_winbind_separator();
+
+ if (!(ent = state->getpwent_state)) {
+ return WINBINDD_ERROR;
+ }
- do {
- status =
- samr_enum_dom_users(
- &ent->domain->sam_dom_handle, &start_ndx, 0, 0,
- 0x10000, &ent->sam_entries, &ent->num_sam_entries);
- } while (status == STATUS_MORE_ENTRIES);
+ /* Start sending back users */
- /* Fill cache with received entries */
-
- winbindd_fill_user_cache(ent->domain->name, ent->sam_entries,
- ent->num_sam_entries);
- }
-
- ent->got_sam_entries = True;
- }
-
- /* Send back a user */
-
- while (ent->sam_entry_index < ent->num_sam_entries) {
- enum winbindd_result result;
- fstring domain_user_name;
- char *user_name = (ent->sam_entries)
- [ent->sam_entry_index].acct_name;
-
- /* Don't bother with machine accounts */
-
- if (user_name[strlen(user_name) - 1] == '$') {
- ent->sam_entry_index++;
- continue;
- }
-
- /* Prepend domain to name */
-
- slprintf(domain_user_name, sizeof(domain_user_name)-1,
- "%s%s%s", ent->domain->name, lp_winbind_separator(), user_name);
-
- /* Get passwd entry from user name */
-
- fstrcpy(state->request.data.username, domain_user_name);
- result = winbindd_getpwnam_from_user(state);
-
- ent->sam_entry_index++;
-
- /* Return if user lookup worked */
-
- if (result == WINBINDD_OK) {
- return result;
- }
-
- /* Try next user */
-
- DEBUG(1, ("could not getpwnam_from_user for username %s\n",
- domain_user_name));
- }
+ for (i = 0; i < num_users; i++) {
+ struct getpwent_user *name_list = NULL;
+ fstring domain_user_name;
+ uint32 result;
- /* We've exhausted all users for this pipe - close it down and
- start on the next one. */
+ /* Do we need to fetch another chunk of users? */
- cleanup:
+ if (ent->num_sam_entries == ent->sam_entry_index) {
- /* Free mallocated memory for sam entries. The data stored here
- may have been allocated from the cache. */
+ while(ent && !get_sam_user_entries(ent)) {
+ struct getent_state *next_ent;
- if (ent->sam_entries != NULL) free(ent->sam_entries);
- ent->sam_entries = NULL;
+ /* Free state information for this domain */
- /* Free state information for this domain */
+ safe_free(ent->sam_entries);
+ ent->sam_entries = NULL;
- {
- struct getent_state *old_ent;
+ next_ent = ent->next;
+ DLIST_REMOVE(state->getpwent_state, ent);
+
+ free(ent);
+ ent = next_ent;
+ }
+
+ /* No more domains */
+
+ if (!ent) break;
+ }
+
+ name_list = ent->sam_entries;
+
+ /* Skip machine accounts */
+
+ if (name_list[ent->sam_entry_index].
+ name[strlen(name_list[ent->sam_entry_index].name) - 1]
+ == '$') {
+ ent->sam_entry_index++;
+ continue;
+ }
+
+ /* Lookup user info */
+
+ slprintf(domain_user_name, sizeof(domain_user_name) - 1,
+ "%s%s%s", ent->domain->name, sep,
+ name_list[ent->sam_entry_index].name);
+
+ result = winbindd_fill_pwent(
+ ent->domain->name,
+ domain_user_name,
+ name_list[ent->sam_entry_index].user_rid,
+ name_list[ent->sam_entry_index].group_rid,
+ name_list[ent->sam_entry_index].gecos,
+ &user_list[user_list_ndx]);
+
+ ent->sam_entry_index++;
+
+ /* Add user to return list */
+
+ if (result) {
+
+ user_list_ndx++;
+ state->response.data.num_entries++;
+ state->response.length +=
+ sizeof(struct winbindd_pw);
+
+ } else {
+ DEBUG(1, ("could not lookup domain user %s\n",
+ domain_user_name));
+ }
+
+ }
+
+ /* Out of domains */
+
+ return (user_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR;
+}
- old_ent = state->getpwent_state;
- DLIST_REMOVE(state->getpwent_state, state->getpwent_state);
- free(old_ent);
+/* List domain users without mapping to unix ids */
+
+enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
+{
+ struct winbindd_domain *domain;
+ SAM_DISPINFO_CTR ctr;
+ SAM_DISPINFO_1 info1;
+ uint32 num_entries = 0, total_entries = 0;
+ char *ted, *extra_data = NULL;
+ int extra_data_len = 0;
+
+ DEBUG(3, ("[%5d]: list users\n", state->pid));
+
+ /* Enumerate over trusted domains */
+
+ ctr.sam.info1 = &info1;
+
+ for (domain = domain_list; domain; domain = domain->next) {
+ uint32 status, start_ndx = 0;
+
+ /* Skip domains other than WINBINDD_DOMAIN environment
+ variable */
+
+ if ((strcmp(state->request.domain, "") != 0) &&
+ !check_domain_env(state->request.domain, domain->name)) {
+ continue;
+ }
+
+ if (!domain_handles_open(domain)) {
+ continue;
+ }
+
+ /* Query display info */
+
+ do {
+ int i;
+
+ status = winbindd_query_dispinfo(domain, &start_ndx,
+ 1, &num_entries,
+ &ctr);
+
+ if (num_entries == 0) {
+ continue;
+ }
+
+ /* Allocate some memory for extra data */
+
+ total_entries += num_entries;
+
+ ted = Realloc(extra_data, sizeof(fstring) *
+ total_entries);
+
+ if (!ted) {
+ DEBUG(0,("winbindd_list_users: failed to enlarge buffer!\n"));
+ if (extra_data)
+ free(extra_data);
+ return WINBINDD_ERROR;
+ } else
+ extra_data = ted;
+
+ /* Pack user list into extra data fields */
+
+ for (i = 0; i < num_entries; i++) {
+ UNISTR2 *uni_acct_name;
+ fstring acct_name, name;
+
+ /* Convert unistring to ascii */
+
+ uni_acct_name = &ctr.sam.info1->str[i].
+ uni_acct_name;
+ unistr2_to_ascii(acct_name, uni_acct_name,
+ sizeof(acct_name) - 1);
+
+ slprintf(name, sizeof(name) - 1, "%s%s%s",
+ domain->name, lp_winbind_separator(),
+ acct_name);
+
+ /* Append to extra data */
+
+ memcpy(&extra_data[extra_data_len], name,
+ strlen(name));
+ extra_data_len += strlen(name);
+
+ extra_data[extra_data_len++] = ',';
+ }
+ } while (status == STATUS_MORE_ENTRIES);
}
- }
- /* Out of pipes so we're done */
+ /* Assign extra_data fields in response structure */
+
+ if (extra_data) {
+ extra_data[extra_data_len - 1] = '\0';
+ state->response.extra_data = extra_data;
+ state->response.length += extra_data_len;
+ }
+
+ /* No domains responded but that's still OK so don't return an
+ error. */
- return WINBINDD_ERROR;
+ return WINBINDD_OK;
}
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 80d6955e6c0..aadc709da2b 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -22,36 +22,40 @@
*/
#include "winbindd.h"
+#include "sids.h"
-BOOL domain_handles_open(struct winbindd_domain *domain)
-{
- return domain->sam_handle_open &&
- domain->sam_dom_handle_open &&
- rpc_hnd_ok(&domain->sam_handle) &&
- rpc_hnd_ok(&domain->sam_dom_handle);
-}
+/* Debug connection state */
-static BOOL resolve_dc_name(char *domain_name, fstring domain_controller)
+void debug_conn_state(void)
{
- struct in_addr ip;
- extern pstring global_myname;
-
- /* if its our primary domain and password server is not '*' then use the
- password server parameter */
- if (strcmp(domain_name,lp_workgroup()) == 0 && !lp_wildcard_dc()) {
- fstrcpy(domain_controller, lp_passwordserver());
- return True;
- }
+ struct winbindd_domain *domain;
- if (!resolve_name(domain_name, &ip, 0x1B)) return False;
+ DEBUG(3, ("server: dc=%s, pwdb_init=%d, lsa_hnd=%d\n",
+ server_state.controller,
+ server_state.pwdb_initialised,
+ server_state.lsa_handle_open));
- return lookup_pdc_name(global_myname, domain_name, &ip,
- domain_controller);
+ for (domain = domain_list; domain; domain = domain->next) {
+ DEBUG(3, ("%s: dc=%s, got_sid=%d, sam_hnd=%d sam_dom_hnd=%d\n",
+ domain->name, domain->controller,
+ domain->got_domain_info, domain->sam_handle_open,
+ domain->sam_dom_handle_open));
+ }
}
+/* Add a trusted domain to our list of domains */
+
static struct winbindd_domain *add_trusted_domain(char *domain_name)
{
- struct winbindd_domain *domain;
+ struct winbindd_domain *domain, *tmp;
+
+ for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ if (strcmp(domain_name, tmp->name) == 0) {
+ DEBUG(3, ("domain %s already in trusted list\n",
+ domain_name));
+ return tmp;
+ }
+ }
DEBUG(1, ("adding trusted domain %s\n", domain_name));
@@ -77,12 +81,13 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name)
}
/* Look up global info for the winbind daemon */
+
static BOOL get_trusted_domains(void)
{
uint32 enum_ctx = 0;
uint32 num_doms = 0;
char **domains = NULL;
- DOM_SID **sids = NULL;
+ DOM_SID *sids = NULL;
BOOL result;
int i;
@@ -96,8 +101,8 @@ static BOOL get_trusted_domains(void)
}
/* Enumerate list of trusted domains */
- result = lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx,
- &num_doms, &domains, &sids);
+ result = wb_lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx,
+ &num_doms, &domains, &sids);
if (!result || !domains) return False;
@@ -110,100 +115,183 @@ static BOOL get_trusted_domains(void)
}
}
- /* Free memory */
- free_char_array(num_doms, domains);
- free_sid_array(num_doms, sids);
-
return True;
}
+/* Open sam and sam domain handles */
-/* Open sam and sam domain handles to a domain and cache the results */
static BOOL open_sam_handles(struct winbindd_domain *domain)
{
- /* Get domain info */
+ /* Get domain info (sid and controller name) */
+
if (!domain->got_domain_info) {
domain->got_domain_info = get_domain_info(domain);
if (!domain->got_domain_info) return False;
}
- if ((domain->sam_handle_open && !rpc_hnd_ok(&domain->sam_handle)) ||
- (domain->sam_dom_handle_open &&
- !rpc_hnd_ok(&domain->sam_dom_handle))) {
+ /* Shut down existing sam handles */
- domain->got_domain_info = get_domain_info(domain);
- if (domain->sam_dom_handle_open) {
- samr_close(&domain->sam_dom_handle);
- domain->sam_dom_handle_open = False;
- }
- if (domain->sam_handle_open) {
- samr_close(&domain->sam_handle);
- domain->sam_handle_open = False;
- }
+ if (domain->sam_dom_handle_open) {
+ wb_samr_close(&domain->sam_dom_handle);
+ domain->sam_dom_handle_open = False;
}
- /* Open sam handle if it isn't already open */
+ if (domain->sam_handle_open) {
+ wb_samr_close(&domain->sam_handle);
+ domain->sam_handle_open = False;
+ }
- if (!domain->sam_handle_open) {
+ /* Open sam handle */
- domain->sam_handle_open =
- samr_connect(domain->controller,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &domain->sam_handle);
+ domain->sam_handle_open =
+ wb_samr_connect(domain->controller,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain->sam_handle);
- if (!domain->sam_handle_open) return False;
- }
+ if (!domain->sam_handle_open) return False;
+
+ /* Open sam domain handle */
+
+ domain->sam_dom_handle_open =
+ wb_samr_open_domain(&domain->sam_handle,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain->sid,
+ &domain->sam_dom_handle);
+
+ if (!domain->sam_dom_handle_open) return False;
+
+ return True;
+}
+
+static BOOL rpc_hnd_ok(CLI_POLICY_HND *hnd)
+{
+ return hnd->cli->fd != -1;
+}
+
+/* Return true if the SAM domain handles are open and responding. */
- /* Open sam domain handle if it isn't already open */
+BOOL domain_handles_open(struct winbindd_domain *domain)
+{
+ time_t t;
+ BOOL result;
- if (!domain->sam_dom_handle_open) {
+ /* Check we haven't checked too recently */
- domain->sam_dom_handle_open =
- samr_open_domain(&domain->sam_handle,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &domain->sid, &domain->sam_dom_handle);
+ t = time(NULL);
- if (!domain->sam_dom_handle_open) return False;
+ if ((t - domain->last_check) < WINBINDD_ESTABLISH_LOOP) {
+ return domain->sam_handle_open &&
+ domain->sam_dom_handle_open;
}
- return True;
+ DEBUG(3, ("checking domain handles for domain %s\n", domain->name));
+ debug_conn_state();
+
+ domain->last_check = t;
+
+ /* Open sam handles if they are marked as closed */
+
+ if (!domain->sam_handle_open || !domain->sam_dom_handle_open) {
+ reopen:
+ DEBUG(3, ("opening sam handles\n"));
+ return open_sam_handles(domain);
+ }
+
+ /* Check sam handles are ok - the domain controller may have failed
+ and we need to move to a BDC. */
+
+ if (!rpc_hnd_ok(&domain->sam_handle) ||
+ !rpc_hnd_ok(&domain->sam_dom_handle)) {
+
+ /* We want to close the current connection but attempt
+ to open a new set, possibly to a new dc. If this
+ doesn't work then return False as we have no dc
+ to talk to. */
+
+ DEBUG(3, ("sam handles not responding\n"));
+
+ winbindd_kill_connections(domain);
+ goto reopen;
+ }
+
+ result = domain->sam_handle_open && domain->sam_dom_handle_open;
+
+ return result;
}
-/* Close all LSA and SAM connections */
+/* Shut down connections to all domain controllers */
-static void winbindd_kill_connections(void)
+void winbindd_kill_connections(struct winbindd_domain *domain)
{
- struct winbindd_cli_state *cli;
- struct winbindd_domain *domain;
+ /* Kill all connections */
+
+ if (!domain) {
+ struct winbindd_domain *tmp;
+
+ for (tmp = domain_list; tmp; tmp = tmp->next) {
+ winbindd_kill_connections(domain);
+ }
+
+ return;
+ }
+
+ /* Log a level 0 message - this is probably a domain controller
+ failure */
- DEBUG(1,("killing winbindd connections\n"));
+ if (!domain->controller[0])
+ return;
- /* Close LSA connection */
+ DEBUG(0, ("killing connections to domain %s with controller %s\n",
+ domain->name, domain->controller));
- server_state.pwdb_initialised = False;
- server_state.lsa_handle_open = False;
- lsa_close(&server_state.lsa_handle);
+ debug_conn_state();
+
+ /* Close LSA connections if we are killing connections to the dc
+ that has them open. */
+
+ if (strequal(server_state.controller, domain->controller)) {
+ server_state.pwdb_initialised = False;
+ server_state.lsa_handle_open = False;
+ wb_lsa_close(&server_state.lsa_handle);
+ }
- /* Close SAM connections */
+ /* Close domain sam handles but don't free them as this
+ severely traumatises the getent state. The connections
+ will be reopened later. */
+
+ if (domain->sam_dom_handle_open) {
+ wb_samr_close(&domain->sam_dom_handle);
+ domain->sam_dom_handle_open = False;
+ }
+
+ if (domain->sam_handle_open) {
+ wb_samr_close(&domain->sam_handle);
+ domain->sam_handle_open = False;
+ }
+
+ /* Re-lookup domain info which includes domain controller name */
+
+ domain->got_domain_info = False;
+}
+
+/* Kill connections to all servers */
+
+void winbindd_kill_all_connections(void)
+{
+ struct winbindd_domain *domain;
+
+ /* Iterate over domain list */
domain = domain_list;
- while(domain) {
+ while (domain) {
struct winbindd_domain *next;
- /* Close SAM handles */
-
- if (domain->sam_dom_handle_open) {
- samr_close(&domain->sam_dom_handle);
- domain->sam_dom_handle_open = False;
- }
+ /* Kill conections */
- if (domain->sam_handle_open) {
- samr_close(&domain->sam_handle);
- domain->sam_handle_open = False;
- }
+ winbindd_kill_connections(domain);
- /* Remove from list */
+ /* Remove domain from list */
next = domain->next;
DLIST_REMOVE(domain_list, domain);
@@ -211,68 +299,113 @@ static void winbindd_kill_connections(void)
domain = next;
}
+}
- /* We also need to go through and trash any pointers to domains in
- get{pw,gr}ent state records */
+static BOOL get_any_dc_name(char *domain, fstring srv_name)
+{
+ struct in_addr *ip_list, dc_ip;
+ extern pstring global_myname;
+ int count, i;
- for (cli = client_list; cli; cli = cli->next) {
- free_getent_state(cli->getpwent_state);
- free_getent_state(cli->getgrent_state);
+ /* Lookup domain controller name */
+
+ if (!get_dc_list(False, domain, &ip_list, &count))
+ return False;
+
+ /* Firstly choose a PDC/BDC who has the same network address as any
+ of our interfaces. */
+
+ for (i = 0; i < count; i++) {
+ if(!is_local_net(ip_list[i]))
+ goto got_ip;
}
+
+ i = (sys_random() % count);
+
+ got_ip:
+ dc_ip = ip_list[i];
+ free(ip_list);
+
+ if (!lookup_pdc_name(global_myname, domain, &dc_ip, srv_name))
+ return False;
+
+ return True;
}
-/* Try to establish connections to NT servers */
+/* Attempt to connect to all domain controllers we know about */
-void establish_connections(void)
+void establish_connections(BOOL force_reestablish)
{
- struct winbindd_domain *domain;
static time_t lastt;
time_t t;
+ /* Check we haven't checked too recently */
+
t = time(NULL);
- if (t - lastt < WINBINDD_ESTABLISH_LOOP) return;
+ if ((t - lastt < WINBINDD_ESTABLISH_LOOP) && !force_reestablish) {
+ return;
+ }
lastt = t;
- /* maybe the connection died - if so then close up and restart */
+ DEBUG(3, ("establishing connections\n"));
+ debug_conn_state();
+
+ /* Maybe the connection died - if so then close up and restart */
+
if (server_state.pwdb_initialised &&
server_state.lsa_handle_open &&
!rpc_hnd_ok(&server_state.lsa_handle)) {
- winbindd_kill_connections();
+ winbindd_kill_connections(NULL);
}
if (!server_state.pwdb_initialised) {
- fstrcpy(server_state.controller, lp_passwordserver());
- if (lp_wildcard_dc()) {
- if (!resolve_dc_name(lp_workgroup(), server_state.controller)) {
- return;
- }
+
+ /* Lookup domain controller name */
+
+ if (!get_any_dc_name(lp_workgroup(),
+ server_state.controller)) {
+ DEBUG(3, ("could not find any domain controllers "
+ "for domain %s\n", lp_workgroup()));
+ return;
}
- server_state.pwdb_initialised = pwdb_initialise(False);
- if (!server_state.pwdb_initialised) return;
+ /* Initialise password database and sids */
+
+ /* server_state.pwdb_initialised = pwdb_initialise(False); */
+ server_state.pwdb_initialised = True;
+
+ if (!server_state.pwdb_initialised) {
+ DEBUG(3, ("could not initialise pwdb\n"));
+ return;
+ }
}
/* Open lsa handle if it isn't already open */
+
if (!server_state.lsa_handle_open) {
+
server_state.lsa_handle_open =
- lsa_open_policy(server_state.controller, &server_state.lsa_handle,
- False, SEC_RIGHTS_MAXIMUM_ALLOWED);
- if (!server_state.lsa_handle_open) return;
+ wb_lsa_open_policy(server_state.controller,
+ False, SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &server_state.lsa_handle);
+
+ if (!server_state.lsa_handle_open) {
+ DEBUG(0, ("error opening lsa handle on dc %s\n",
+ server_state.controller));
+ return;
+ }
+
+ /* Now we can talk to the server we can get some info */
- /* now we can talk to the server we can get some info */
get_trusted_domains();
}
- for (domain=domain_list; domain; domain=domain->next) {
- if (!domain_handles_open(domain)) {
- open_sam_handles(domain);
- }
- }
+ debug_conn_state();
}
-
/* Connect to a domain controller using get_any_dc_name() to discover
the domain name and sid */
+
BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
{
fstring level5_dom;
@@ -280,7 +413,7 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
uint32 enum_ctx = 0;
uint32 num_doms = 0;
char **domains = NULL;
- DOM_SID **sids = NULL;
+ DOM_SID *sids = NULL;
if (domain == NULL) {
return False;
@@ -289,20 +422,24 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
DEBUG(1, ("looking up sid for domain %s\n", domain_name));
/* Get controller name for domain */
- if (!resolve_dc_name(domain_name, domain->controller)) {
+
+ if (!get_any_dc_name(domain_name, domain->controller)) {
+ DEBUG(0, ("Could not resolve domain controller for domain %s\n",
+ domain_name));
return False;
}
- if (strequal(domain->controller, server_state.controller)) {
- /* Do a level 5 query info policy */
- return lsa_query_info_pol(&server_state.lsa_handle, 0x05,
- level5_dom, &domain->sid);
+ /* Do a level 5 query info policy if we are looking up our own SID */
+
+ if (strequal(domain_name, lp_workgroup())) {
+ return wb_lsa_query_info_pol(&server_state.lsa_handle, 0x05,
+ level5_dom, &domain->sid);
}
/* Use lsaenumdomains to get sid for this domain */
- res = lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx,
- &num_doms, &domains, &sids);
+ res = wb_lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx,
+ &num_doms, &domains, &sids);
/* Look for domain name */
@@ -312,7 +449,7 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
for(i = 0; i < num_doms; i++) {
if (strequal(domain_name, domains[i])) {
- sid_copy(&domain->sid, sids[i]);
+ sid_copy(&domain->sid, &sids[i]);
found = True;
break;
}
@@ -321,15 +458,9 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
res = found;
}
- /* Free memory */
-
- free_char_array(num_doms, domains);
- free_sid_array(num_doms, sids);
-
return res;
}
-
/* Lookup domain controller and sid for a domain */
BOOL get_domain_info(struct winbindd_domain *domain)
@@ -339,8 +470,14 @@ BOOL get_domain_info(struct winbindd_domain *domain)
DEBUG(1, ("Getting domain info for domain %s\n", domain->name));
/* Lookup domain sid */
+
if (!lookup_domain_sid(domain->name, domain)) {
DEBUG(0, ("could not find sid for domain %s\n", domain->name));
+
+ /* Could be a DC failure - shut down connections to this domain */
+
+ winbindd_kill_connections(domain);
+
return False;
}
@@ -356,8 +493,7 @@ BOOL get_domain_info(struct winbindd_domain *domain)
/* Lookup a sid in a domain from a name */
-BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
- char *name, DOM_SID *sid,
+BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,
enum SID_NAME_USE *type)
{
int num_sids = 0, num_names = 1;
@@ -373,8 +509,8 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
/* Lookup name */
- res = lsa_lookup_names(&server_state.lsa_handle, num_names, (char **)&name,
- &sids, &types, &num_sids);
+ res = wb_lsa_lookup_names(&server_state.lsa_handle, num_names,
+ (char **)&name, &sids, &types, &num_sids);
/* Return rid and type if lookup successful */
@@ -393,18 +529,12 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
}
}
- /* Free memory */
-
- if (types != NULL) free(types);
- if (sids != NULL) free(sids);
-
return res;
}
/* Lookup a name in a domain from a sid */
-BOOL winbindd_lookup_name_by_sid(struct winbindd_domain *domain,
- DOM_SID *sid, char *name,
+BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,
enum SID_NAME_USE *type)
{
int num_sids = 1, num_names = 0;
@@ -413,8 +543,9 @@ BOOL winbindd_lookup_name_by_sid(struct winbindd_domain *domain,
BOOL res;
/* Lookup name */
- res = lsa_lookup_sids(&server_state.lsa_handle, num_sids, &sid, &names,
- &types, &num_names);
+
+ res = wb_lsa_lookup_sids(&server_state.lsa_handle, num_sids, sid,
+ &names, &types, &num_names);
/* Return name and type if successful */
@@ -433,32 +564,57 @@ BOOL winbindd_lookup_name_by_sid(struct winbindd_domain *domain,
}
}
- /* Free memory */
-
- safe_free(types);
- free_char_array(num_names, names);
-
return res;
}
/* Lookup user information from a rid */
BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
- uint32 user_rid, SAM_USERINFO_CTR *user_info)
+ uint32 user_rid, SAM_USERINFO_CTR **user_info)
{
- if (!domain_handles_open(domain)) return False;
-
- return get_samr_query_userinfo(&domain->sam_dom_handle, 0x15, user_rid, user_info);
+ return wb_get_samr_query_userinfo(&domain->sam_dom_handle, 0x15,
+ user_rid, user_info);
}
+/* Lookup groups a user is a member of. I wish Unix had a call like this! */
+
+BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
+ uint32 user_rid, uint32 *num_groups,
+ DOM_GID **user_groups)
+{
+ POLICY_HND user_pol;
+ BOOL result;
+
+ if (!wb_samr_open_user(&domain->sam_dom_handle,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ user_rid, &user_pol)) {
+ return False;
+ }
+
+ if (cli_samr_query_usergroups(domain->sam_dom_handle.cli,
+ domain->sam_dom_handle.mem_ctx,
+ &user_pol, num_groups, user_groups)
+ != NT_STATUS_OK) {
+ result = False;
+ goto done;
+ }
+
+ result = True;
+
+done:
+ cli_samr_close(domain->sam_dom_handle.cli,
+ domain->sam_dom_handle.mem_ctx, &user_pol);
+
+ return True;
+}
+
/* Lookup group information from a rid */
BOOL winbindd_lookup_groupinfo(struct winbindd_domain *domain,
uint32 group_rid, GROUP_INFO_CTR *info)
{
- if (!domain_handles_open(domain)) return False;
-
- return get_samr_query_groupinfo(&domain->sam_dom_handle, 1, group_rid, info);
+ return wb_get_samr_query_groupinfo(&domain->sam_dom_handle, 1,
+ group_rid, info);
}
/* Lookup group membership given a rid */
@@ -468,40 +624,48 @@ BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
uint32 **rid_mem, char ***names,
enum SID_NAME_USE **name_types)
{
- if (!domain_handles_open(domain)) return False;
-
- return sam_query_groupmem(&domain->sam_dom_handle, group_rid, num_names,
- rid_mem, names, name_types);
+ return wb_sam_query_groupmem(&domain->sam_dom_handle, group_rid,
+ num_names, rid_mem, names, name_types);
}
-/* Lookup alias membership given a rid */
+/* Globals for domain list stuff */
+
+struct winbindd_domain *domain_list = NULL;
+
+/* Given a domain name, return the struct winbindd domain info for it
+ if it is actually working. */
-int winbindd_lookup_aliasmem(struct winbindd_domain *domain,
- uint32 alias_rid, uint32 *num_names,
- DOM_SID ***sids, char ***names,
- enum SID_NAME_USE **name_types)
+struct winbindd_domain *find_domain_from_name(char *domain_name)
{
- /* Open sam handles */
- if (!domain_handles_open(domain)) return False;
+ struct winbindd_domain *tmp;
- return sam_query_aliasmem(domain->controller,
- &domain->sam_dom_handle, alias_rid, num_names,
- sids, names, name_types);
-}
+ /* Search through list */
-/* Globals for domain list stuff */
+ for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ if (strcmp(domain_name, tmp->name) == 0) {
-struct winbindd_domain *domain_list = NULL;
+ if (!tmp->got_domain_info) {
+ get_domain_info(tmp);
+ }
+
+ return tmp->got_domain_info ? tmp : NULL;
+ }
+ }
+
+ /* Not found */
+
+ return NULL;
+}
/* Given a domain name, return the struct winbindd domain info for it */
-struct winbindd_domain *find_domain_from_name(char *domain_name)
+struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
{
struct winbindd_domain *tmp;
/* Search through list */
for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- if (strcmp(domain_name, tmp->name) == 0) {
+ if (sid_equal(sid, &tmp->sid)) {
if (!tmp->got_domain_info) return NULL;
return tmp;
}
@@ -544,14 +708,14 @@ static BOOL parse_id_list(char *paramstr, BOOL is_user)
/* Give a nicer error message if no parameters specified */
if (strequal(paramstr, "")) {
- DEBUG(0, ("winbid %s parameter missing\n", is_user ? "uid" : "gid"));
+ DEBUG(0, ("winbind %s parameter missing\n", is_user ? "uid" : "gid"));
return False;
}
/* Parse entry */
if (sscanf(paramstr, "%u-%u", &id_low, &id_high) != 2) {
- DEBUG(0, ("winbid %s parameter invalid\n",
+ DEBUG(0, ("winbind %s parameter invalid\n",
is_user ? "uid" : "gid"));
return False;
}
@@ -588,7 +752,7 @@ BOOL winbindd_param_init(void)
}
if (server_state.gid_low > server_state.gid_high) {
- DEBUG(0, ("gid range for invalid\n"));
+ DEBUG(0, ("gid range invalid\n"));
return False;
}
@@ -597,85 +761,83 @@ BOOL winbindd_param_init(void)
/* Convert a enum winbindd_cmd to a string */
-char *winbindd_cmd_to_string(enum winbindd_cmd cmd)
-{
- char *result;
+struct cmdstr_table {
+ enum winbindd_cmd cmd;
+ char *desc;
+};
- switch (cmd) {
+static struct cmdstr_table cmdstr_table[] = {
+
+ /* User functions */
- case WINBINDD_GETPWNAM_FROM_USER:
- result = "getpwnam from user";
- break;
-
- case WINBINDD_GETPWNAM_FROM_UID:
- result = "getpwnam from uid";
- break;
+ { WINBINDD_GETPWNAM_FROM_USER, "getpwnam from user" },
+ { WINBINDD_GETPWNAM_FROM_UID, "getpwnam from uid" },
+ { WINBINDD_SETPWENT, "setpwent" },
+ { WINBINDD_ENDPWENT, "endpwent" },
+ { WINBINDD_GETPWENT, "getpwent" },
+ { WINBINDD_GETGROUPS, "getgroups" },
- case WINBINDD_GETGRNAM_FROM_GROUP:
- result = "getgrnam from group";
- break;
+ /* Group functions */
- case WINBINDD_GETGRNAM_FROM_GID:
- result = "getgrnam from gid";
- break;
+ { WINBINDD_GETGRNAM_FROM_GROUP, "getgrnam from group" },
+ { WINBINDD_GETGRNAM_FROM_GID, "getgrnam from gid" },
+ { WINBINDD_SETGRENT, "setgrent" },
+ { WINBINDD_ENDGRENT, "endgrent" },
+ { WINBINDD_GETGRENT, "getgrent" },
- case WINBINDD_SETPWENT:
- result = "setpwent";
- break;
+ /* PAM auth functions */
- case WINBINDD_ENDPWENT:
- result = "endpwent";
- break;
+ { WINBINDD_PAM_AUTH, "pam auth" },
+ { WINBINDD_PAM_CHAUTHTOK, "pam chauthtok" },
- case WINBINDD_GETPWENT:
- result = "getpwent";
- break;
+ /* List things */
- case WINBINDD_SETGRENT:
- result = "setgrent";
- break;
+ { WINBINDD_LIST_USERS, "list users" },
+ { WINBINDD_LIST_GROUPS, "list groups" },
+ { WINBINDD_LIST_TRUSTDOM, "list trusted domains" },
- case WINBINDD_ENDGRENT:
- result = "endgrent";
- break;
+ /* SID related functions */
- case WINBINDD_GETGRENT:
- result = "getgrent";
- break;
+ { WINBINDD_LOOKUPSID, "lookup sid" },
+ { WINBINDD_LOOKUPNAME, "lookup name" },
- case WINBINDD_PAM_AUTH:
- result = "pam_auth";
- break;
+ /* S*RS related functions */
- default:
- result = "invalid command";
- break;
- }
+ { WINBINDD_SID_TO_UID, "sid to uid" },
+ { WINBINDD_SID_TO_GID, "sid to gid " },
+ { WINBINDD_GID_TO_SID, "gid to sid" },
+ { WINBINDD_UID_TO_SID, "uid to sid" },
- return result;
-};
+ /* Miscellaneous other stuff */
+ { WINBINDD_CHECK_MACHACC, "check machine acct pw" },
-/* parse a string of the form DOMAIN/user into a domain and a user */
-void parse_domain_user(char *domuser, fstring domain, fstring user)
+ /* End of list */
+
+ { WINBINDD_NUM_CMDS, NULL }
+};
+
+char *winbindd_cmd_to_string(enum winbindd_cmd cmd)
{
- char *p;
- char *sep = lp_winbind_separator();
- if (!sep) sep = "\\";
- p = strchr(domuser,*sep);
- if (!p) p = strchr(domuser,'\\');
- if (!p) {
- fstrcpy(domain,"");
- fstrcpy(user, domuser);
- return;
+ struct cmdstr_table *table = cmdstr_table;
+ char *result = NULL;
+
+ for(table = cmdstr_table; table->desc; table++) {
+ if (cmd == table->cmd) {
+ result = table->desc;
+ break;
+ }
}
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
-}
+ if (result == NULL) {
+ result = "invalid command";
+ }
+
+ return result;
+};
/* find the sequence number for a domain */
+
uint32 domain_sequence_number(char *domain_name)
{
struct winbindd_domain *domain;
@@ -684,7 +846,12 @@ uint32 domain_sequence_number(char *domain_name)
domain = find_domain_from_name(domain_name);
if (!domain) return DOM_SEQUENCE_NONE;
- if (!samr_query_dom_info(&domain->sam_dom_handle, 2, &ctr)) {
+ if (!wb_samr_query_dom_info(&domain->sam_dom_handle, 2, &ctr)) {
+
+ /* If this fails, something bad has gone wrong */
+
+ winbindd_kill_connections(domain);
+
DEBUG(2,("domain sequence query failed\n"));
return DOM_SEQUENCE_NONE;
}
@@ -694,3 +861,57 @@ uint32 domain_sequence_number(char *domain_name)
return ctr.info.inf2.seq_num;
}
+
+/* Query display info for a domain. This returns enough information plus a
+ bit extra to give an overview of domain users for the User Manager
+ application. */
+
+uint32 winbindd_query_dispinfo(struct winbindd_domain *domain,
+ uint32 *start_ndx, uint16 info_level,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr)
+{
+ uint32 status;
+
+ status = wb_samr_query_dispinfo(&domain->sam_dom_handle, start_ndx,
+ info_level, num_entries, ctr);
+
+ return status;
+}
+
+/* Check if a domain is present in a comma-separated list of domains */
+
+BOOL check_domain_env(char *domain_env, char *domain)
+{
+ fstring name;
+ char *tmp = domain_env;
+
+ while(next_token(&tmp, name, ",", sizeof(fstring))) {
+ if (strequal(name, domain)) {
+ return True;
+ }
+ }
+
+ return False;
+}
+
+
+/* Parse a string of the form DOMAIN/user into a domain and a user */
+
+void parse_domain_user(char *domuser, fstring domain, fstring user)
+{
+ char *p;
+ char *sep = lp_winbind_separator();
+ if (!sep) sep = "\\";
+ p = strchr(domuser,*sep);
+ if (!p) p = strchr(domuser,'\\');
+ if (!p) {
+ fstrcpy(domain,"");
+ fstrcpy(user, domuser);
+ return;
+ }
+
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ strupper(domain);
+}
diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c
index dea6418cb84..d6e316ddaaa 100644
--- a/source/nsswitch/wins.c
+++ b/source/nsswitch/wins.c
@@ -68,16 +68,19 @@ struct in_addr *lookup_backend(const char *name, int *count)
{
int fd;
static int initialised;
- struct in_addr *ret;
+ struct in_addr *ret = NULL;
struct in_addr p;
int j;
if (!initialised) {
initialised = 1;
DEBUGLEVEL = 0;
+
+ /* needed for lp_xx() functions */
+ charset_initialise();
+
TimeInit();
setup_logging("nss_wins",True);
- charset_initialise();
lp_load(CONFIGFILE,True,False,False);
load_interfaces();
}
@@ -129,8 +132,8 @@ struct in_addr *lookup_backend(const char *name, int *count)
gethostbyname() - we ignore any domain portion of the name and only
handle names that are at most 15 characters long
**************************************************************************/
-
-NSS_STATUS _nss_wins_gethostbyname_r(const char *name, struct hostent *he,
+enum nss_status
+_nss_wins_gethostbyname_r(const char *name, struct hostent *he,
char *buffer, size_t buflen, int *errnop,
int *h_errnop)
{
@@ -138,7 +141,7 @@ NSS_STATUS _nss_wins_gethostbyname_r(const char *name, struct hostent *he,
struct in_addr *ip_list;
int i, count;
size_t namelen = strlen(name) + 1;
-
+
memset(he, '\0', sizeof(*he));
ip_list = lookup_backend(name, &count);
diff --git a/source/pam_smbpass/pam_smb_acct.c b/source/pam_smbpass/pam_smb_acct.c
index af0c21cad57..8d91c456bf4 100644
--- a/source/pam_smbpass/pam_smb_acct.c
+++ b/source/pam_smbpass/pam_smb_acct.c
@@ -46,13 +46,14 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
const char *name;
const char *p;
- struct smb_passwd *smb_pwent = NULL;
+ SAM_ACCOUNT *sampass = NULL;
extern BOOL in_client;
/* Samba initialization. */
setup_logging( "pam_smbpass", False );
charset_initialise();
+ codepage_initialise(lp_client_code_page());
in_client = True;
ctrl = set_ctrl( flags, argc, argv );
@@ -70,18 +71,19 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
}
- if (!initialize_password_db()) {
+ if (!initialize_password_db(True)) {
_log_err( LOG_ALERT, "Cannot access samba password database" );
return PAM_AUTHINFO_UNAVAIL;
}
/* Get the user's record. */
- smb_pwent = getsmbpwnam( name );
+ pdb_init_sam(&sampass);
+ pdb_getsampwnam(sampass, name );
- if (!smb_pwent)
+ if (!sampass)
return PAM_USER_UNKNOWN;
- if (smb_pwent->acct_ctrl & ACB_DISABLED) {
+ if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
if (on( SMB_DEBUG, ctrl )) {
_log_err( LOG_DEBUG
, "acct: account %s is administratively disabled", name );
diff --git a/source/pam_smbpass/pam_smb_auth.c b/source/pam_smbpass/pam_smb_auth.c
index 0e95a842993..739b1653eeb 100644
--- a/source/pam_smbpass/pam_smb_auth.c
+++ b/source/pam_smbpass/pam_smb_auth.c
@@ -45,7 +45,7 @@ do { \
} while (0)
static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
- const char *name, struct smb_passwd *smb_pwent);
+ const char *name, SAM_ACCOUNT *sampass);
/*
* pam_sm_authenticate() authenticates users against the samba password file.
@@ -61,19 +61,18 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
{
unsigned int ctrl;
int retval, *ret_data = NULL;
-
+ SAM_ACCOUNT *sampass = NULL;
+ extern BOOL in_client;
const char *name;
/* Points to memory managed by the PAM library. Do not free. */
- const char *p = NULL;
-
- struct smb_passwd *smb_pwent = NULL;
+ char *p = NULL;
- extern BOOL in_client;
/* Samba initialization. */
setup_logging("pam_smbpass",False);
charset_initialise();
+ codepage_initialise(lp_client_code_page());
in_client = True;
ctrl = set_ctrl(flags, argc, argv);
@@ -94,48 +93,52 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "username [%s] obtained", name );
}
- if (!initialize_password_db()) {
+ if (!initialize_password_db(True)) {
_log_err( LOG_ALERT, "Cannot access samba password database" );
retval = PAM_AUTHINFO_UNAVAIL;
AUTH_RETURN;
}
- smb_pwent = getsmbpwnam( name );
+ pdb_init_sam(&sampass);
+
+ pdb_getsampwnam( sampass, name );
if (on( SMB_MIGRATE, ctrl )) {
- retval = _smb_add_user(pamh, ctrl, name, smb_pwent);
+ retval = _smb_add_user(pamh, ctrl, name, sampass);
+ pdb_free_sam(sampass);
AUTH_RETURN;
}
- if (smb_pwent == NULL) {
+ if (sampass == NULL) {
_log_err(LOG_ALERT, "Failed to find entry for user %s.", name);
retval = PAM_USER_UNKNOWN;
+ pdb_free_sam(sampass);
+ sampass = NULL;
AUTH_RETURN;
}
/* if this user does not have a password... */
- if (_smb_blankpasswd( ctrl, smb_pwent )) {
- smb_pwent = NULL;
+ if (_smb_blankpasswd( ctrl, sampass )) {
+ pdb_free_sam(sampass);
retval = PAM_SUCCESS;
AUTH_RETURN;
}
/* get this user's authentication token */
- retval = _smb_read_password(pamh, ctrl, NULL, "Password: ", NULL
- , _SMB_AUTHTOK, &p);
+ retval = _smb_read_password(pamh, ctrl, NULL, "Password: ", NULL, _SMB_AUTHTOK, &p);
if (retval != PAM_SUCCESS ) {
_log_err(LOG_CRIT, "auth: no password provided for [%s]"
, name);
- smb_pwent = NULL;
+ pdb_free_sam(sampass);
AUTH_RETURN;
}
/* verify the password of this user */
- retval = _smb_verify_password( pamh, smb_pwent, p, ctrl );
- smb_pwent = NULL;
+ retval = _smb_verify_password( pamh, sampass, p, ctrl );
+ pdb_free_sam(sampass);
p = NULL;
AUTH_RETURN;
}
@@ -165,11 +168,11 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags,
/* Helper function for adding a user to the db. */
static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
- const char *name, struct smb_passwd *smb_pwent)
+ const char *name, SAM_ACCOUNT *sampass)
{
pstring err_str;
pstring msg_str;
- const char *pass = NULL;
+ char *pass = NULL;
int retval;
err_str[0] = '\0';
@@ -187,7 +190,7 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
}
/* Add the user to the db if they aren't already there. */
- if (smb_pwent == NULL) {
+ if (sampass == NULL) {
retval = local_password_change( name, LOCAL_ADD_USER,
pass, err_str,
sizeof(err_str),
@@ -208,11 +211,9 @@ static int _smb_add_user(pam_handle_t *pamh, unsigned int ctrl,
}
/* Change the user's password IFF it's null. */
- if (smb_pwent->smb_passwd == NULL && (smb_pwent->acct_ctrl & ACB_PWNOTREQ))
+ if ((pdb_get_lanman_passwd(sampass) == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ))
{
- retval = local_password_change( name, 0,
- pass, err_str,
- sizeof(err_str),
+ retval = local_password_change( name, 0, pass, err_str, sizeof(err_str),
msg_str, sizeof(msg_str) );
if (!retval && *err_str)
{
diff --git a/source/pam_smbpass/pam_smb_passwd.c b/source/pam_smbpass/pam_smb_passwd.c
index e1bb8f37042..2281c1dfd1d 100644
--- a/source/pam_smbpass/pam_smb_passwd.c
+++ b/source/pam_smbpass/pam_smb_passwd.c
@@ -33,8 +33,7 @@
#include "support.h"
-int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user
- , const char *pass_new )
+int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, char *pass_new )
{
char c;
int retval, i;
@@ -93,13 +92,14 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
extern BOOL in_client;
- struct smb_passwd *smb_pwent=NULL;
+ SAM_ACCOUNT *sampass = NULL;
const char *user;
- const char *pass_old, *pass_new;
+ char *pass_old, *pass_new;
/* Samba initialization. */
setup_logging( "pam_smbpass", False );
charset_initialise();
+ codepage_initialise(lp_client_code_page());
in_client = True;
ctrl = set_ctrl(flags, argc, argv);
@@ -120,15 +120,16 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "username [%s] obtained", user );
}
- if (!initialize_password_db()) {
+ if (!initialize_password_db(True)) {
_log_err( LOG_ALERT, "Cannot access samba password database" );
return PAM_AUTHINFO_UNAVAIL;
}
/* obtain user record */
- smb_pwent = getsmbpwnam(user);
+ pdb_init_sam(&sampass);
+ pdb_getsampwnam(sampass,user);
- if (smb_pwent == NULL) {
+ if (sampass == NULL) {
_log_err( LOG_ALERT, "Failed to find entry for user %s.", user );
return PAM_USER_UNKNOWN;
}
@@ -141,10 +142,10 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
char *Announce;
- if (_smb_blankpasswd( ctrl, smb_pwent )) {
+ if (_smb_blankpasswd( ctrl, sampass )) {
+ pdb_free_sam(sampass);
return PAM_SUCCESS;
-
}
/* Password change by root, or for an expired token, doesn't
@@ -156,6 +157,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
Announce = (char *) malloc(sizeof(greeting)+strlen(user));
if (Announce == NULL) {
_log_err(LOG_CRIT, "password: out of memory");
+ pdb_free_sam(sampass);
return PAM_BUF_ERR;
}
strncpy( Announce, greeting, sizeof(greeting) );
@@ -163,23 +165,20 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
#undef greeting
set( SMB__OLD_PASSWD, ctrl );
- retval = _smb_read_password( pamh, ctrl
- , Announce
- , "Current SMB password: "
- , NULL
- , _SMB_OLD_AUTHTOK
- , &pass_old );
+ retval = _smb_read_password( pamh, ctrl, Announce, "Current SMB password: ",
+ NULL, _SMB_OLD_AUTHTOK, &pass_old );
free( Announce );
if (retval != PAM_SUCCESS) {
_log_err( LOG_NOTICE
, "password - (old) token not obtained" );
+ pdb_free_sam(sampass);
return retval;
}
/* verify that this is the password for this user */
- retval = _smb_verify_password( pamh, smb_pwent, pass_old, ctrl );
+ retval = _smb_verify_password( pamh, sampass, pass_old, ctrl );
} else {
pass_old = NULL;
@@ -187,6 +186,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
pass_old = NULL;
+ pdb_free_sam(sampass);
return retval;
} else if (flags & PAM_UPDATE_AUTHTOK) {
@@ -195,6 +195,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
/* NOTE: there is currently no support for password expiring
under Samba. Support will be added here when it becomes
available. */
+ pdb_free_sam(sampass);
return PAM_SUCCESS;
}
/*
@@ -221,6 +222,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (retval != PAM_SUCCESS) {
_log_err( LOG_NOTICE, "password: user not authenticated" );
+ pdb_free_sam(sampass);
return retval;
}
@@ -247,6 +249,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
, "password: new password not obtained" );
}
pass_old = NULL; /* tidy up */
+ pdb_free_sam(sampass);
return retval;
}
@@ -265,6 +268,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (retval != PAM_SUCCESS) {
_log_err(LOG_NOTICE, "new password not acceptable");
pass_new = pass_old = NULL; /* tidy up */
+ pdb_free_sam(sampass);
return retval;
}
@@ -279,7 +283,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
if (retval == PAM_SUCCESS) {
/* password updated */
_log_err( LOG_NOTICE, "password for (%s/%d) changed by (%s/%d)"
- , user, smb_pwent->smb_userid, uidtoname( getuid() )
+ , user, pdb_get_uid(sampass), uidtoname( getuid() )
, getuid() );
} else {
_log_err( LOG_ERR, "password change failed for user %s"
@@ -287,7 +291,10 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
pass_old = pass_new = NULL;
- smb_pwent = NULL;
+ if (sampass) {
+ pdb_free_sam(sampass);
+ sampass = NULL;
+ }
} else { /* something has broken with the library */
@@ -295,7 +302,13 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
retval = PAM_ABORT;
}
+
+ if (sampass) {
+ pdb_free_sam(sampass);
+ sampass = NULL;
+ }
+ pdb_free_sam(sampass);
return retval;
}
diff --git a/source/pam_smbpass/support.c b/source/pam_smbpass/support.c
index 01f4aa30c7d..5042c33b268 100644
--- a/source/pam_smbpass/support.c
+++ b/source/pam_smbpass/support.c
@@ -296,9 +296,8 @@ void _cleanup_failures( pam_handle_t * pamh, void *fl, int err )
}
}
-int _smb_verify_password( pam_handle_t * pamh
- , const struct smb_passwd *smb_pwent
- , const char *p, unsigned int ctrl )
+int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass,
+ const char *p, unsigned int ctrl )
{
uchar hash_pass[16];
uchar lm_pw[16];
@@ -307,10 +306,10 @@ int _smb_verify_password( pam_handle_t * pamh
char *data_name;
const char *name;
- if (!smb_pwent)
+ if (!sampass)
return PAM_ABORT;
- name = smb_pwent->smb_name;
+ name = pdb_get_username(sampass);
#ifdef HAVE_PAM_FAIL_DELAY
if (off( SMB_NODELAY, ctrl )) {
@@ -318,13 +317,13 @@ int _smb_verify_password( pam_handle_t * pamh
}
#endif
- if (!smb_pwent->smb_passwd)
+ if (!pdb_get_lanman_passwd(sampass))
{
_log_err( LOG_DEBUG, "user %s has null SMB password"
, name );
if (off( SMB__NONULL, ctrl )
- && (smb_pwent->acct_ctrl & ACB_PWNOTREQ))
+ && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ))
{ /* this means we've succeeded */
return PAM_SUCCESS;
} else {
@@ -335,13 +334,12 @@ int _smb_verify_password( pam_handle_t * pamh
, "failed auth request by %s for service %s as %s(%d)"
, uidtoname( getuid() )
, service ? service : "**unknown**", name
- , smb_pwent->smb_userid );
+ , pdb_get_uid(sampass) );
return PAM_AUTH_ERR;
}
}
- data_name = (char *) malloc( sizeof(FAIL_PREFIX)
- + strlen( name ));
+ data_name = (char *) malloc( sizeof(FAIL_PREFIX) + strlen( name ));
if (data_name == NULL) {
_log_err( LOG_CRIT, "no memory for data-name" );
}
@@ -353,9 +351,9 @@ int _smb_verify_password( pam_handle_t * pamh
if (strlen( p ) == 16 || (strlen( p ) == 32
&& pdb_gethexpwd( p, (char *) hash_pass ))) {
- if (!memcmp( hash_pass, smb_pwent->smb_passwd, 16 )
- || (smb_pwent->smb_nt_passwd
- && !memcmp( hash_pass, smb_pwent->smb_nt_passwd, 16 )))
+ if (!memcmp( hash_pass, pdb_get_lanman_passwd(sampass), 16 )
+ || (pdb_get_nt_passwd(sampass)
+ && !memcmp( hash_pass, pdb_get_nt_passwd(sampass), 16 )))
{
retval = PAM_SUCCESS;
if (data_name) { /* reset failures */
@@ -363,7 +361,6 @@ int _smb_verify_password( pam_handle_t * pamh
}
_pam_delete( data_name );
memset( hash_pass, '\0', 16 );
- smb_pwent = NULL;
return retval;
}
}
@@ -378,7 +375,7 @@ int _smb_verify_password( pam_handle_t * pamh
/* the moment of truth -- do we agree with the password? */
- if (!memcmp( nt_pw, smb_pwent->smb_nt_passwd, 16 )) {
+ if (!memcmp( nt_pw, pdb_get_nt_passwd(sampass), 16 )) {
retval = PAM_SUCCESS;
if (data_name) { /* reset failures */
@@ -414,11 +411,11 @@ int _smb_verify_password( pam_handle_t * pamh
, "failed auth request by %s for service %s as %s(%d)"
, uidtoname( getuid() )
, service ? service : "**unknown**", name
- , smb_pwent->smb_userid );
+ , pdb_get_uid(sampass) );
new->count = 1;
}
new->user = xstrdup( name );
- new->id = smb_pwent->smb_userid;
+ new->id = pdb_get_uid(sampass);
new->agent = xstrdup( uidtoname( getuid() ) );
pam_set_data( pamh, data_name, new, _cleanup_failures );
@@ -428,20 +425,20 @@ int _smb_verify_password( pam_handle_t * pamh
, "failed auth request by %s for service %s as %s(%d)"
, uidtoname( getuid() )
, service ? service : "**unknown**", name
- , smb_pwent->smb_userid );
+ , pdb_get_uid(sampass) );
}
} else {
_log_err( LOG_NOTICE
, "failed auth request by %s for service %s as %s(%d)"
, uidtoname( getuid() )
, service ? service : "**unknown**", name
- , smb_pwent->smb_userid );
+ , pdb_get_uid(sampass) );
retval = PAM_AUTH_ERR;
}
}
_pam_delete( data_name );
- smb_pwent = NULL;
+
return retval;
}
@@ -453,7 +450,7 @@ int _smb_verify_password( pam_handle_t * pamh
* - to avoid prompting for one in such cases (CG)
*/
-int _smb_blankpasswd( unsigned int ctrl, const struct smb_passwd *smb_pwent )
+int _smb_blankpasswd( unsigned int ctrl, SAM_ACCOUNT *sampass )
{
int retval;
@@ -466,7 +463,7 @@ int _smb_blankpasswd( unsigned int ctrl, const struct smb_passwd *smb_pwent )
if (on( SMB__NONULL, ctrl ))
return 0; /* will fail but don't let on yet */
- if (smb_pwent->smb_passwd == NULL)
+ if (pdb_get_lanman_passwd(sampass) == NULL)
retval = 1;
else
retval = 0;
@@ -478,14 +475,13 @@ int _smb_blankpasswd( unsigned int ctrl, const struct smb_passwd *smb_pwent )
* obtain a password from the user
*/
-int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl
- , const char *comment, const char *prompt1
- , const char *prompt2, const char *data_name
- , const char **pass )
+int _smb_read_password( pam_handle_t * pamh, unsigned int ctrl,
+ char *comment, char *prompt1,
+ char *prompt2, char *data_name, char **pass )
{
int authtok_flag;
int retval;
- const char *item = NULL;
+ char *item = NULL;
char *token;
struct pam_message msg[3], *pmsg[3];
diff --git a/source/pam_smbpass/support.h b/source/pam_smbpass/support.h
index 85bbd0a523c..779e2df15ef 100644
--- a/source/pam_smbpass/support.h
+++ b/source/pam_smbpass/support.h
@@ -26,9 +26,8 @@ extern BOOL strequal(const char *, const char *);
extern struct smb_passwd *
_my_get_smbpwnam(FILE *, const char *, BOOL *, BOOL *, long *);
-extern int _smb_verify_password( pam_handle_t *pamh
- , const struct smb_passwd *smb_pwent
- , const char *p, unsigned int ctrl );
+extern int _smb_verify_password( pam_handle_t *pamh , SAM_ACCOUNT *sampass,
+ const char *p, unsigned int ctrl );
/*
* this function obtains the name of the current user and ensures
@@ -40,13 +39,12 @@ extern int _smb_get_user(pam_handle_t *, unsigned int,
/* _smb_blankpasswd() is a quick check for a blank password */
-extern int _smb_blankpasswd(unsigned int, const struct smb_passwd *);
+extern int _smb_blankpasswd(unsigned int, SAM_ACCOUNT *);
/* obtain a password from the user */
-extern int _smb_read_password( pam_handle_t *, unsigned int, const char*,
- const char *, const char *, const char *,
- const char **);
+extern int _smb_read_password( pam_handle_t *, unsigned int, char*,
+ char *, char *, char *, char **);
extern int _pam_smb_approve_pass(pam_handle_t *, unsigned int, const char *,
const char *);
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index fb96c3214de..631782fd3f6 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -118,11 +118,11 @@ typedef struct
char *szPasswdChat;
char *szLogFile;
char *szConfigFile;
-/*#ifdef WITH_TDBPWD
+#ifdef WITH_TDB_SAM
char *szTDBPasswdFile;
-#else*/
+#else
char *szSMBPasswdFile;
-/* #endif */
+#endif
char *szPasswordServer;
char *szSocketOptions;
char *szValidChars;
@@ -152,11 +152,6 @@ typedef struct
char *szNetbiosAliases;
char *szDomainOtherSIDs;
char *szNameResolveOrder;
- char *szLdapServer;
- char *szLdapSuffix;
- char *szLdapFilter;
- char *szLdapRoot;
- char *szLdapRootPassword;
char *szPanicAction;
char *szAddUserScript;
char *szDelUserScript;
@@ -172,6 +167,8 @@ typedef struct
char *szTemplateHomedir;
char *szTemplateShell;
char *szWinbindSeparator;
+ BOOL bWinbindEnumUsers;
+ BOOL bWinbindEnumGroups;
char *szAddShareCommand;
char *szChangeShareCommand;
char *szDeleteShareCommand;
@@ -190,6 +187,7 @@ typedef struct
int maxdisksize;
int lpqcachetime;
int iMaxSmbdProcesses;
+ BOOL bDisableSpoolss;
int iTotalPrintJobs;
int syslog;
int os_level;
@@ -209,9 +207,15 @@ typedef struct
int min_passwd_length;
int oplock_break_wait_time;
int winbind_cache_time;
-#ifdef WITH_LDAP
+#ifdef WITH_LDAP_SAM
int ldap_port;
+ int ldap_ssl;
+ char *szLdapServer;
+ char *szLdapSuffix;
+ char *szLdapFilter;
+ char *szLdapAdminDn;
#endif /* WITH_LDAP */
+
#ifdef WITH_SSL
int sslVersion;
char *sslHostsRequire;
@@ -223,6 +227,9 @@ typedef struct
char *sslClientCert;
char *sslClientPrivKey;
char *sslCiphers;
+ char *sslEgdSocket;
+ char *sslEntropyFile;
+ int sslEntropyBytes;
BOOL sslEnabled;
BOOL sslReqClientCert;
BOOL sslReqServerCert;
@@ -270,6 +277,7 @@ typedef struct
BOOL bDebugUid;
BOOL bHostMSDfs;
BOOL bHideLocalUsers;
+ BOOL bUseMmap;
}
global;
@@ -366,7 +374,6 @@ typedef struct
BOOL bLocking;
BOOL bStrictLocking;
BOOL bPosixLocking;
- BOOL bShareModes;
BOOL bOpLocks;
BOOL bLevel2OpLocks;
BOOL bOnlyUser;
@@ -374,6 +381,7 @@ typedef struct
BOOL bWidelinks;
BOOL bSymlinks;
BOOL bSyncAlways;
+ BOOL bStrictAllocate;
BOOL bStrictSync;
char magic_char;
BOOL *copymap;
@@ -387,6 +395,7 @@ typedef struct
BOOL bBlockingLocks;
BOOL bInheritPerms;
BOOL bMSDfsRoot;
+ BOOL bUseClientDriver;
char dummy[3]; /* for alignment */
}
@@ -479,7 +488,6 @@ static service sDefault = {
True, /* bLocking */
False, /* bStrictLocking */
True, /* bPosixLocking */
- True, /* bShareModes */
True, /* bOpLocks */
True, /* bLevel2OpLocks */
False, /* bOnlyUser */
@@ -487,6 +495,7 @@ static service sDefault = {
True, /* bWidelinks */
True, /* bSymlinks */
False, /* bSyncAlways */
+ False, /* bStrictAllocate */
False, /* bStrictSync */
'~', /* magic char */
NULL, /* copymap */
@@ -500,6 +509,7 @@ static service sDefault = {
True, /* bBlockingLocks */
False, /* bInheritPerms */
False, /* bMSDfsRoot */
+ False, /* bUseClientDriver */
"" /* dummy */
};
@@ -571,6 +581,21 @@ static struct enum_list enum_printing[] = {
{-1, NULL}
};
+#ifdef WITH_LDAP_SAM
+static struct enum_list enum_ldap_ssl[] = {
+ {LDAP_SSL_ON, "Yes"},
+ {LDAP_SSL_ON, "yes"},
+ {LDAP_SSL_ON, "on"},
+ {LDAP_SSL_ON, "On"},
+ {LDAP_SSL_OFF, "no"},
+ {LDAP_SSL_OFF, "No"},
+ {LDAP_SSL_OFF, "off"},
+ {LDAP_SSL_OFF, "Off"},
+ {LDAP_SSL_START_TLS, "start tls"},
+ {-1, NULL}
+};
+#endif
+
/* Types of machine we can announce as. */
#define ANNOUNCE_AS_NT_SERVER 1
#define ANNOUNCE_AS_WIN95 2
@@ -673,11 +698,11 @@ static struct parm_struct parm_table[] = {
{"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
{"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, 0},
{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
-/* #ifdef WITH_TDBPWD
+#ifdef WITH_TDB_SAM
{"tdb passwd file", P_STRING, P_GLOBAL, &Globals.szTDBPasswdFile, NULL, NULL, 0},
-#else */
+#else
{"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
-/* #endif */
+#endif
{"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
{"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
{"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
@@ -746,9 +771,14 @@ static struct parm_struct parm_table[] = {
{"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0},
{"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0},
{"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0},
+ {"ssl cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0},
{"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0},
+ {"ssl key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0},
{"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0},
{"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0},
+ {"ssl egd socket", P_STRING, P_GLOBAL, &Globals.sslEgdSocket, NULL, NULL, 0},
+ {"ssl entropy file", P_STRING, P_GLOBAL, &Globals.sslEntropyFile, NULL, NULL, 0},
+ {"ssl entropy bytes", P_INTEGER, P_GLOBAL, &Globals.sslEntropyBytes, NULL, NULL, 0},
{"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL, 0},
{"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL, 0},
{"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0},
@@ -815,8 +845,10 @@ static struct parm_struct parm_table[] = {
{"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
{"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
+ {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE},
{"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
{"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
+ {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, 0},
{"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
{"Printing Options", P_SEP, P_SEPARATOR},
@@ -831,6 +863,7 @@ static struct parm_struct parm_table[] = {
{"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
{"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
{"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
+ {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
{"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
{"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
{"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
@@ -842,10 +875,11 @@ static struct parm_struct parm_table[] = {
{"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, 0},
{"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, 0},
{"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, 0},
- {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, 0},
+ {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, 0},
{"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT|FLAG_DOS_STRING},
{"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_DOS_STRING},
+ {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT},
{"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT},
{"printer driver file", P_STRING, P_LOCAL, &sDefault.szDriverFile, NULL, NULL, FLAG_PRINT},
{"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
@@ -931,18 +965,17 @@ static struct parm_struct parm_table[] = {
{"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
-#ifdef WITH_LDAP
+#ifdef WITH_LDAP_SAM
{"Ldap Options", P_SEP, P_SEPARATOR},
{"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
{"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
{"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
{"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
- {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0},
- {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword, NULL, NULL, 0},
-#endif /* WITH_LDAP */
+ {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, 0},
+ {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, 0},
+#endif /* WITH_LDAP_SAM */
{"Miscellaneous Options", P_SEP, P_SEPARATOR},
{"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, 0},
@@ -1020,6 +1053,8 @@ static struct parm_struct parm_table[] = {
{"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, 0},
{"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, 0},
{"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, 0},
+ {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, 0},
+ {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, 0},
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
@@ -1063,7 +1098,7 @@ static void init_printer_values(void)
break;
case PRINT_CUPS:
-#ifdef HAVE_LIBCUPS
+#ifdef HAVE_CUPS
string_set(&sDefault.szLpqcommand, "");
string_set(&sDefault.szLprmcommand, "");
string_set(&sDefault.szPrintcommand, "");
@@ -1072,7 +1107,7 @@ static void init_printer_values(void)
string_set(&sDefault.szQueuepausecommand, "");
string_set(&sDefault.szQueueresumecommand, "");
- string_set(&Globals.szPrintcapname, "cups");
+ string_set(&Globals.szPrintcapname, "cups");
#else
string_set(&sDefault.szLpqcommand,
"/usr/bin/lpstat -o %p");
@@ -1089,7 +1124,7 @@ static void init_printer_values(void)
string_set(&sDefault.szQueueresumecommand,
"/usr/bin/enable %p");
string_set(&Globals.szPrintcapname, "lpstat");
-#endif /* HAVE_LIBCUPS */
+#endif /* HAVE_CUPS */
break;
case PRINT_SYSV:
@@ -1173,11 +1208,8 @@ static void init_globals(void)
DEBUG(3, ("Initialising global parameters\n"));
-/* #ifdef WITH_TDBPWD
+#ifdef WITH_TDB_SAM
string_set(&Globals.szTDBPasswdFile, TDB_PASSWD_FILE);
-#else */
-#ifdef WITH_TDBPWD
- string_set(&Globals.szSMBPasswdFile, TDB_PASSWD_FILE);
#else
string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
#endif
@@ -1219,6 +1251,7 @@ static void init_globals(void)
Globals.max_xmit = 65535;
Globals.max_mux = 50; /* This is *needed* for profile support. */
Globals.lpqcachetime = 10;
+ Globals.bDisableSpoolss = False;
Globals.iMaxSmbdProcesses = 0;/* no limit specified */
Globals.iTotalPrintJobs = 0; /* no limit specified */
Globals.pwordlevel = 0;
@@ -1279,12 +1312,11 @@ static void init_globals(void)
Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
Globals.enhanced_browsing = True;
-
-#ifdef WITH_LDAP
- /* default values for ldap */
- string_set(&Globals.szLdapServer, "localhost");
- Globals.ldap_port = 389;
-#endif /* WITH_LDAP */
+#ifdef MMAP_BLACKLIST
+ Globals.bUseMmap = False;
+#else
+ Globals.bUseMmap = True;
+#endif
#ifdef WITH_SSL
Globals.sslVersion = SMB_SSL_V23;
@@ -1297,12 +1329,23 @@ static void init_globals(void)
string_set(&Globals.sslClientCert, "");
string_set(&Globals.sslClientPrivKey, "");
string_set(&Globals.sslCiphers, "");
+ string_set(&Globals.sslEgdSocket, "");
+ string_set(&Globals.sslEntropyFile, "");
+ Globals.sslEntropyBytes = 256;
Globals.sslEnabled = False;
Globals.sslReqClientCert = False;
Globals.sslReqServerCert = False;
Globals.sslCompatibility = False;
#endif /* WITH_SSL */
+#ifdef WITH_LDAP_SAM
+ string_set(&Globals.szLdapServer, "localhost");
+ string_set(&Globals.szLdapSuffix, "");
+ string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
+ string_set(&Globals.szLdapAdminDn, "");
+ Globals.ldap_port = 389;
+ Globals.ldap_ssl = LDAP_SSL_OFF;
+#endif /* WITH_LDAP_SAM */
/* these parameters are set to defaults that are more appropriate
for the increasing samba install base:
@@ -1337,6 +1380,9 @@ static void init_globals(void)
string_set(&Globals.szWinbindSeparator, "\\");
Globals.winbind_cache_time = 15;
+ Globals.bWinbindEnumUsers = True;
+ Globals.bWinbindEnumGroups = True;
+
/*
* This must be done last as it checks the value in
* client_code_page.
@@ -1413,11 +1459,11 @@ static char *lp_string(const char *s)
FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
-/* #ifdef WITH_TDBPWD
+#ifdef WITH_TDB_SAM
FN_GLOBAL_STRING(lp_tdb_passwd_file, &Globals.szTDBPasswdFile)
-#else */
+#else
FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
-/* #endif */
+#endif
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
@@ -1469,14 +1515,17 @@ FN_GLOBAL_STRING(lp_winbind_gid, &Globals.szWinbindGID)
FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
FN_GLOBAL_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
+FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
+FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
FN_GLOBAL_STRING(lp_codepagedir,&Globals.szCodePageDir)
-#ifdef WITH_LDAP
+#ifdef WITH_LDAP_SAM
FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
-FN_GLOBAL_STRING(lp_ldap_root, &Globals.szLdapRoot)
-FN_GLOBAL_STRING(lp_ldap_rootpasswd, &Globals.szLdapRootPassword)
-#endif /* WITH_LDAP */
+FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
+FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
+FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
+#endif /* WITH_LDAP_SAM */
FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
@@ -1492,6 +1541,9 @@ FN_GLOBAL_STRING(lp_ssl_privkey, &Globals.sslPrivKey)
FN_GLOBAL_STRING(lp_ssl_client_cert, &Globals.sslClientCert)
FN_GLOBAL_STRING(lp_ssl_client_privkey, &Globals.sslClientPrivKey)
FN_GLOBAL_STRING(lp_ssl_ciphers, &Globals.sslCiphers)
+FN_GLOBAL_STRING(lp_ssl_egdsocket, &Globals.sslEgdSocket)
+FN_GLOBAL_STRING(lp_ssl_entropyfile, &Globals.sslEntropyFile)
+FN_GLOBAL_INTEGER(lp_ssl_entropybytes, &Globals.sslEntropyBytes)
FN_GLOBAL_BOOL(lp_ssl_enabled, &Globals.sslEnabled)
FN_GLOBAL_BOOL(lp_ssl_reqClientCert, &Globals.sslReqClientCert)
FN_GLOBAL_BOOL(lp_ssl_reqServerCert, &Globals.sslReqServerCert)
@@ -1539,6 +1591,7 @@ FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
+FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
@@ -1557,6 +1610,7 @@ FN_GLOBAL_INTEGER(lp_security, &Globals.security)
FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
+FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
FN_GLOBAL_INTEGER(lp_totalprintjobs, &Globals.iTotalPrintJobs)
FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
FN_GLOBAL_INTEGER(lp_client_code_page, &Globals.client_code_page)
@@ -1569,9 +1623,6 @@ FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size)
FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
-#ifdef WITH_LDAP
-FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
-#endif /* WITH_LDAP */
FN_LOCAL_STRING(lp_preexec, szPreExec)
FN_LOCAL_STRING(lp_postexec, szPostExec)
FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
@@ -1635,7 +1686,6 @@ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
FN_LOCAL_BOOL(lp_locking, bLocking)
FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
-FN_LOCAL_BOOL(lp_share_modes, bShareModes)
FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
@@ -1643,6 +1693,7 @@ FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
+FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
FN_LOCAL_BOOL(lp_map_system, bMap_system)
FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
@@ -1654,6 +1705,7 @@ FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
+FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
@@ -1757,6 +1809,8 @@ static int add_a_service(service * pservice, char *name)
/* if not, then create one */
if (i == iNumServices)
{
+ service **tsp;
+
#ifdef __INSURE__
service **oldservices = iNumServices ? malloc(sizeof(service *) * iNumServices) : NULL;
@@ -1764,10 +1818,19 @@ static int add_a_service(service * pservice, char *name)
memcpy(oldservices, ServicePtrs, sizeof(service *) * iNumServices);
#endif
- ServicePtrs =
- (service **) Realloc(ServicePtrs,
- sizeof(service *) *
- num_to_alloc);
+ tsp = (service **) Realloc(ServicePtrs,
+ sizeof(service *) *
+ num_to_alloc);
+
+ if (!tsp) {
+ DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
+ return (-1);
+ } else {
+ ServicePtrs = tsp;
+ ServicePtrs[iNumServices] =
+ (service *) malloc(sizeof(service));
+ }
+
#ifdef __INSURE__
if (iNumServices && (memcmp(oldservices, ServicePtrs, sizeof(service *) * iNumServices) != 0)) {
smb_panic("add_a_service: Realloc corrupted ptrs...\n");
@@ -1775,11 +1838,7 @@ static int add_a_service(service * pservice, char *name)
safe_free(oldservices);
#endif
- if (ServicePtrs)
- ServicePtrs[iNumServices] =
- (service *) malloc(sizeof(service));
-
- if (!ServicePtrs || !ServicePtrs[iNumServices])
+ if (!ServicePtrs[iNumServices])
return (-1);
iNumServices++;
@@ -1804,7 +1863,15 @@ from service ifrom. homename must be in DOS codepage.
***************************************************************************/
BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
{
- int i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
+ int i;
+ SMB_STRUCT_STAT buf;
+
+ /* if the user's home directory doesn't exist, then don't
+ add it to the list of available shares */
+ if (sys_stat(pszHomedir, &buf))
+ return False;
+
+ i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
if (i < 0)
return (False);
@@ -1893,8 +1960,6 @@ BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
/* Printers cannot be read_only. */
ServicePtrs[i]->bRead_only = False;
- /* No share modes on printer services. */
- ServicePtrs[i]->bShareModes = False;
/* No oplocks on printer services. */
ServicePtrs[i]->bOpLocks = False;
/* Printer services must be printable. */
@@ -2092,47 +2157,43 @@ static struct file_lists
{
struct file_lists *next;
char *name;
+ char *subfname;
time_t modtime;
-}
- *file_lists = NULL;
+} *file_lists = NULL;
/*******************************************************************
keep a linked list of all config files so we know when one has changed
it's date and needs to be reloaded
********************************************************************/
-static void add_to_file_list(char *fname)
+static void add_to_file_list(char *fname, char *subfname)
{
struct file_lists *f = file_lists;
-
- while (f)
- {
+
+ while (f) {
if (f->name && !strcmp(f->name, fname))
break;
f = f->next;
}
-
- if (!f)
- {
+
+ if (!f) {
f = (struct file_lists *)malloc(sizeof(file_lists[0]));
if (!f)
return;
f->next = file_lists;
f->name = strdup(fname);
- if (!f->name)
- {
- free(f);
+ if (!f->name) {
+ SAFE_FREE(f);
+ return;
+ }
+ f->subfname = strdup(subfname);
+ if (!f->subfname) {
+ SAFE_FREE(f);
return;
}
file_lists = f;
}
-
- {
- pstring n2;
- pstrcpy(n2, fname);
- standard_sub_basic(n2);
- f->modtime = file_modtime(n2);
- }
-
+
+ f->modtime = file_modtime(subfname);
}
/*******************************************************************
@@ -2142,26 +2203,24 @@ BOOL lp_file_list_changed(void)
{
struct file_lists *f = file_lists;
DEBUG(6, ("lp_file_list_changed()\n"));
-
- while (f)
- {
+
+ while (f) {
pstring n2;
time_t mod_time;
-
+
pstrcpy(n2, f->name);
standard_sub_basic(n2);
-
+
DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
- f->name, n2, ctime(&f->modtime)));
-
+ f->name, n2, ctime(&f->modtime)));
+
mod_time = file_modtime(n2);
-
- if (f->modtime != mod_time)
- {
- DEBUGADD(6,
- ("file %s modified: %s\n", n2,
- ctime(&mod_time)));
+
+ if ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0)) {
+ DEBUGADD(6, ("file %s modified: %s\n", n2, ctime(&mod_time)));
f->modtime = mod_time;
+ SAFE_FREE(f->subfname);
+ f->subfname = strdup(n2);
return (True);
}
f = f->next;
@@ -2387,7 +2446,7 @@ static BOOL handle_include(char *pszParmValue, char **ptr)
pstring fname;
pstrcpy(fname, pszParmValue);
- add_to_file_list(fname);
+ add_to_file_list(pszParmValue, fname);
standard_sub_basic(fname);
@@ -3108,7 +3167,7 @@ void lp_add_one_printer(char *name, char *comment)
if ((i = lp_servicenumber(name)) >= 0)
{
string_set(&ServicePtrs[i]->comment, comment);
- unix_to_dos(ServicePtrs[i]->comment, True);
+ unix_to_dos(ServicePtrs[i]->comment, True);
ServicePtrs[i]->autoloaded = True;
}
}
@@ -3257,7 +3316,10 @@ BOOL lp_load(char *pszFname, BOOL global_only, BOOL save_defaults,
pstring n2;
BOOL bRetval;
- add_to_file_list(pszFname);
+ pstrcpy(n2, pszFname);
+ standard_sub_basic(n2);
+
+ add_to_file_list(pszFname, n2);
bRetval = False;
@@ -3372,8 +3434,8 @@ int lp_servicenumber(char *pszServiceName)
int iService;
for (iService = iNumServices - 1; iService >= 0; iService--)
- if (VALID(iService) &&
- strequal(lp_servicename(iService), pszServiceName))
+ if (VALID(iService) && ServicePtrs[iService]->szService &&
+ strequal(ServicePtrs[iService]->szService, pszServiceName))
break;
if (iService < 0)
@@ -3606,3 +3668,24 @@ char *lp_printername(int snum)
return ret;
}
+
+/***********************************************************
+ Return a pointer to the private directory (containing
+ smbpasswd etc.).
+************************************************************/
+
+void get_private_directory(pstring priv_dir)
+{
+ char *p;
+
+ *priv_dir = 0;
+
+#ifdef WITH_TDB_SAM
+ pstrcpy(priv_dir, lp_tdb_passwd_file());
+#else
+ pstrcpy(priv_dir, lp_smb_passwd_file());
+#endif
+
+ p = strrchr(priv_dir, '/');
+ if (p) *p = 0;
+}
diff --git a/source/param/params.c b/source/param/params.c
index b359b269d4e..2bc32f1c66d 100644
--- a/source/param/params.c
+++ b/source/param/params.c
@@ -252,13 +252,16 @@ static BOOL Section( myFILE *InFile, BOOL (*sfunc)(char *) )
/* Check that the buffer is big enough for the next character. */
if( i > (bSize - 2) )
{
- bSize += BUFR_INC;
- bufr = Realloc( bufr, bSize );
- if( NULL == bufr )
+ char *tb;
+
+ tb = Realloc( bufr, bSize +BUFR_INC );
+ if( NULL == tb )
{
DEBUG(0, ("%s Memory re-allocation failure.", func) );
return( False );
}
+ bufr = tb;
+ bSize += BUFR_INC;
}
/* Handle a single character. */
@@ -346,13 +349,16 @@ static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i > (bSize - 2) ) /* Ensure there's space for next char. */
{
- bSize += BUFR_INC;
- bufr = Realloc( bufr, bSize );
- if( NULL == bufr )
+ char *tb;
+
+ tb = Realloc( bufr, bSize + BUFR_INC );
+ if( NULL == tb )
{
DEBUG(0, ("%s Memory re-allocation failure.", func) );
return( False );
}
+ bufr = tb;
+ bSize += BUFR_INC;
}
switch( c )
diff --git a/source/passdb/pampass.c b/source/passdb/pampass.c
index fc8e4af47d8..dd9d38f66c3 100644
--- a/source/passdb/pampass.c
+++ b/source/passdb/pampass.c
@@ -88,7 +88,7 @@ static BOOL smb_pam_nt_status_error_handler(pam_handle_t *pamh, int pam_error,
if (smb_pam_error_handler(pamh, pam_error, msg, dbglvl))
return True;
- if (*nt_status == NT_STATUS_NOPROBLEMO) {
+ if (*nt_status == NT_STATUS_OK) {
/* Complain LOUDLY */
DEBUG(0, ("smb_pam_nt_status_error_handler: PAM: BUG: PAM and NT_STATUS \
error MISMATCH, forcing to NT_STATUS_LOGON_FAILURE"));
@@ -301,14 +301,13 @@ static int smb_pam_passchange_conv(int num_msg,
case PAM_PROMPT_ECHO_ON:
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: PAM said: %s\n", msg[replies]->msg));
fstrcpy(current_prompt, msg[replies]->msg);
- strlower(current_prompt);
trim_string(current_prompt, " ", " ");
for (t=pw_chat; t; t=t->next) {
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: trying to match |%s| to |%s|\n",
t->prompt, current_prompt ));
- if (ms_fnmatch(t->prompt, current_prompt) == 0) {
+ if (unix_wild_match(t->prompt, current_prompt) == 0) {
fstrcpy(current_reply, t->reply);
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We sent: %s\n", current_reply));
pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
@@ -334,14 +333,13 @@ static int smb_pam_passchange_conv(int num_msg,
case PAM_PROMPT_ECHO_OFF:
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: PAM said: %s\n", msg[replies]->msg));
fstrcpy(current_prompt, msg[replies]->msg);
- strlower(current_prompt);
trim_string(current_prompt, " ", " ");
for (t=pw_chat; t; t=t->next) {
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: trying to match |%s| to |%s|\n",
t->prompt, current_prompt ));
- if (ms_fnmatch(t->prompt, current_prompt) == 0) {
+ if (unix_wild_match(t->prompt, current_prompt) == 0) {
fstrcpy(current_reply, t->reply);
DEBUG(10,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We sent: %s\n", current_reply));
pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword);
@@ -535,7 +533,7 @@ static uint32 smb_pam_auth(pam_handle_t *pamh, char *user)
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_auth: PAM: User %s Authenticated OK\n", user));
- nt_status = NT_STATUS_NOPROBLEMO;
+ nt_status = NT_STATUS_OK;
break;
default:
DEBUG(0, ("smb_pam_auth: PAM: UNKNOWN ERROR while authenticating user %s\n", user));
@@ -580,7 +578,7 @@ static uint32 smb_pam_account(pam_handle_t *pamh, char * user)
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_account: PAM: Account OK for User: %s\n", user));
- nt_status = NT_STATUS_NOPROBLEMO;
+ nt_status = NT_STATUS_OK;
break;
default:
nt_status = NT_STATUS_ACCOUNT_DISABLED;
@@ -627,7 +625,7 @@ static uint32 smb_pam_setcred(pam_handle_t *pamh, char * user)
break;
case PAM_SUCCESS:
DEBUG(4, ("smb_pam_setcred: PAM: SetCredentials OK for User: %s\n", user));
- nt_status = NT_STATUS_NOPROBLEMO;
+ nt_status = NT_STATUS_OK;
break;
default:
DEBUG(0, ("smb_pam_setcred: PAM: UNKNOWN PAM ERROR (%d) during SetCredentials for User: %s\n", pam_error, user));
@@ -789,7 +787,7 @@ uint32 smb_pam_accountcheck(char * user)
/* Ignore PAM if told to. */
if (!lp_obey_pam_restrictions())
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
if ((pconv = smb_setup_pam_conv(smb_pam_conv, user, NULL, NULL)) == NULL)
return False;
@@ -797,7 +795,7 @@ uint32 smb_pam_accountcheck(char * user)
if (!smb_pam_start(&pamh, user, NULL, pconv))
return NT_STATUS_ACCOUNT_DISABLED;
- if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_NOPROBLEMO)
+ if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_OK)
DEBUG(0, ("smb_pam_accountcheck: PAM: Account Validation Failed - Rejecting User %s!\n", user));
smb_pam_end(pamh, pconv);
@@ -826,19 +824,19 @@ uint32 smb_pam_passcheck(char * user, char * password)
if (!smb_pam_start(&pamh, user, NULL, pconv))
return NT_STATUS_LOGON_FAILURE;
- if ((nt_status = smb_pam_auth(pamh, user)) != NT_STATUS_NOPROBLEMO) {
+ if ((nt_status = smb_pam_auth(pamh, user)) != NT_STATUS_OK) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_auth failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
}
- if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_NOPROBLEMO) {
+ if ((nt_status = smb_pam_account(pamh, user)) != NT_STATUS_OK) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_account failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
}
- if ((nt_status = smb_pam_setcred(pamh, user)) != NT_STATUS_NOPROBLEMO) {
+ if ((nt_status = smb_pam_setcred(pamh, user)) != NT_STATUS_OK) {
DEBUG(0, ("smb_pam_passcheck: PAM: smb_pam_setcred failed - Rejecting User %s !\n", user));
smb_pam_end(pamh, pconv);
return nt_status;
@@ -878,7 +876,7 @@ BOOL smb_pam_passchange(char * user, char * oldpassword, char * newpassword)
/* If PAM not used, no PAM restrictions on accounts. */
uint32 smb_pam_accountcheck(char * user)
{
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/* If PAM not used, also no PAM restrictions on sessions. */
diff --git a/source/passdb/pass_check.c b/source/passdb/pass_check.c
index 9424189b236..b3e762741fc 100644
--- a/source/passdb/pass_check.c
+++ b/source/passdb/pass_check.c
@@ -27,9 +27,9 @@
extern int DEBUGLEVEL;
/* these are kept here to keep the string_combinations function simple */
-static char this_user[100] = "";
-static char this_salt[100] = "";
-static char this_crypted[100] = "";
+static fstring this_user;
+static fstring this_salt;
+static fstring this_crypted;
#ifdef WITH_AFS
@@ -599,7 +599,7 @@ static BOOL password_check(char *password)
{
#ifdef WITH_PAM
- return (smb_pam_passcheck(this_user, password) == NT_STATUS_NOPROBLEMO);
+ return (smb_pam_passcheck(this_user, password) == NT_STATUS_OK);
#endif /* WITH_PAM */
#ifdef WITH_AFS
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index e1d7dca39a6..37da884a67f 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -2,8 +2,9 @@
Unix SMB/Netbios implementation.
Version 1.9.
Password and authentication handling
- Copyright (C) Jeremy Allison 1996-1998
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+ Copyright (C) Jeremy Allison 1996-2001
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+ Copyright (C) Gerald (Jerry) Carter 2000-2001
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
@@ -31,628 +32,216 @@ extern int DEBUGLEVEL;
*/
extern DOM_SID global_sam_sid;
-extern pstring global_myname;
-extern fstring global_myworkgroup;
-/*
- * NOTE. All these functions are abstracted into a structure
- * that points to the correct function for the selected database. JRA.
- *
- * NOTE. for the get/mod/add functions, there are two sets of functions.
- * one supports struct sam_passwd, the other supports struct smb_passwd.
- * for speed optimisation it is best to support both these sets.
- *
- * it is, however, optional to support one set but not the other: there
- * is conversion-capability built in to passdb.c, and run-time error
- * detection for when neither are supported.
- *
- * password database writers are recommended to implement the sam_passwd
- * functions in a first pass, as struct sam_passwd contains more
- * information, needed by the NT Domain support.
- *
- * a full example set of derivative functions are listed below. an API
- * writer is expected to cut/paste these into their module, replace
- * either one set (struct smb_passwd) or the other (struct sam_passwd)
- * OR both, and optionally also to write display info routines
- * (struct sam_disp_info). lkcl
- *
- */
+struct passdb_ops *pdb_ops;
-static struct passdb_ops *pdb_ops;
+#if 0 /* JERRY */
+static void* pdb_handle = NULL;
+#endif
/***************************************************************
Initialize the password db operations.
***************************************************************/
-BOOL initialize_password_db(void)
-{
- if (pdb_ops)
- {
- return True;
- }
-
-#ifdef WITH_NISPLUS
- pdb_ops = nisplus_initialize_password_db();
-#elif defined(WITH_LDAP)
- pdb_ops = ldap_initialize_password_db();
-#elif defined(WITH_TDBPWD)
- pdb_ops = tdb_initialize_password_db();
-#else
- pdb_ops = file_initialize_password_db();
-#endif
-
- return (pdb_ops != NULL);
+BOOL initialize_password_db(BOOL reload)
+{
+ /*
+ * This function is unfinished right now, so just
+ * ignore the details and always return True. It
+ * is here only as a placeholder --jerry
+ */
+ return True;
+
}
+/*************************************************************
+ Initialises a struct sam_disp_info.
+ **************************************************************/
-/***************************************************************
- Start to enumerate the smb or sam passwd list. Returns a void pointer
- to ensure no modification outside this module.
-
- Note that currently it is being assumed that a pointer returned
- from this function may be used to enumerate struct sam_passwd
- entries as well as struct smb_passwd entries. This may need
- to change. JRA.
-
-****************************************************************/
-
-void *startsmbpwent(BOOL update)
+static void pdb_init_dispinfo(struct sam_disp_info *user)
{
- return pdb_ops->startsmbpwent(update);
+ if (user == NULL)
+ return;
+ ZERO_STRUCTP(user);
}
-/***************************************************************
- End enumeration of the smb or sam passwd list.
-
- Note that currently it is being assumed that a pointer returned
- from this function may be used to enumerate struct sam_passwd
- entries as well as struct smb_passwd entries. This may need
- to change. JRA.
-****************************************************************/
+/************************************************************
+ Fill the SAM_ACCOUNT with default values.
+ ***********************************************************/
-void endsmbpwent(void *vp)
+static BOOL pdb_fill_default_sam(SAM_ACCOUNT *user)
{
- pdb_ops->endsmbpwent(vp);
-}
-
-/*************************************************************************
- Routine to return the next entry in the smb passwd list.
- *************************************************************************/
-
-struct smb_passwd *getsmbpwent(void *vp)
-{
- return pdb_ops->getsmbpwent(vp);
-}
+ if (user == NULL) {
+ DEBUG(0,("pdb_fill_default_sam: SAM_ACCOUNT was NULL\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(user);
+ user->logon_time = (time_t)0;
+ user->pass_last_set_time = (time_t)0;
+ user->pass_can_change_time = (time_t)0;
+ user->logoff_time =
+ user->kickoff_time =
+ user->pass_must_change_time = get_time_t_max(); /* Password never expires. */
+
+ user->unknown_3 = 0x00ffffff; /* don't know */
+ user->logon_divs = 168; /* hours per week */
+ user->hours_len = 21; /* 21 times 8 bits = 168 */
+ memset(user->hours, 0xff, user->hours_len); /* available at all hours */
+ user->unknown_5 = 0x00000000; /* don't know */
+ user->unknown_6 = 0x000004ec; /* don't know */
+ return True;
+}
-/************************************************************************
- Routine to add an entry to the smb passwd file.
-*************************************************************************/
-BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
-{
- return pdb_ops->add_smbpwd_entry(newpwd);
-}
-
-/************************************************************************
- Routine to search the smb passwd file for an entry matching the username.
- and then modify its password entry. We can't use the startsampwent()/
- getsampwent()/endsampwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out password or NO PASS
-************************************************************************/
+/*************************************************************
+ Alloc memory and initialises a struct sam_passwd.
+ ************************************************************/
-BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override)
+BOOL pdb_init_sam(SAM_ACCOUNT **user)
{
- return pdb_ops->mod_smbpwd_entry(pwd, override);
-}
+ if (*user != NULL) {
+ DEBUG(0,("pdb_init_sam: SAM_ACCOUNT was non NULL\n"));
+#if 0
+ smb_panic("NULL pointer passed to pdb_init_sam\n");
+#endif
+ return False;
+ }
+
+ *user=(SAM_ACCOUNT *)malloc(sizeof(SAM_ACCOUNT));
+
+ if (*user==NULL) {
+ DEBUG(0,("pdb_init_sam: error while allocating memory\n"));
+ return False;
+ }
-/************************************************************************
- Routine to delete an entry from the smb passwd file.
-*************************************************************************/
+ pdb_fill_default_sam(*user);
-BOOL del_smbpwd_entry(const char *name)
-{
- return pdb_ops->del_smbpwd_entry(name);
+ return True;
}
-/************************************************************************
- Routine to search smb passwd by name.
-*************************************************************************/
-
-struct smb_passwd *getsmbpwnam(char *name)
-{
- return pdb_ops->getsmbpwnam(name);
-}
-/************************************************************************
- Routine to search smb passwd by user rid.
-*************************************************************************/
+/*************************************************************
+ Initialises a struct sam_passwd with sane values.
+ ************************************************************/
-struct smb_passwd *getsmbpwrid(uint32 user_rid)
+BOOL pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, struct passwd *pwd)
{
- return pdb_ops->getsmbpwrid(user_rid);
-}
+ if (!pwd) {
+ new_sam_acct = NULL;
+ return False;
+ }
-/************************************************************************
- Routine to search smb passwd by uid.
-*************************************************************************/
+ if (!pdb_init_sam(new_sam_acct)) {
+ new_sam_acct = NULL;
+ return False;
+ }
-struct smb_passwd *getsmbpwuid(uid_t smb_userid)
-{
- return pdb_ops->getsmbpwuid(smb_userid);
+ pdb_set_username(*new_sam_acct, pwd->pw_name);
+ pdb_set_fullname(*new_sam_acct, pwd->pw_gecos);
+ pdb_set_uid(*new_sam_acct, pwd->pw_uid);
+ pdb_set_gid(*new_sam_acct, pwd->pw_gid);
+ pdb_set_profile_path(*new_sam_acct, lp_logon_path());
+ pdb_set_homedir(*new_sam_acct, lp_logon_home());
+ pdb_set_dir_drive(*new_sam_acct, lp_logon_drive());
+ pdb_set_logon_script(*new_sam_acct, lp_logon_script());
+ return True;
}
-/*
- * Functions that manupulate a struct sam_passwd.
- */
-/************************************************************************
- Utility function to search sam passwd by name. use this if your database
- does not have search facilities.
-*************************************************************************/
+/************************************************************
+ Free the NT/LM hashes only.
+ ***********************************************************/
-struct sam_passwd *iterate_getsam21pwnam(char *name)
+static BOOL pdb_free_sam_contents(SAM_ACCOUNT *user)
{
- struct sam_passwd *pwd = NULL;
- void *fp = NULL;
-
- DEBUG(10, ("search by name: %s\n", name));
-
- /* Open the smb password database - not for update. */
- fp = startsmbpwent(False);
-
- if (fp == NULL)
- {
- DEBUG(0, ("unable to open sam password database.\n"));
- return NULL;
- }
-
- while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->smb_name, name))
- {
- DEBUG(10, ("iterate: %s 0x%x\n", pwd->smb_name, pwd->user_rid));
+ if (user == NULL) {
+ DEBUG(0,("pdb_free_sam_contents: SAM_ACCOUNT was NULL\n"));
+#if 0
+ smb_panic("NULL pointer passed to pdb_free_sam\n");
+#endif
+ return False;
}
- if (pwd != NULL)
- {
- DEBUG(10, ("found by name: %s\n", name));
- }
+ /* As we start mallocing more strings this is where
+ we should free them. */
- endsmbpwent(fp);
- return pwd;
+ SAFE_FREE(user->nt_pw);
+ SAFE_FREE(user->lm_pw);
+
+ return True;
}
-/************************************************************************
- Utility function to search sam passwd by rid. use this if your database
- does not have search facilities.
- search capability by both rid and uid are needed as the rid <-> uid
- mapping may be non-monotonic.
+/************************************************************
+ Reset the SAM_ACCOUNT and free the NT/LM hashes.
+ - note: they are not zero'ed out however.
+ ***********************************************************/
-*************************************************************************/
-
-struct sam_passwd *iterate_getsam21pwrid(uint32 rid)
+BOOL pdb_reset_sam(SAM_ACCOUNT *user)
{
- struct sam_passwd *pwd = NULL;
- void *fp = NULL;
-
- DEBUG(10, ("search by rid: %x\n", rid));
-
- /* Open the smb password file - not for update. */
- fp = startsmbpwent(False);
-
- if (fp == NULL)
- {
- DEBUG(0, ("unable to open sam password database.\n"));
- return NULL;
+ if (user == NULL) {
+ DEBUG(0,("pdb_reset_sam: SAM_ACCOUNT was NULL\n"));
+ return False;
}
-
- while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid)
- {
- DEBUG(10, ("iterate: %s 0x%x\n", pwd->smb_name, pwd->user_rid));
+
+ if (!pdb_free_sam_contents(user)) {
+ return False;
}
- if (pwd != NULL)
- {
- DEBUG(10, ("found by user_rid: %x\n", rid));
+ if (!pdb_fill_default_sam(user)) {
+ return False;
}
- endsmbpwent(fp);
- return pwd;
+ return True;
}
-/************************************************************************
- Utility function to search sam passwd by uid. use this if your database
- does not have search facilities.
-
- search capability by both rid and uid are needed as the rid <-> uid
- mapping may be non-monotonic.
-*************************************************************************/
+/************************************************************
+ Free the SAM_ACCOUNT and the NT/LM hashes.
+ ***********************************************************/
-struct sam_passwd *iterate_getsam21pwuid(uid_t uid)
+BOOL pdb_free_sam(SAM_ACCOUNT *user)
{
- struct sam_passwd *pwd = NULL;
- void *fp = NULL;
-
- DEBUG(10, ("search by uid: %x\n", (int)uid));
-
- /* Open the smb password file - not for update. */
- fp = startsmbpwent(False);
-
- if (fp == NULL)
- {
- DEBUG(0, ("unable to open sam password database.\n"));
- return NULL;
+ if (user == NULL) {
+ DEBUG(0,("pdb_free_sam: SAM_ACCOUNT was NULL\n"));
+#if 0
+ smb_panic("NULL pointer passed to pdb_free_sam\n");
+#endif
+ return False;
}
- while ((pwd = getsam21pwent(fp)) != NULL && pwd->smb_userid != uid)
- ;
-
- if (pwd != NULL)
- {
- DEBUG(10, ("found by smb_userid: %x\n", (int)uid));
+ if (!pdb_free_sam_contents(user)) {
+ return False;
}
- endsmbpwent(fp);
- return pwd;
-}
-
-/*************************************************************************
- Routine to return a display info structure, by rid
- *************************************************************************/
-struct sam_disp_info *getsamdisprid(uint32 rid)
-{
- return pdb_ops->getsamdisprid(rid);
-}
-
-/*************************************************************************
- Routine to return the next entry in the sam passwd list.
- *************************************************************************/
-
-struct sam_passwd *getsam21pwent(void *vp)
-{
- return pdb_ops->getsam21pwent(vp);
-}
-
-
-/************************************************************************
- Routine to search sam passwd by name.
-*************************************************************************/
-
-struct sam_passwd *getsam21pwnam(char *name)
-{
- return pdb_ops->getsam21pwnam(name);
-}
-
-/************************************************************************
- Routine to search sam passwd by rid.
-*************************************************************************/
-
-struct sam_passwd *getsam21pwrid(uint32 rid)
-{
- return pdb_ops->getsam21pwrid(rid);
-}
-
-/************************************************************************
- Routine to add a SAM entry to the smb passwd file.
-*************************************************************************/
-
-BOOL add_sam21pwd_entry(struct sam_passwd *pwd)
-{
- return pdb_ops->add_sam21pwd_entry(pwd);
-}
-
-/************************************************************************
- Routine to modify a SAM entry to the smb passwd file.
-*************************************************************************/
-
-BOOL mod_sam21pwd_entry(struct sam_passwd *pwd, BOOL override)
-{
- return pdb_ops->mod_sam21pwd_entry(pwd, override);
-}
-
-/**********************************************************
- **********************************************************
-
- utility routines which are likely to be useful to all password
- databases
-
- **********************************************************
- **********************************************************/
-
-/*************************************************************
- initialises a struct sam_disp_info.
- **************************************************************/
-
-static void pdb_init_dispinfo(struct sam_disp_info *user)
-{
- if (user == NULL) return;
- memset((char *)user, '\0', sizeof(*user));
+ SAFE_FREE(user);
+
+ return True;
}
-/*************************************************************
- initialises a struct smb_passwd.
- **************************************************************/
-
-void pdb_init_smb(struct smb_passwd *user)
-{
- if (user == NULL) return;
- memset((char *)user, '\0', sizeof(*user));
- user->pass_last_set_time = (time_t)-1;
-}
-
-/*************************************************************
- initialises a struct sam_passwd.
- **************************************************************/
-void pdb_init_sam(struct sam_passwd *user)
-{
- if (user == NULL) return;
- memset((char *)user, '\0', sizeof(*user));
- user->logon_time = (time_t)-1;
- user->logoff_time = (time_t)-1;
- user->kickoff_time = (time_t)-1;
- user->pass_last_set_time = (time_t)-1;
- user->pass_can_change_time = (time_t)-1;
- user->pass_must_change_time = (time_t)-1;
-}
/*************************************************************************
Routine to return the next entry in the sam passwd list.
*************************************************************************/
-struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user)
+struct sam_disp_info *pdb_sam_to_dispinfo(SAM_ACCOUNT *user)
{
static struct sam_disp_info disp_info;
- if (user == NULL) return NULL;
+ if (user == NULL)
+ return NULL;
pdb_init_dispinfo(&disp_info);
- disp_info.smb_name = user->smb_name;
+ disp_info.smb_name = user->username;
disp_info.full_name = user->full_name;
disp_info.user_rid = user->user_rid;
return &disp_info;
}
-/*************************************************************
- converts a sam_passwd structure to a smb_passwd structure.
- **************************************************************/
-
-struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user)
-{
- static struct smb_passwd pw_buf;
-
- if (user == NULL) return NULL;
-
- pdb_init_smb(&pw_buf);
-
- pw_buf.smb_userid = user->smb_userid;
- pw_buf.smb_name = user->smb_name;
- pw_buf.smb_passwd = user->smb_passwd;
- pw_buf.smb_nt_passwd = user->smb_nt_passwd;
- pw_buf.acct_ctrl = user->acct_ctrl;
- pw_buf.pass_last_set_time = user->pass_last_set_time;
-
- return &pw_buf;
-}
-
-
-/*************************************************************
- converts a smb_passwd structure to a sam_passwd structure.
- **************************************************************/
-
-struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user)
-{
- static struct sam_passwd pw_buf;
-
- if (user == NULL) return NULL;
-
- pdb_init_sam(&pw_buf);
-
- pw_buf.smb_userid = user->smb_userid;
- pw_buf.smb_name = user->smb_name;
- pw_buf.smb_passwd = user->smb_passwd;
- pw_buf.smb_nt_passwd = user->smb_nt_passwd;
- pw_buf.acct_ctrl = user->acct_ctrl;
- pw_buf.pass_last_set_time = user->pass_last_set_time;
-
- return &pw_buf;
-}
-
-static void select_name(fstring *string, char **name, const UNISTR2 *from)
-{
- if (from->buffer != 0)
- {
- unistr2_to_ascii(*string, from, sizeof(*string));
- *name = *string;
- }
-}
-
-/*************************************************************
- copies a sam passwd.
- **************************************************************/
-void copy_id23_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_23 *from)
-{
- static fstring smb_name;
- static fstring full_name;
- static fstring home_dir;
- static fstring dir_drive;
- static fstring logon_script;
- static fstring profile_path;
- static fstring acct_desc;
- static fstring workstations;
- static fstring unknown_str;
- static fstring munged_dial;
-
- if (from == NULL || to == NULL) return;
-
- to->logon_time = nt_time_to_unix(&from->logon_time);
- to->logoff_time = nt_time_to_unix(&from->logoff_time);
- to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
- to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
- to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
- to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
-
- select_name(&smb_name , &to->smb_name , &from->uni_user_name );
- select_name(&full_name , &to->full_name , &from->uni_full_name );
- select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
- select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
- select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
- select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
- select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
- select_name(&workstations, &to->workstations, &from->uni_workstations);
- select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
- select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
-
- to->smb_userid = (uid_t)-1;
- to->smb_grpid = (gid_t)-1;
- to->user_rid = from->user_rid;
- to->group_rid = from->group_rid;
-
- to->smb_passwd = NULL;
- to->smb_nt_passwd = NULL;
-
- to->acct_ctrl = from->acb_info;
- to->unknown_3 = from->unknown_3;
-
- to->logon_divs = from->logon_divs;
- to->hours_len = from->logon_hrs.len;
- memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
-
- to->unknown_5 = from->unknown_5;
- to->unknown_6 = from->unknown_6;
-}
-
-/*************************************************************
- copies a sam passwd.
- **************************************************************/
-void copy_id21_to_sam_passwd(struct sam_passwd *to, SAM_USER_INFO_21 *from)
-{
- static fstring smb_name;
- static fstring full_name;
- static fstring home_dir;
- static fstring dir_drive;
- static fstring logon_script;
- static fstring profile_path;
- static fstring acct_desc;
- static fstring workstations;
- static fstring unknown_str;
- static fstring munged_dial;
-
- if (from == NULL || to == NULL) return;
-
- to->logon_time = nt_time_to_unix(&from->logon_time);
- to->logoff_time = nt_time_to_unix(&from->logoff_time);
- to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
- to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
- to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
- to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
-
- select_name(&smb_name , &to->smb_name , &from->uni_user_name );
- select_name(&full_name , &to->full_name , &from->uni_full_name );
- select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
- select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
- select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
- select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
- select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
- select_name(&workstations, &to->workstations, &from->uni_workstations);
- select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
- select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
-
- to->smb_userid = (uid_t)-1;
- to->smb_grpid = (gid_t)-1;
- to->user_rid = from->user_rid;
- to->group_rid = from->group_rid;
-
- to->smb_passwd = NULL;
- to->smb_nt_passwd = NULL;
-
- to->acct_ctrl = from->acb_info;
- to->unknown_3 = from->unknown_3;
-
- to->logon_divs = from->logon_divs;
- to->hours_len = from->logon_hrs.len;
- memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
-
- to->unknown_5 = from->unknown_5;
- to->unknown_6 = from->unknown_6;
-}
-
-
-/*************************************************************
- copies a sam passwd.
- **************************************************************/
-void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from)
-{
- static fstring smb_name="";
- static fstring full_name="";
- static fstring home_dir="";
- static fstring dir_drive="";
- static fstring logon_script="";
- static fstring profile_path="";
- static fstring acct_desc="";
- static fstring workstations="";
- static fstring unknown_str="";
- static fstring munged_dial="";
-
- if (from == NULL || to == NULL) return;
-
- memcpy(to, from, sizeof(*from));
-
- if (from->smb_name != NULL) {
- fstrcpy(smb_name , from->smb_name);
- to->smb_name = smb_name;
- }
-
- if (from->full_name != NULL) {
- fstrcpy(full_name, from->full_name);
- to->full_name = full_name;
- }
-
- if (from->home_dir != NULL) {
- fstrcpy(home_dir , from->home_dir);
- to->home_dir = home_dir;
- }
-
- if (from->dir_drive != NULL) {
- fstrcpy(dir_drive , from->dir_drive);
- to->dir_drive = dir_drive;
- }
-
- if (from->logon_script != NULL) {
- fstrcpy(logon_script , from->logon_script);
- to->logon_script = logon_script;
- }
-
- if (from->profile_path != NULL) {
- fstrcpy(profile_path , from->profile_path);
- to->profile_path = profile_path;
- }
-
- if (from->acct_desc != NULL) {
- fstrcpy(acct_desc , from->acct_desc);
- to->acct_desc = acct_desc;
- }
-
- if (from->workstations != NULL) {
- fstrcpy(workstations , from->workstations);
- to->workstations = workstations;
- }
-
- if (from->unknown_str != NULL) {
- fstrcpy(unknown_str , from->unknown_str);
- to->unknown_str = unknown_str;
- }
-
- if (from->munged_dial != NULL) {
- fstrcpy(munged_dial , from->munged_dial);
- to->munged_dial = munged_dial;
- }
-}
-
/**********************************************************
Encode the account control bits into a string.
length = length of string to encode into (including terminating
@@ -661,38 +250,35 @@ void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from)
char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
{
- static fstring acct_str;
- size_t i = 0;
-
- acct_str[i++] = '[';
-
- if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
- if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
- if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
- if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
- if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
- if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
- if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
- if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
- if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
- if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
- if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
-
- for ( ; i < length - 2 ; i++ ) { acct_str[i] = ' '; }
-
- i = length - 2;
- acct_str[i++] = ']';
- acct_str[i++] = '\0';
-
- return acct_str;
+ static fstring acct_str;
+ size_t i = 0;
+
+ acct_str[i++] = '[';
+
+ if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
+ if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
+ if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
+ if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
+ if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
+ if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
+ if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
+ if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
+ if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
+ if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
+ if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
+
+ for ( ; i < length - 2 ; i++ )
+ acct_str[i] = ' ';
+
+ i = length - 2;
+ acct_str[i++] = ']';
+ acct_str[i++] = '\0';
+
+ return acct_str;
}
/**********************************************************
Decode the account control bits from a string.
-
- this function breaks coding standards minimum line width of 80 chars.
- reason: vertical line-up code clarity - all case statements fit into
- 15 lines, which is more important.
**********************************************************/
uint16 pdb_decode_acct_ctrl(const char *p)
@@ -705,12 +291,11 @@ uint16 pdb_decode_acct_ctrl(const char *p)
* NT password (in the form [NDHTUWSLXI]).
*/
- if (*p != '[') return 0;
+ if (*p != '[')
+ return 0;
- for (p++; *p && !finished; p++)
- {
- switch (*p)
- {
+ for (p++; *p && !finished; p++) {
+ switch (*p) {
case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
@@ -734,105 +319,10 @@ uint16 pdb_decode_acct_ctrl(const char *p)
return acct_ctrl;
}
-/*******************************************************************
- gets password-database-format time from a string.
- ********************************************************************/
-
-static time_t get_time_from_string(const char *p)
-{
- int i;
-
- for (i = 0; i < 8; i++)
- {
- if (p[i] == '\0' || !isxdigit((int)(p[i]&0xFF)))
- break;
- }
- if (i == 8)
- {
- /*
- * p points at 8 characters of hex digits -
- * read into a time_t as the seconds since
- * 1970 that the password was last changed.
- */
- return (time_t)strtol(p, NULL, 16);
- }
- return (time_t)-1;
-}
-
-/*******************************************************************
- gets password last set time
- ********************************************************************/
-
-time_t pdb_get_last_set_time(const char *p)
-{
- if (*p && StrnCaseCmp(p, "LCT-", 4))
- {
- return get_time_from_string(p + 4);
- }
- return (time_t)-1;
-}
-
-
-/*******************************************************************
- sets password-database-format time in a string.
- ********************************************************************/
-static void set_time_in_string(char *p, int max_len, char *type, time_t t)
-{
- slprintf(p, max_len, ":%s-%08X:", type, (uint32)t);
-}
-
-/*******************************************************************
- sets logon time
- ********************************************************************/
-void pdb_set_logon_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "LNT", t);
-}
-
-/*******************************************************************
- sets logoff time
- ********************************************************************/
-void pdb_set_logoff_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "LOT", t);
-}
-
-/*******************************************************************
- sets kickoff time
- ********************************************************************/
-void pdb_set_kickoff_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "KOT", t);
-}
-
-/*******************************************************************
- sets password can change time
- ********************************************************************/
-void pdb_set_can_change_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "CCT", t);
-}
-
-/*******************************************************************
- sets password last set time
- ********************************************************************/
-void pdb_set_must_change_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "MCT", t);
-}
-
-/*******************************************************************
- sets password last set time
- ********************************************************************/
-void pdb_set_last_set_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "LCT", t);
-}
-
-
/*************************************************************
Routine to set 32 hex password characters from a 16 byte array.
**************************************************************/
+
void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
{
if (pwd != NULL) {
@@ -846,19 +336,23 @@ void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
}
}
+
/*************************************************************
Routine to get the 32 hex characters and turn them
into a 16 byte array.
**************************************************************/
+
BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
{
int i;
unsigned char lonybble, hinybble;
char *hexchars = "0123456789ABCDEF";
char *p1, *p2;
-
- for (i = 0; i < 32; i += 2)
- {
+
+ if (!p)
+ return (False);
+
+ for (i = 0; i < 32; i += 2) {
hinybble = toupper(p[i]);
lonybble = toupper(p[i + 1]);
@@ -866,9 +360,7 @@ BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
p2 = strchr(hexchars, lonybble);
if (!p1 || !p2)
- {
return (False);
- }
hinybble = PTR_DIFF(p1, hexchars);
lonybble = PTR_DIFF(p2, hexchars);
@@ -884,35 +376,16 @@ BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
{
- struct passwd *pw = Get_Pwnam(user_name, False);
+ struct passwd *pw = Get_Pwnam(user_name, False);
if (u_rid == NULL || g_rid == NULL || user_name == NULL)
- {
return False;
- }
- if (!pw)
- {
+ if (!pw) {
DEBUG(1,("Username %s is invalid on this system\n", user_name));
return False;
}
-
- /* These parameters where removed. Use the 'domain admins' or 'domain
- guests' instead. --jerry */
-#if 0 /* JERRY */
- if (user_in_list(user_name, lp_domain_guest_users()))
- {
- *u_rid = DOMAIN_USER_RID_GUEST;
- }
- else if (user_in_list(user_name, lp_domain_admin_users()))
- {
- *u_rid = DOMAIN_USER_RID_ADMIN;
- }
- else
- {
-#endif
-
/* turn the unix UID into a Domain RID. this is what the posix
sub-system does (adds 1000 to the uid) */
*u_rid = pdb_uid_to_user_rid(pw->pw_uid);
@@ -923,239 +396,6 @@ BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
return True;
}
-/****************************************************************************
- Read the machine SID from a file.
-****************************************************************************/
-
-static BOOL read_sid_from_file(int fd, char *sid_file)
-{
- fstring fline;
-
- memset(fline, '\0', sizeof(fline));
-
- if(read(fd, fline, sizeof(fline) -1 ) < 0) {
- DEBUG(0,("unable to read file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- return False;
- }
-
- /*
- * Convert to the machine SID.
- */
-
- fline[sizeof(fline)-1] = '\0';
- if(!string_to_sid( &global_sam_sid, fline)) {
- DEBUG(0,("unable to generate machine SID.\n"));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
- Generate the global machine sid. Look for the MACHINE.SID file first, if
- not found then look in smb.conf and use it to create the MACHINE.SID file.
- Note this function will be replaced soon. JRA.
-****************************************************************************/
-
-BOOL pdb_generate_sam_sid(void)
-{
- int fd;
- char *p;
- pstring sid_file;
- fstring sid_string;
- SMB_STRUCT_STAT st;
- BOOL overwrite_bad_sid = False;
-
- generate_wellknown_sids();
-
- pstrcpy(sid_file, lp_smb_passwd_file());
- p = strrchr(sid_file, '/');
- if(p != NULL) {
- *++p = '\0';
- }
-
- if (!directory_exist(sid_file, NULL)) {
- if (mkdir(sid_file, 0700) != 0) {
- DEBUG(0,("can't create private directory %s : %s\n",
- sid_file, strerror(errno)));
- return False;
- }
- }
-
- pstrcat(sid_file, "MACHINE.SID");
-
- if((fd = sys_open(sid_file, O_RDWR | O_CREAT, 0644)) == -1) {
- DEBUG(0,("unable to open or create file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- return False;
- }
-
- /*
- * Check if the file contains data.
- */
-
- if(sys_fstat( fd, &st) < 0) {
- DEBUG(0,("unable to stat file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
-
- if(st.st_size > 0) {
- /*
- * We have a valid SID - read it.
- */
- if(!read_sid_from_file( fd, sid_file)) {
- DEBUG(0,("unable to read file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
-
- /*
- * JRA. Reversed the sense of this test now that I have
- * actually done this test *personally*. One more reason
- * to never trust third party information you have not
- * independently verified.... sigh. JRA.
- */
-
- if(global_sam_sid.num_auths > 0 && global_sam_sid.sub_auths[0] == 0x21) {
- /*
- * Fix and re-write...
- */
- overwrite_bad_sid = True;
- global_sam_sid.sub_auths[0] = 21;
- DEBUG(5,("pdb_generate_sam_sid: Old (incorrect) sid id_auth of hex 21 \
-detected - re-writing to be decimal 21 instead.\n" ));
- sid_to_string(sid_string, &global_sam_sid);
- if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0) {
- DEBUG(0,("unable to seek file file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
- } else {
- close(fd);
- return True;
- }
- } else {
- /*
- * The file contains no data - we need to generate our
- * own sid.
- * Generate the new sid data & turn it into a string.
- */
- int i;
- uchar raw_sid_data[12];
- DOM_SID mysid;
-
- memset((char *)&mysid, '\0', sizeof(DOM_SID));
- mysid.sid_rev_num = 1;
- mysid.id_auth[5] = 5;
- mysid.num_auths = 0;
- mysid.sub_auths[mysid.num_auths++] = 21;
-
- generate_random_buffer( raw_sid_data, 12, True);
- for( i = 0; i < 3; i++)
- mysid.sub_auths[mysid.num_auths++] = IVAL(raw_sid_data, i*4);
-
- sid_to_string(sid_string, &mysid);
- }
-
- fstrcat(sid_string, "\n");
-
- /*
- * Ensure our new SID is valid.
- */
-
- if(!string_to_sid( &global_sam_sid, sid_string)) {
- DEBUG(0,("unable to generate machine SID.\n"));
- return False;
- }
-
- /*
- * Do an exclusive blocking lock on the file.
- */
-
- if(!do_file_lock( fd, 60, F_WRLCK)) {
- DEBUG(0,("unable to lock file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
-
- if(!overwrite_bad_sid) {
- /*
- * At this point we have a blocking lock on the SID
- * file - check if in the meantime someone else wrote
- * SID data into the file. If so - they were here first,
- * use their data.
- */
-
- if(sys_fstat( fd, &st) < 0) {
- DEBUG(0,("unable to stat file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
-
- if(st.st_size > 0) {
- /*
- * Unlock as soon as possible to reduce
- * contention on the exclusive lock.
- */
- do_file_lock( fd, 60, F_UNLCK);
-
- /*
- * We have a valid SID - read it.
- */
-
- if(!read_sid_from_file( fd, sid_file)) {
- DEBUG(0,("unable to read file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- close(fd);
- return False;
- }
- close(fd);
- return True;
- }
- }
-
- /*
- * The file is still empty and we have an exlusive lock on it,
- * or we're fixing an earlier mistake.
- * Write out out SID data into the file.
- */
-
- /*
- * Use chmod here as some (strange) UNIX's don't
- * have fchmod. JRA.
- */
-
- if(chmod(sid_file, 0644) < 0) {
- DEBUG(0,("unable to set correct permissions on file %s. \
-Error was %s\n", sid_file, strerror(errno) ));
- do_file_lock( fd, 60, F_UNLCK);
- close(fd);
- return False;
- }
-
- if(write( fd, sid_string, strlen(sid_string)) != strlen(sid_string)) {
- DEBUG(0,("unable to write file %s. Error was %s\n",
- sid_file, strerror(errno) ));
- do_file_lock( fd, 60, F_UNLCK);
- close(fd);
- return False;
- }
-
- /*
- * Unlock & exit.
- */
-
- do_file_lock( fd, 60, F_UNLCK);
- close(fd);
- return True;
-}
/*******************************************************************
Converts NT user RID to a UNIX uid.
********************************************************************/
@@ -1204,7 +444,7 @@ static BOOL pdb_rid_is_well_known(uint32 rid)
/*******************************************************************
Decides if a RID is a user or group RID.
********************************************************************/
-
+
BOOL pdb_rid_is_user(uint32 rid)
{
/* lkcl i understand that NT attaches an enumeration to a RID
@@ -1230,9 +470,10 @@ BOOL pdb_rid_is_user(uint32 rid)
BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
{
-
BOOL is_user = pdb_rid_is_user(rid);
+ *psid_name_use = SID_NAME_UNKNOWN;
+
DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
"group", (unsigned int)rid));
@@ -1240,28 +481,26 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
if(rid == DOMAIN_USER_RID_ADMIN) {
pstring admin_users;
char *p = admin_users;
-#if 0 /* JERRY */
- pstrcpy( admin_users, lp_domain_admin_users());
-#endif
+ *psid_name_use = SID_NAME_USER;
if(!next_token(&p, name, NULL, sizeof(fstring)))
fstrcpy(name, "Administrator");
} else if (rid == DOMAIN_USER_RID_GUEST) {
pstring guest_users;
char *p = guest_users;
-#if 0 /* JERRY */
- pstrcpy( guest_users, lp_domain_guest_users());
-#endif
+ *psid_name_use = SID_NAME_USER;
if(!next_token(&p, name, NULL, sizeof(fstring)))
fstrcpy(name, "Guest");
} else {
uid_t uid;
struct passwd *pass;
-
- /* Don't try to convert the rid to a name if
- running in appliance mode */
-
- if (lp_hide_local_users()) return False;
-
+
+ /*
+ * Don't try to convert the rid to a name if
+ * running in appliance mode
+ */
+ if (lp_hide_local_users())
+ return False;
+
uid = pdb_user_rid_to_uid(rid);
pass = sys_getpwuid(uid);
@@ -1280,39 +519,36 @@ BOOL local_lookup_rid(uint32 rid, char *name, enum SID_NAME_USE *psid_name_use)
DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name,
(unsigned int)rid ));
}
+
} else {
gid_t gid;
- struct group *gr;
+ struct group *gr;
+
+ /*
+ * Don't try to convert the rid to a name if running
+ * in appliance mode
+ */
- /* Don't try to convert the rid to a name if
- running in appliance mode */
+ if (lp_hide_local_users())
+ return False;
+
+ gid = pdb_user_rid_to_gid(rid);
+ gr = getgrgid(gid);
- if (lp_hide_local_users()) return False;
+ *psid_name_use = SID_NAME_ALIAS;
- gid = pdb_user_rid_to_gid(rid);
+ DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
+ gr ? "succeeded" : "failed" ));
- switch (rid) {
- case DOMAIN_GROUP_RID_ADMINS:
- fstrcpy(name, "Domain Admins");
- break;
- case DOMAIN_GROUP_RID_USERS:
- fstrcpy(name, "Domain Users");
- break;
- case DOMAIN_GROUP_RID_GUESTS:
- fstrcpy(name, "Domain Guests");
- break;
- default:
- gr = getgrgid(gid);
- DEBUG(5,("local_lookup_rid: looking up gid %u %s\n", (unsigned int)gid, gr ? "succeeded" : "failed" ));
- if(!gr)
- slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
- else
- fstrcpy( name, gr->gr_name);
- break;
+ if(!gr) {
+ slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
+ return True;
}
- *psid_name_use = SID_NAME_ALIAS;
- DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name, (unsigned int)rid ));
+ fstrcpy( name, gr->gr_name);
+
+ DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
+ (unsigned int)rid ));
}
return True;
@@ -1330,6 +566,8 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
fstring user;
fstring domain;
+ *psid_name_use = SID_NAME_UNKNOWN;
+
/*
* domain and user may be quoted const strings, and map_username and
* friends can modify them. Make a modifiable copy. JRA.
@@ -1351,20 +589,18 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
return True;
}
- /* Don't lookup local unix users if running in appliance mode */
-
- if (lp_hide_local_users()) return False;
-
- /* Lookup names for users and groups on the local machine */
+ /*
+ * Don't lookup local unix users if running in appliance mode
+ */
+ if (lp_hide_local_users())
+ return False;
(void)map_username(user);
- /*
- * Must call Get_Pwnam to map uppercase names to lowercase names
- * when needed!
- */
-
- if(!(pass = Get_Pwnam(user,False))) {
+ if((pass = Get_Pwnam(user, False))) {
+ sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
+ *psid_name_use = SID_NAME_USER;
+ } else {
/*
* Maybe it was a group ?
*/
@@ -1375,10 +611,6 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
*psid_name_use = SID_NAME_ALIAS;
- } else {
-
- sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
- *psid_name_use = SID_NAME_USER;
}
sid_copy( psid, &local_sid);
@@ -1392,7 +624,7 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
{
- extern DOM_SID global_sam_sid;
+ extern DOM_SID global_sam_sid;
sid_copy(psid, &global_sam_sid);
sid_append_rid(psid, pdb_uid_to_user_rid(uid));
@@ -1400,14 +632,14 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
return psid;
}
-
/****************************************************************************
Convert a SID to uid - locally.
****************************************************************************/
BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
{
- extern DOM_SID global_sam_sid;
+ extern DOM_SID global_sam_sid;
+
DOM_SID dom_sid;
uint32 rid;
fstring str;
@@ -1425,7 +657,6 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
* We can only convert to a uid if this is our local
* Domain SID (ie. we are the controling authority).
*/
-
if (!sid_equal(&global_sam_sid, &dom_sid))
return False;
@@ -1434,13 +665,13 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
/*
* Ensure this uid really does exist.
*/
-
if(!(pass = sys_getpwuid(*puid)))
return False;
DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
(unsigned int)*puid, pass->pw_name ));
+ *name_type = SID_NAME_USER;
return True;
}
@@ -1467,8 +698,8 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
extern DOM_SID global_sam_sid;
DOM_SID dom_sid;
uint32 rid;
- struct group *grp;
fstring str;
+ struct group *grp;
*name_type = SID_NAME_UNKNOWN;
@@ -1495,8 +726,943 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
if(!(grp = getgrgid(*pgid)))
return False;
+ *name_type = SID_NAME_ALIAS;
+
DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u) (%s).\n", sid_to_string( str, psid),
(unsigned int)*pgid, grp->gr_name ));
return True;
}
+
+static void select_name(pstring string, const UNISTR2 *from)
+{
+ if (from->buffer != 0)
+ unistr2_to_ascii(string, from, sizeof(pstring));
+}
+
+/*************************************************************
+ Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
+ **************************************************************/
+
+void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
+{
+
+ if (from == NULL || to == NULL)
+ return;
+
+ to->logon_time = nt_time_to_unix(&from->logon_time);
+ to->logoff_time = nt_time_to_unix(&from->logoff_time);
+ to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
+ to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
+ to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
+ to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
+
+ select_name(to->username , &from->uni_user_name );
+ select_name(to->full_name , &from->uni_full_name );
+ select_name(to->home_dir , &from->uni_home_dir );
+ select_name(to->dir_drive , &from->uni_dir_drive );
+ select_name(to->logon_script, &from->uni_logon_script);
+ select_name(to->profile_path, &from->uni_profile_path);
+ select_name(to->acct_desc , &from->uni_acct_desc );
+ select_name(to->workstations, &from->uni_workstations);
+ select_name(to->unknown_str , &from->uni_unknown_str );
+ select_name(to->munged_dial , &from->uni_munged_dial );
+
+ to->user_rid = from->user_rid;
+ to->group_rid = from->group_rid;
+
+ to->acct_ctrl = from->acb_info;
+ to->unknown_3 = from->unknown_3;
+
+ to->logon_divs = from->logon_divs;
+ to->hours_len = from->logon_hrs.len;
+ memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
+
+ to->unknown_5 = from->unknown_5;
+ to->unknown_6 = from->unknown_6;
+}
+
+/*************************************************************
+ Copies a sam passwd.
+ **************************************************************/
+
+void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
+{
+ if (from == NULL || to == NULL)
+ return;
+
+ to->logon_time = nt_time_to_unix(&from->logon_time);
+ to->logoff_time = nt_time_to_unix(&from->logoff_time);
+ to->kickoff_time = nt_time_to_unix(&from->kickoff_time);
+ to->pass_last_set_time = nt_time_to_unix(&from->pass_last_set_time);
+ to->pass_can_change_time = nt_time_to_unix(&from->pass_can_change_time);
+ to->pass_must_change_time = nt_time_to_unix(&from->pass_must_change_time);
+
+ select_name(to->username , &from->uni_user_name );
+ select_name(to->full_name , &from->uni_full_name );
+ select_name(to->home_dir , &from->uni_home_dir );
+ select_name(to->dir_drive , &from->uni_dir_drive );
+ select_name(to->logon_script, &from->uni_logon_script);
+ select_name(to->profile_path, &from->uni_profile_path);
+ select_name(to->acct_desc , &from->uni_acct_desc );
+ select_name(to->workstations, &from->uni_workstations);
+ select_name(to->unknown_str , &from->uni_unknown_str );
+ select_name(to->munged_dial , &from->uni_munged_dial );
+
+ to->user_rid = from->user_rid;
+ to->group_rid = from->group_rid;
+
+ /* FIXME!! Do we need to copy the passwords here as well?
+ I don't know. Need to figure this out --jerry */
+
+ to->acct_ctrl = from->acb_info;
+ to->unknown_3 = from->unknown_3;
+
+ to->logon_divs = from->logon_divs;
+ to->hours_len = from->logon_hrs.len;
+ memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
+
+ to->unknown_5 = from->unknown_5;
+ to->unknown_6 = from->unknown_6;
+}
+
+/*************************************************************
+ Copies a SAM_ACCOUNT.
+ **************************************************************/
+
+void copy_sam_passwd(SAM_ACCOUNT *to, const SAM_ACCOUNT *from)
+{
+ if (!from || !to)
+ return;
+
+ memcpy(to, from, sizeof(SAM_ACCOUNT));
+}
+
+/*************************************************************
+ Change a password entry in the local smbpasswd file.
+
+ FIXME!! The function needs to be abstracted into the
+ passdb interface or something. It is currently being called
+ by _api_samr_create_user() in rpc_server/srv_samr.c
+
+ --jerry
+ *************************************************************/
+
+BOOL local_password_change(char *user_name, int local_flags,
+ char *new_passwd,
+ char *err_str, size_t err_str_len,
+ char *msg_str, size_t msg_str_len)
+{
+ struct passwd *pwd = NULL;
+ SAM_ACCOUNT *sam_pass=NULL;
+
+ *err_str = '\0';
+ *msg_str = '\0';
+
+ if (local_flags & LOCAL_ADD_USER) {
+
+ /*
+ * Check for a local account - if we're adding only.
+ */
+
+ if(!(pwd = sys_getpwnam(user_name))) {
+ slprintf(err_str, err_str_len - 1, "User %s does not \
+exist in system password file (usually /etc/passwd). Cannot add \
+account without a valid local system user.\n", user_name);
+ return False;
+ }
+ }
+
+ /* Get the smb passwd entry for this user */
+ pdb_init_sam(&sam_pass);
+ if(!pdb_getsampwnam(sam_pass, user_name)) {
+ pdb_free_sam(sam_pass);
+
+ if(!(local_flags & LOCAL_ADD_USER)) {
+ slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
+ return False;
+ }
+
+ sam_pass = NULL;
+ if (!pdb_init_sam_pw(&sam_pass, pwd)) {
+ return False;
+ }
+
+ /* Set account flags. Note that the default is non-expiring accounts */
+ pdb_set_acct_ctrl(sam_pass,(local_flags & LOCAL_TRUST_ACCOUNT) ? ACB_WSTRUST : ACB_NORMAL|ACB_PWNOEXP);
+
+ if (local_flags & LOCAL_DISABLE_USER)
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED);
+
+ if (local_flags & LOCAL_SET_NO_PASSWORD) {
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ);
+ } else {
+ /* set the passwords here. if we get to here it means
+ we have a valid, active account */
+ if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ }
+
+ if (pdb_add_sam_account(sam_pass)) {
+ slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return True;
+ } else {
+ slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ } else {
+ /* the entry already existed */
+ local_flags &= ~LOCAL_ADD_USER;
+ }
+
+ /*
+ * We are root - just write the new password
+ * and the valid last change time.
+ */
+
+ if(local_flags & LOCAL_DISABLE_USER) {
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED);
+ } else if (local_flags & LOCAL_ENABLE_USER) {
+ if(pdb_get_lanman_passwd(sam_pass) == NULL) {
+ if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ }
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
+ } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ);
+
+ /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
+ if (!pdb_set_lanman_passwd (sam_pass, NULL)) {
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ if (!pdb_set_nt_passwd(sam_pass, NULL)) {
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ } else {
+ /*
+ * If we're dealing with setting a completely empty user account
+ * ie. One with a password of 'XXXX', but not set disabled (like
+ * an account created from scratch) then if the old password was
+ * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
+ * We remove that as we're giving this user their first password
+ * and the decision hasn't really been made to disable them (ie.
+ * don't create them disabled). JRA.
+ */
+ if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED))
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED));
+ pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ));
+ if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ }
+
+ if(local_flags & LOCAL_DELETE_USER) {
+ if (!pdb_delete_sam_account(user_name)) {
+ slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
+ } else {
+ if(!pdb_update_sam_account(sam_pass, True)) {
+ slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
+ pdb_free_sam(sam_pass);
+ return False;
+ }
+ if(local_flags & LOCAL_DISABLE_USER)
+ slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
+ else if (local_flags & LOCAL_ENABLE_USER)
+ slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
+ else if (local_flags & LOCAL_SET_NO_PASSWORD)
+ slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
+ }
+
+ pdb_free_sam(sam_pass);
+ return True;
+}
+
+/*********************************************************************
+ Collection of get...() functions for SAM_ACCOUNT_INFO.
+ ********************************************************************/
+
+uint16 pdb_get_acct_ctrl (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->acct_ctrl);
+ else
+ return (ACB_DISABLED);
+}
+
+time_t pdb_get_logon_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->logon_time);
+ else
+ return (0);
+}
+
+time_t pdb_get_logoff_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->logoff_time);
+ else
+ return (-1);
+}
+
+time_t pdb_get_kickoff_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->kickoff_time);
+ else
+ return (-1);
+}
+
+time_t pdb_get_pass_last_set_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->pass_last_set_time);
+ else
+ return (-1);
+}
+
+time_t pdb_get_pass_can_change_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->pass_can_change_time);
+ else
+ return (-1);
+}
+
+time_t pdb_get_pass_must_change_time (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->pass_must_change_time);
+ else
+ return (-1);
+}
+
+uint16 pdb_get_logon_divs (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->logon_divs);
+ else
+ return (-1);
+}
+
+uint32 pdb_get_hours_len (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->hours_len);
+ else
+ return (-1);
+}
+
+uint8* pdb_get_hours (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->hours);
+ else
+ return (NULL);
+}
+
+uint8* pdb_get_nt_passwd (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->nt_pw);
+ else
+ return (NULL);
+}
+
+uint8* pdb_get_lanman_passwd (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->lm_pw);
+ else
+ return (NULL);
+}
+
+uint32 pdb_get_user_rid (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->user_rid);
+ else
+ return (-1);
+}
+
+uint32 pdb_get_group_rid (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->group_rid);
+ else
+ return (-1);
+}
+
+uid_t pdb_get_uid (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->uid);
+ else
+ return ((uid_t)-1);
+}
+
+gid_t pdb_get_gid (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->gid);
+ else
+ return ((gid_t)-1);
+}
+
+char* pdb_get_username (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->username);
+ else
+ return (NULL);
+}
+
+char* pdb_get_domain (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->domain);
+ else
+ return (NULL);
+}
+
+char* pdb_get_nt_username (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->nt_username);
+ else
+ return (NULL);
+}
+
+char* pdb_get_fullname (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->full_name);
+ else
+ return (NULL);
+}
+
+char* pdb_get_homedir (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->home_dir);
+ else
+ return (NULL);
+}
+
+char* pdb_get_dirdrive (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->dir_drive);
+ else
+ return (NULL);
+}
+
+char* pdb_get_logon_script (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->logon_script);
+ else
+ return (NULL);
+}
+
+char* pdb_get_profile_path (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->profile_path);
+ else
+ return (NULL);
+}
+
+char* pdb_get_acct_desc (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->acct_desc);
+ else
+ return (NULL);
+}
+
+char* pdb_get_workstations (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->workstations);
+ else
+ return (NULL);
+}
+
+char* pdb_get_munged_dial (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->munged_dial);
+ else
+ return (NULL);
+}
+
+uint32 pdb_get_unknown3 (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->unknown_3);
+ else
+ return (-1);
+}
+
+uint32 pdb_get_unknown5 (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->unknown_5);
+ else
+ return (-1);
+}
+
+uint32 pdb_get_unknown6 (SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->unknown_6);
+ else
+ return (-1);
+}
+
+/*********************************************************************
+ Collection of set...() functions for SAM_ACCOUNT_INFO.
+ ********************************************************************/
+
+BOOL pdb_set_acct_ctrl (SAM_ACCOUNT *sampass, uint16 flags)
+{
+ if (!sampass)
+ return False;
+
+ if (sampass) {
+ sampass->acct_ctrl = flags;
+ return True;
+ }
+
+ return False;
+}
+
+BOOL pdb_set_logon_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
+ return False;
+
+ sampass->logon_time = mytime;
+ return True;
+}
+
+BOOL pdb_set_logoff_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
+ return False;
+
+ sampass->logoff_time = mytime;
+ return True;
+}
+
+BOOL pdb_set_kickoff_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
+ return False;
+
+ sampass->kickoff_time = mytime;
+ return True;
+}
+
+BOOL pdb_set_pass_can_change_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
+ return False;
+
+ sampass->pass_can_change_time = mytime;
+ return True;
+}
+
+BOOL pdb_set_pass_must_change_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
+ return False;
+
+ sampass->pass_must_change_time = mytime;
+ return True;
+}
+
+BOOL pdb_set_pass_last_set_time (SAM_ACCOUNT *sampass, time_t mytime)
+{
+ if (!sampass)
+ return False;
+
+ sampass->pass_last_set_time = mytime;
+ return True;
+}
+
+BOOL pdb_set_hours_len (SAM_ACCOUNT *sampass, uint32 len)
+{
+ if (!sampass)
+ return False;
+
+ sampass->hours_len = len;
+ return True;
+}
+
+BOOL pdb_set_logons_divs (SAM_ACCOUNT *sampass, uint16 hours)
+{
+ if (!sampass)
+ return False;
+
+ sampass->logon_divs = hours;
+ return True;
+}
+
+BOOL pdb_set_uid (SAM_ACCOUNT *sampass, uid_t uid)
+{
+ if (!sampass)
+ return False;
+
+ sampass->uid = uid;
+ return True;
+}
+
+BOOL pdb_set_gid (SAM_ACCOUNT *sampass, gid_t gid)
+{
+ if (!sampass)
+ return False;
+
+ sampass->gid = gid;
+ return True;
+}
+
+BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid)
+{
+ if (!sampass)
+ return False;
+
+ sampass->user_rid = rid;
+ return True;
+}
+
+BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid)
+{
+ if (!sampass)
+ return False;
+
+ sampass->group_rid = grid;
+ return True;
+}
+
+/*********************************************************************
+ Set the user's UNIX name.
+ ********************************************************************/
+
+BOOL pdb_set_username(SAM_ACCOUNT *sampass, char *username)
+{
+ if (!sampass)
+ return False;
+ *sampass->username = '\0';
+ if (!username)
+ return False;
+
+ StrnCpy (sampass->username, username, strlen(username));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the domain name.
+ ********************************************************************/
+
+BOOL pdb_set_domain(SAM_ACCOUNT *sampass, char *domain)
+{
+ if (!sampass)
+ return False;
+ *sampass->domain = '\0';
+ if (!domain)
+ return False;
+
+ StrnCpy (sampass->domain, domain, strlen(domain));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's NT name.
+ ********************************************************************/
+
+BOOL pdb_set_nt_username(SAM_ACCOUNT *sampass, char *nt_username)
+{
+ if (!sampass)
+ return False;
+ *sampass->nt_username = '\0';
+ if (!nt_username)
+ return False;
+
+ StrnCpy (sampass->nt_username, nt_username, strlen(nt_username));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's full name.
+ ********************************************************************/
+
+BOOL pdb_set_fullname(SAM_ACCOUNT *sampass, char *fullname)
+{
+ if (!sampass)
+ return False;
+ *sampass->full_name = '\0';
+ if (!fullname)
+ return False;
+
+ StrnCpy (sampass->full_name, fullname, strlen(fullname));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's logon script.
+ ********************************************************************/
+
+BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, char *logon_script)
+{
+ if (!sampass)
+ return False;
+ *sampass->logon_script = '\0';
+ if (!logon_script)
+ return False;
+
+ StrnCpy (sampass->logon_script, logon_script, strlen(logon_script));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's profile path.
+ ********************************************************************/
+
+BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, char *profile_path)
+{
+ if (!sampass)
+ return False;
+ *sampass->profile_path = '\0';
+ if (!profile_path)
+ return False;
+
+ StrnCpy (sampass->profile_path, profile_path, strlen(profile_path));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's directory drive.
+ ********************************************************************/
+
+BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, char *dir_drive)
+{
+ if (!sampass)
+ return False;
+ *sampass->dir_drive = '\0';
+ if (!dir_drive)
+ return False;
+
+ StrnCpy (sampass->dir_drive, dir_drive, strlen(dir_drive));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's home directory.
+ ********************************************************************/
+
+BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, char *homedir)
+{
+ if (!sampass)
+ return False;
+ *sampass->home_dir = '\0';
+ if (!homedir)
+ return False;
+
+ StrnCpy (sampass->home_dir, homedir, strlen(homedir));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's account description.
+ ********************************************************************/
+
+BOOL pdb_set_acct_desc (SAM_ACCOUNT *sampass, char *acct_desc)
+{
+ if (!sampass)
+ return False;
+ *sampass->acct_desc = '\0';
+ if (!acct_desc)
+ return False;
+
+ StrnCpy (sampass->acct_desc, acct_desc, strlen(acct_desc));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's workstation allowed list.
+ ********************************************************************/
+
+BOOL pdb_set_workstations (SAM_ACCOUNT *sampass, char *workstations)
+{
+ if (!sampass)
+ return False;
+ *sampass->workstations = '\0';
+ if (!workstations)
+ return False;
+
+ StrnCpy (sampass->workstations, workstations, strlen(workstations));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's dial string.
+ ********************************************************************/
+
+BOOL pdb_set_munged_dial (SAM_ACCOUNT *sampass, char *munged_dial)
+{
+ if (!sampass)
+ return False;
+ *sampass->munged_dial = '\0';
+ if (!munged_dial)
+ return False;
+
+ StrnCpy (sampass->munged_dial, munged_dial, strlen(munged_dial));
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's NT hash.
+ ********************************************************************/
+
+BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
+{
+ if (!sampass)
+ return False;
+
+ if (!pwd) {
+ /* Allow setting to NULL */
+ SAFE_FREE(sampass->nt_pw);
+ return True;
+ }
+
+ if (sampass->nt_pw!=NULL)
+ DEBUG(4,("pdb_set_nt_passwd: NT hash non NULL overwritting ?\n"));
+ else
+ sampass->nt_pw=(unsigned char *)malloc(sizeof(unsigned char)*16);
+
+ if (sampass->nt_pw==NULL)
+ return False;
+
+ memcpy (sampass->nt_pw, pwd, 16);
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's LM hash.
+ ********************************************************************/
+
+BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, uint8 *pwd)
+{
+ if (!sampass)
+ return False;
+
+ if (!pwd) {
+ /* Allow setting to NULL */
+ SAFE_FREE(sampass->lm_pw);
+ return True;
+ }
+
+ if (sampass->lm_pw!=NULL)
+ DEBUG(4,("pdb_set_lanman_passwd: LM hash non NULL overwritting ?\n"));
+ else
+ sampass->lm_pw=(unsigned char *)malloc(sizeof(unsigned char)*16);
+
+ if (sampass->lm_pw==NULL)
+ return False;
+
+ memcpy (sampass->lm_pw, pwd, 16);
+
+ return True;
+}
+
+/*********************************************************************
+ Set the user's PLAINTEXT password. Used as an interface to the above.
+ ********************************************************************/
+
+BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, char *plaintext)
+{
+ uchar new_lanman_p16[16];
+ uchar new_nt_p16[16];
+
+ if (!sampass || !plaintext)
+ return False;
+
+ nt_lm_owf_gen (plaintext, new_nt_p16, new_lanman_p16);
+
+ if (!pdb_set_nt_passwd (sampass, new_nt_p16))
+ return False;
+
+ if (!pdb_set_lanman_passwd (sampass, new_lanman_p16))
+ return False;
+
+ return True;
+}
+
+BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn)
+{
+ if (!sampass)
+ return False;
+
+ sampass->unknown_3 = unkn;
+ return True;
+}
+
+BOOL pdb_set_unknown_5 (SAM_ACCOUNT *sampass, uint32 unkn)
+{
+ if (!sampass)
+ return False;
+
+ sampass->unknown_5 = unkn;
+ return True;
+}
+
+BOOL pdb_set_unknown_6 (SAM_ACCOUNT *sampass, uint32 unkn)
+{
+ if (!sampass)
+ return False;
+
+ sampass->unknown_6 = unkn;
+ return True;
+}
+
+BOOL pdb_set_hours (SAM_ACCOUNT *sampass, uint8 *hours)
+{
+ if (!sampass)
+ return False;
+
+ if (!hours) {
+ memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
+ return True;
+ }
+
+ memcpy (sampass->hours, hours, MAX_HOURS_LEN);
+
+ return True;
+}
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index be528abae73..856adec244b 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -30,18 +30,14 @@ static TDB_CONTEXT *tdb;
BOOL secrets_init(void)
{
pstring fname;
- char *p;
-
- if (tdb) return True;
- pstrcpy(fname, lp_smb_passwd_file());
- p = strrchr(fname, '/');
- if(!p) return False;
+ if (tdb)
+ return True;
- *p = 0;
+ get_private_directory(fname);
pstrcat(fname,"/secrets.tdb");
- tdb = tdb_open_log(fname, 0, 0, O_RDWR|O_CREAT, 0600);
+ tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb) {
DEBUG(0,("Failed to open %s\n", fname));
@@ -56,11 +52,13 @@ BOOL secrets_init(void)
void *secrets_fetch(char *key, size_t *size)
{
TDB_DATA kbuf, dbuf;
- if (!tdb) return False;
+ if (!tdb)
+ return False;
kbuf.dptr = key;
kbuf.dsize = strlen(key);
dbuf = tdb_fetch(tdb, kbuf);
- if (size) *size = dbuf.dsize;
+ if (size)
+ *size = dbuf.dsize;
return dbuf.dptr;
}
@@ -69,7 +67,8 @@ void *secrets_fetch(char *key, size_t *size)
BOOL secrets_store(char *key, void *data, size_t size)
{
TDB_DATA kbuf, dbuf;
- if (!tdb) return False;
+ if (!tdb)
+ return False;
kbuf.dptr = key;
kbuf.dsize = strlen(key);
dbuf.dptr = data;
@@ -83,7 +82,8 @@ BOOL secrets_store(char *key, void *data, size_t size)
BOOL secrets_delete(char *key)
{
TDB_DATA kbuf;
- if (!tdb) return False;
+ if (!tdb)
+ return False;
kbuf.dptr = key;
kbuf.dsize = strlen(key);
return tdb_delete(tdb, kbuf) == 0;
@@ -110,8 +110,7 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
if (dyn_sid == NULL)
return False;
- if (size != sizeof(DOM_SID))
- {
+ if (size != sizeof(DOM_SID)) {
free(dyn_sid);
return False;
}
@@ -121,10 +120,10 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
return True;
}
-
/************************************************************************
form a key for fetching a domain trust password
************************************************************************/
+
char *trust_keystr(char *domain)
{
static fstring keystr;
@@ -212,3 +211,44 @@ void reset_globals_after_fork(void)
*/
generate_random_buffer( &dummy, 1, True);
}
+
+BOOL secrets_store_ldap_pw(char* dn, char* pw)
+{
+ fstring key;
+ char *p;
+
+ pstrcpy(key, dn);
+ for (p=key; *p; p++)
+ if (*p == ',') *p = '/';
+
+ return secrets_store(key, pw, strlen(pw));
+}
+
+BOOL fetch_ldap_pw(char *dn, char* pw, int len)
+{
+ fstring key;
+ char *p;
+ void *data = NULL;
+ size_t size;
+
+ pstrcpy(key, dn);
+ for (p=key; *p; p++)
+ if (*p == ',') *p = '/';
+
+ data=secrets_fetch(key, &size);
+ if (!size) {
+ DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n"));
+ return False;
+ }
+
+ if (size > len-1)
+ {
+ DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1));
+ return False;
+ }
+
+ memcpy(pw, data, size);
+ pw[size] = '\0';
+
+ return True;
+}
diff --git a/source/passdb/smbpassfile.c b/source/passdb/smbpassfile.c
index c1ab8868d43..e4b11dbf76a 100644
--- a/source/passdb/smbpassfile.c
+++ b/source/passdb/smbpassfile.c
@@ -30,13 +30,15 @@
extern int DEBUGLEVEL;
extern pstring global_myname;
-BOOL global_machine_password_needs_changing = False;
+
+static int mach_passwd_lock_depth;
+static FILE *mach_passwd_fp;
/***************************************************************
Lock an fd. Abandon after waitsecs seconds.
****************************************************************/
-BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
+static BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
{
if (fd < 0)
return False;
@@ -58,7 +60,7 @@ BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
Unlock an fd. Abandon after waitsecs seconds.
****************************************************************/
-BOOL pw_file_unlock(int fd, int *plock_depth)
+static BOOL pw_file_unlock(int fd, int *plock_depth)
{
BOOL ret=True;
@@ -74,9 +76,6 @@ BOOL pw_file_unlock(int fd, int *plock_depth)
return ret;
}
-static int mach_passwd_lock_depth;
-static FILE *mach_passwd_fp;
-
/************************************************************************
Routine to get the name for an old trust account file.
************************************************************************/
@@ -84,17 +83,14 @@ static FILE *mach_passwd_fp;
static void get_trust_account_file_name( char *domain, char *name, char *mac_file)
{
unsigned int mac_file_len;
- char *p;
- pstrcpy(mac_file, lp_smb_passwd_file());
- p = strrchr(mac_file, '/');
- if(p != NULL)
- *++p = '\0';
+ /* strip the filename to the last '/' */
+ get_private_directory(mac_file);
+ pstrcat(mac_file, "/");
mac_file_len = strlen(mac_file);
- if ((int)(sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6) < 0)
- {
+ if ((int)(sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6) < 0) {
DEBUG(0,("trust_password_lock: path %s too long to add trust details.\n",
mac_file));
return;
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index 5e28f3e5b60..c410c9d1e04 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -26,13 +26,20 @@ extern int DEBUGLEVEL;
extern pstring global_myname;
extern DOM_SID global_sid_World;
-static TDB_CONTEXT *tdb; /* used for driver files */
+static TDB_CONTEXT *tdb_forms; /* used for forms files */
+static TDB_CONTEXT *tdb_drivers; /* used for driver files */
+static TDB_CONTEXT *tdb_printers; /* used for printers files */
#define FORMS_PREFIX "FORMS/"
#define DRIVERS_PREFIX "DRIVERS/"
+#define DRIVER_INIT_PREFIX "DRIVER_INIT/"
#define PRINTERS_PREFIX "PRINTERS/"
-
-#define NTDRIVERS_DATABASE_VERSION 1
+#define SECDESC_PREFIX "SECDESC/"
+
+#define NTDRIVERS_DATABASE_VERSION_1 1
+#define NTDRIVERS_DATABASE_VERSION_2 2
+
+#define NTDRIVERS_DATABASE_VERSION NTDRIVERS_DATABASE_VERSION_2
/* Map generic permissions to printer object specific permissions */
@@ -48,8 +55,6 @@ forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
array index). Letter is always first, so (for the current code) additions
always put things in the correct order. */
static nt_forms_struct default_forms[] = {
- {"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
-
{"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
{"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
{"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
@@ -170,6 +175,58 @@ static nt_forms_struct default_forms[] = {
{"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
};
+static BOOL upgrade_to_version_2(void)
+{
+ TDB_DATA kbuf, newkey, dbuf;
+
+ DEBUG(0,("upgrade_to_version_2: upgrading print tdb's to version 2\n"));
+
+ for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
+ newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
+
+ dbuf = tdb_fetch(tdb_drivers, kbuf);
+
+ if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
+ DEBUG(0,("upgrade_to_version_2:moving form\n"));
+ if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
+ DEBUG(0,("upgrade_to_version_2: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
+ return False;
+ }
+ if (tdb_delete(tdb_drivers, kbuf) != 0) {
+ DEBUG(0,("upgrade_to_version_2: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ return False;
+ }
+ }
+
+ if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
+ DEBUG(0,("upgrade_to_version_2:moving printer\n"));
+ if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
+ DEBUG(0,("upgrade_to_version_2: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
+ return False;
+ }
+ if (tdb_delete(tdb_drivers, kbuf) != 0) {
+ DEBUG(0,("upgrade_to_version_2: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ return False;
+ }
+ }
+
+ if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
+ DEBUG(0,("upgrade_to_version_2:moving secdesc\n"));
+ if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
+ DEBUG(0,("upgrade_to_version_2: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
+ return False;
+ }
+ if (tdb_delete(tdb_drivers, kbuf) != 0) {
+ DEBUG(0,("upgrade_to_version_2: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
+ return False;
+ }
+ }
+
+ safe_free(dbuf.dptr);
+ }
+
+ return True;
+}
/****************************************************************************
open the NT printing tdb
@@ -179,23 +236,45 @@ BOOL nt_printing_init(void)
static pid_t local_pid;
char *vstring = "INFO/version";
- if (tdb && local_pid == sys_getpid()) return True;
- tdb = tdb_open_log(lock_path("ntdrivers.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open nt drivers database %s (%s)\n",
+ if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
+ return True;
+
+ tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!tdb_drivers) {
+ DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
lock_path("ntdrivers.tdb"), strerror(errno) ));
return False;
}
-
+
+ tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!tdb_printers) {
+ DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
+ lock_path("ntprinters.tdb"), strerror(errno) ));
+ return False;
+ }
+
+ tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!tdb_forms) {
+ DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
+ lock_path("ntforms.tdb"), strerror(errno) ));
+ return False;
+ }
+
local_pid = sys_getpid();
-
+
/* handle a Samba upgrade */
- tdb_lock_bystring(tdb, vstring);
- if (tdb_fetch_int(tdb, vstring) != NTDRIVERS_DATABASE_VERSION) {
- tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
- tdb_store_int(tdb, vstring, NTDRIVERS_DATABASE_VERSION);
- }
- tdb_unlock_bystring(tdb, vstring);
+ tdb_lock_bystring(tdb_drivers, vstring);
+ if (tdb_fetch_int(tdb_drivers, vstring) != NTDRIVERS_DATABASE_VERSION) {
+
+ if (tdb_fetch_int(tdb_drivers, vstring) == NTDRIVERS_DATABASE_VERSION_1) {
+ if (!upgrade_to_version_2())
+ return False;
+ } else
+ tdb_traverse(tdb_drivers, (tdb_traverse_func)tdb_delete, NULL);
+
+ tdb_store_int(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION);
+ }
+ tdb_unlock_bystring(tdb_drivers, vstring);
return True;
}
@@ -237,17 +316,18 @@ get a form struct list
int get_ntforms(nt_forms_struct **list)
{
TDB_DATA kbuf, newkey, dbuf;
+ nt_forms_struct *tl;
nt_forms_struct form;
int ret;
int i;
int n = 0;
- for (kbuf = tdb_firstkey(tdb);
+ for (kbuf = tdb_firstkey(tdb_forms);
kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
+ newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) continue;
- dbuf = tdb_fetch(tdb, kbuf);
+ dbuf = tdb_fetch(tdb_forms, kbuf);
if (!dbuf.dptr) continue;
fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
@@ -257,11 +337,12 @@ int get_ntforms(nt_forms_struct **list)
safe_free(dbuf.dptr);
if (ret != dbuf.dsize) continue;
- *list = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
- if (!*list) {
+ tl = Realloc(*list, sizeof(nt_forms_struct)*(n+1));
+ if (!tl) {
DEBUG(0,("get_ntforms: Realloc fail.\n"));
return 0;
}
+ *list = tl;
(*list)[n] = form;
n++;
}
@@ -293,7 +374,7 @@ int write_ntforms(nt_forms_struct **list, int number)
kbuf.dptr = key;
dbuf.dsize = len;
dbuf.dptr = buf;
- if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) break;
+ if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
}
return i;
@@ -307,6 +388,7 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
int n=0;
BOOL update;
fstring form_name;
+ nt_forms_struct *tl;
/*
* NT tries to add forms even when
@@ -326,8 +408,11 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
}
if (update==False) {
- if((*list=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL)
+ if((tl=Realloc(*list, (n+1)*sizeof(nt_forms_struct))) == NULL) {
+ DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
return False;
+ }
+ *list = tl;
unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
(*count)++;
}
@@ -366,7 +451,7 @@ BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32
if (n == *count) {
DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
- *ret = ERROR_INVALID_PARAMETER;
+ *ret = ERRinvalidparam;
return False;
}
@@ -374,8 +459,8 @@ BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, uint32
dos_to_unix(key, True); /* Convert key to unix-codepage */
kbuf.dsize = strlen(key)+1;
kbuf.dptr = key;
- if (tdb_delete(tdb, kbuf) != 0) {
- *ret = ERROR_NOT_ENOUGH_MEMORY;
+ if (tdb_delete(tdb_forms, kbuf) != 0) {
+ *ret = ERRnomem;
return False;
}
@@ -419,19 +504,23 @@ int get_ntdrivers(fstring **list, char *architecture, uint32 version)
{
int total=0;
fstring short_archi;
+ fstring *fl;
pstring key;
TDB_DATA kbuf, newkey;
get_short_archi(short_archi, architecture);
slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
- for (kbuf = tdb_firstkey(tdb);
+ for (kbuf = tdb_firstkey(tdb_drivers);
kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
+ newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
if (strncmp(kbuf.dptr, key, strlen(key)) != 0) continue;
- if((*list = Realloc(*list, sizeof(fstring)*(total+1))) == NULL)
+ if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
+ DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
return -1;
+ } else
+ *list = fl;
fstrcpy((*list)[total], kbuf.dptr+strlen(key));
total++;
@@ -471,7 +560,7 @@ BOOL get_short_archi(char *short_archi, char *long_archi)
if (archi_table[i].long_archi==NULL) {
DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
- return FALSE;
+ return False;
}
StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
@@ -480,375 +569,9 @@ BOOL get_short_archi(char *short_archi, char *long_archi)
DEBUGADD(108,("long architecture: [%s]\n", long_archi));
DEBUGADD(108,("short architecture: [%s]\n", short_archi));
- return TRUE;
-}
-
-/****************************************************************************
-Determine the correct cVersion associated with an architecture and driver
-****************************************************************************/
-static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
- struct current_user *user, uint32 *perr)
-{
- int cversion;
- int access_mode;
- int action;
- int ecode;
- char buf[PE_HEADER_SIZE];
- ssize_t byte_count;
- pstring driverpath;
- fstring user_name;
- fstring null_pw;
- files_struct *fsp = NULL;
- BOOL bad_path;
- SMB_STRUCT_STAT st;
- struct passwd *pass;
- connection_struct *conn;
-
- ZERO_STRUCT(st);
-
- /* If architecture is Windows 95/98, the version is always 0. */
- if (strcmp(architecture, "WIN40") == 0) {
- DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
- return 0;
- }
-
- become_root();
- pass = sys_getpwuid(user->uid);
- if(pass == NULL) {
- DEBUG(0,("get_correct_cversion: Unable to get passwd entry for uid %u\n",
- (unsigned int)user->uid ));
- unbecome_root();
- *perr = ERROR_ACCESS_DENIED;
- return -1;
- }
- unbecome_root();
-
- /* connect to the print$ share under the same account as the user connected
- * to the rpc pipe */
- fstrcpy(user_name, pass->pw_name );
- DEBUG(10,("get_correct_cversion: uid %d -> user %s\n", (int)user->uid, user_name));
-
- /* Null password is ok - we are already an authenticated user... */
- *null_pw = '\0';
- conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
-
- if (conn == NULL) {
- DEBUG(0,("get_correct_cversion: Unable to connect\n"));
- *perr = (uint32)ecode;
- return -1;
- }
-
- /* Save who we are - we are temporarily becoming the connection user. */
- push_sec_ctx();
-
- if (!become_user(conn, conn->vuid)) {
- DEBUG(0,("get_correct_cversion: Can't become user %s\n", user_name ));
- *perr = ERROR_ACCESS_DENIED;
- pop_sec_ctx();
- return -1;
- }
-
- /* Open the driver file (Portable Executable format) and determine the
- * deriver the cversion. */
- slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
-
- unix_convert(driverpath,conn,NULL,&bad_path,&st);
-
- fsp = open_file_shared(conn, driverpath, &st,
- SET_OPEN_MODE(DOS_OPEN_RDONLY),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- 0, 0, &access_mode, &action);
- if (!fsp) {
- DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
- driverpath, errno));
- *perr = ERROR_ACCESS_DENIED;
- goto error_exit;
- }
-
- if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
- DEBUG(3,("get_correct_cversion: File [%s] DOS header too short, bytes read = %d\n",
- driverpath, byte_count));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
-
- /* Is this really a DOS header? */
- if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
- DEBUG(6,("get_correct_cversion: File [%s] bad DOS magic = 0x%x\n",
- driverpath, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
-
- /* Skip OEM header (if any) and the DOS stub to start of Windows header */
- if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
- DEBUG(3,("get_correct_cversion: File [%s] too short, errno = %d\n",
- driverpath, errno));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
-
- if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
- DEBUG(3,("get_correct_cversion: File [%s] Windows header too short, bytes read = %d\n",
- driverpath, byte_count));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
-
- /* The header may be a PE (Portable Executable) or an NE (New Executable) */
- if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
- if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) == PE_HEADER_MACHINE_I386) {
-
- switch (SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)) {
- case 4: cversion = 2; break; /* Win NT 4 */
- case 5: cversion = 3; break; /* Win 2000 */
- default:
- DEBUG(6,("get_correct_cversion: PE formated file [%s] bad version = %d\n",
- driverpath, SVAL(buf,PE_HEADER_MAJOR_OS_VER_OFFSET)));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
- } else {
- DEBUG(6,("get_correct_cversion: PE formatted file [%s] wrong machine = 0x%x\n",
- driverpath, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
-
- } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
- if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) == NE_HEADER_TARGOS_WIN ) {
-
- switch (CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)) {
- case 3: cversion = 0; break; /* Win 3.x / Win 9x / Win ME */
- /* case ?: cversion = 1; break;*/ /* Win NT 3.51 ... needs research JRR */
- default:
- DEBUG(6,("get_correct_cversion: NE formated file [%s] bad version = %d\n",
- driverpath, CVAL(buf,NE_HEADER_MAJOR_VER_OFFSET)));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
- } else {
- DEBUG(6,("get_correct_cversion: NE formatted file [%s] wrong target OS = 0x%x\n",
- driverpath, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
-
- } else {
- DEBUG(6,("get_correct_cversion: Unknown file format [%s], signature = 0x%x\n",
- driverpath, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
- *perr = NT_STATUS_FILE_INVALID;
- goto error_exit;
- }
-
- DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
- driverpath, cversion));
-
- close_file(fsp, True);
- close_cnum(conn, user->vuid);
- pop_sec_ctx();
- return cversion;
-
-
- error_exit:
- if(fsp)
- close_file(fsp, True);
-
- close_cnum(conn, user->vuid);
- pop_sec_ctx();
- return -1;
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
- struct current_user *user)
-{
- fstring architecture;
- fstring new_name;
- char *p;
- int i;
- uint32 err;
-
- /* clean up the driver name.
- * we can get .\driver.dll
- * or worse c:\windows\system\driver.dll !
- */
- /* using an intermediate string to not have overlaping memcpy()'s */
- if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->driverpath, new_name);
- }
-
- if ((p = strrchr(driver->datafile,'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->datafile, new_name);
- }
-
- if ((p = strrchr(driver->configfile,'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->configfile, new_name);
- }
-
- if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->helpfile, new_name);
- }
-
- if (driver->dependentfiles) {
- for (i=0; *driver->dependentfiles[i]; i++) {
- if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->dependentfiles[i], new_name);
- }
- }
- }
-
- get_short_archi(architecture, driver->environment);
-
- /* jfm:7/16/2000 the client always sends the cversion=0.
- * The server should check which version the driver is by reading
- * the PE header of driver->driverpath.
- *
- * For Windows 95/98 the version is 0 (so the value sent is correct)
- * For Windows NT (the architecture doesn't matter)
- * NT 3.1: cversion=0
- * NT 3.5/3.51: cversion=1
- * NT 4: cversion=2
- * NT2K: cversion=3
- */
- if ((driver->cversion = get_correct_cversion( architecture,
- driver->driverpath, user, &err)) == -1)
- return err;
-
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
- struct current_user *user)
-{
- fstring architecture;
- fstring new_name;
- char *p;
- int i;
- uint32 err;
-
- /* clean up the driver name.
- * we can get .\driver.dll
- * or worse c:\windows\system\driver.dll !
- */
- /* using an intermediate string to not have overlaping memcpy()'s */
- if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->driverpath, new_name);
- }
-
- if ((p = strrchr(driver->datafile,'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->datafile, new_name);
- }
-
- if ((p = strrchr(driver->configfile,'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->configfile, new_name);
- }
-
- if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->helpfile, new_name);
- }
-
- if (driver->dependentfiles) {
- for (i=0; *driver->dependentfiles[i]; i++) {
- if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
- fstrcpy(new_name, p+1);
- fstrcpy(driver->dependentfiles[i], new_name);
- }
- }
- }
-
- get_short_archi(architecture, driver->environment);
-
- /* jfm:7/16/2000 the client always sends the cversion=0.
- * The server should check which version the driver is by reading
- * the PE header of driver->driverpath.
- *
- * For Windows 95/98 the version is 0 (so the value sent is correct)
- * For Windows NT (the architecture doesn't matter)
- * NT 3.1: cversion=0
- * NT 3.5/3.51: cversion=1
- * NT 4: cversion=2
- * NT2K: cversion=3
- */
- if ((driver->version = get_correct_cversion(architecture,
- driver->driverpath, user, &err)) == -1)
- return err;
-
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
- uint32 level, struct current_user *user)
-{
- switch (level) {
- case 3:
- {
- NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
- driver=driver_abstract.info_3;
- return clean_up_driver_struct_level_3(driver, user);
- }
- case 6:
- {
- NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
- driver=driver_abstract.info_6;
- return clean_up_driver_struct_level_6(driver, user);
- }
- default:
- return ERROR_INVALID_PARAMETER;
- }
-}
-
-/****************************************************************************
- This function sucks and should be replaced. JRA.
-****************************************************************************/
-
-static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
-{
- dst->cversion = src->version;
-
- fstrcpy( dst->name, src->name);
- fstrcpy( dst->environment, src->environment);
- fstrcpy( dst->driverpath, src->driverpath);
- fstrcpy( dst->datafile, src->datafile);
- fstrcpy( dst->configfile, src->configfile);
- fstrcpy( dst->helpfile, src->helpfile);
- fstrcpy( dst->monitorname, src->monitorname);
- fstrcpy( dst->defaultdatatype, src->defaultdatatype);
- dst->dependentfiles = src->dependentfiles;
-}
-
-#if 0 /* Debugging function */
-
-static char* ffmt(unsigned char *c){
- int i;
- static char ffmt_str[17];
-
- for (i=0; i<16; i++) {
- if ((c[i] < ' ') || (c[i] > '~'))
- ffmt_str[i]='.';
- else
- ffmt_str[i]=c[i];
- }
- ffmt_str[16]='\0';
- return ffmt_str;
+ return True;
}
-#endif
-
/****************************************************************************
Version information in Microsoft files is held in a VS_VERSION_INFO structure.
There are two case to be covered here: PE (Portable Executable) and NE (New
@@ -1197,6 +920,327 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file,
}
/****************************************************************************
+Determine the correct cVersion associated with an architecture and driver
+****************************************************************************/
+static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
+ struct current_user *user, uint32 *perr)
+{
+ int cversion;
+ int access_mode;
+ int action;
+ int ecode;
+ pstring driverpath;
+ fstring user_name;
+ fstring null_pw;
+ files_struct *fsp = NULL;
+ BOOL bad_path;
+ SMB_STRUCT_STAT st;
+ struct passwd *pass;
+ connection_struct *conn;
+
+ ZERO_STRUCT(st);
+
+ /* If architecture is Windows 95/98/ME, the version is always 0. */
+ if (strcmp(architecture, "WIN40") == 0) {
+ DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
+ return 0;
+ }
+
+ become_root();
+ pass = sys_getpwuid(user->uid);
+ if(pass == NULL) {
+ DEBUG(0,("get_correct_cversion: Unable to get passwd entry for uid %u\n",
+ (unsigned int)user->uid ));
+ unbecome_root();
+ *perr = ERRnoaccess;
+ return -1;
+ }
+ unbecome_root();
+
+ /* connect to the print$ share under the same account as the user connected
+ * to the rpc pipe */
+ fstrcpy(user_name, pass->pw_name );
+ DEBUG(10,("get_correct_cversion: uid %d -> user %s\n", (int)user->uid, user_name));
+
+ /* Null password is ok - we are already an authenticated user... */
+ *null_pw = '\0';
+ conn = make_connection("print$", user_name, null_pw, 0, "A:", user->vuid, &ecode);
+
+ if (conn == NULL) {
+ DEBUG(0,("get_correct_cversion: Unable to connect\n"));
+ *perr = (uint32)ecode;
+ return -1;
+ }
+
+ /* Save who we are - we are temporarily becoming the connection user. */
+ push_sec_ctx();
+
+ if (!become_user(conn, conn->vuid)) {
+ DEBUG(0,("get_correct_cversion: Can't become user %s\n", user_name ));
+ *perr = ERRnoaccess;
+ pop_sec_ctx();
+ return -1;
+ }
+
+ /* Open the driver file (Portable Executable format) and determine the
+ * deriver the cversion. */
+ slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
+
+ unix_convert(driverpath,conn,NULL,&bad_path,&st);
+
+ fsp = open_file_shared(conn, driverpath, &st,
+ SET_OPEN_MODE(DOS_OPEN_RDONLY),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ 0, 0, &access_mode, &action);
+ if (!fsp) {
+ DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
+ driverpath, errno));
+ *perr = ERRnoaccess;
+ goto error_exit;
+ }
+ else {
+ uint32 major;
+ uint32 minor;
+ int ret = get_file_version(fsp, driverpath, &major, &minor);
+ if (ret == -1) goto error_exit;
+
+ if (!ret) {
+ DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
+ goto error_exit;
+ }
+
+ /*
+ * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
+ * for more details. Version in this case is not just the version of the
+ * file, but the version in the sense of kernal mode (2) vs. user mode
+ * (3) drivers. Other bits of the version fields are the version info.
+ * JRR 010716
+ */
+ cversion = major & 0x0000ffff;
+ switch (cversion) {
+ case 2: /* WinNT drivers */
+ case 3: /* Win2K drivers */
+ break;
+
+ default:
+ DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
+ driverpath, cversion));
+ goto error_exit;
+ }
+
+ DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
+ driverpath, major, minor));
+ }
+
+ DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
+ driverpath, cversion));
+
+ close_file(fsp, True);
+ close_cnum(conn, user->vuid);
+ pop_sec_ctx();
+ return cversion;
+
+
+ error_exit:
+ if(fsp)
+ close_file(fsp, True);
+
+ close_cnum(conn, user->vuid);
+ pop_sec_ctx();
+ return -1;
+}
+
+/****************************************************************************
+****************************************************************************/
+static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
+ struct current_user *user)
+{
+ fstring architecture;
+ fstring new_name;
+ char *p;
+ int i;
+ uint32 err;
+
+ /* clean up the driver name.
+ * we can get .\driver.dll
+ * or worse c:\windows\system\driver.dll !
+ */
+ /* using an intermediate string to not have overlaping memcpy()'s */
+ if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->driverpath, new_name);
+ }
+
+ if ((p = strrchr(driver->datafile,'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->datafile, new_name);
+ }
+
+ if ((p = strrchr(driver->configfile,'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->configfile, new_name);
+ }
+
+ if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->helpfile, new_name);
+ }
+
+ if (driver->dependentfiles) {
+ for (i=0; *driver->dependentfiles[i]; i++) {
+ if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->dependentfiles[i], new_name);
+ }
+ }
+ }
+
+ get_short_archi(architecture, driver->environment);
+
+ /* jfm:7/16/2000 the client always sends the cversion=0.
+ * The server should check which version the driver is by reading
+ * the PE header of driver->driverpath.
+ *
+ * For Windows 95/98 the version is 0 (so the value sent is correct)
+ * For Windows NT (the architecture doesn't matter)
+ * NT 3.1: cversion=0
+ * NT 3.5/3.51: cversion=1
+ * NT 4: cversion=2
+ * NT2K: cversion=3
+ */
+ if ((driver->cversion = get_correct_cversion( architecture,
+ driver->driverpath, user, &err)) == -1)
+ return err;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver,
+ struct current_user *user)
+{
+ fstring architecture;
+ fstring new_name;
+ char *p;
+ int i;
+ uint32 err;
+
+ /* clean up the driver name.
+ * we can get .\driver.dll
+ * or worse c:\windows\system\driver.dll !
+ */
+ /* using an intermediate string to not have overlaping memcpy()'s */
+ if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->driverpath, new_name);
+ }
+
+ if ((p = strrchr(driver->datafile,'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->datafile, new_name);
+ }
+
+ if ((p = strrchr(driver->configfile,'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->configfile, new_name);
+ }
+
+ if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->helpfile, new_name);
+ }
+
+ if (driver->dependentfiles) {
+ for (i=0; *driver->dependentfiles[i]; i++) {
+ if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
+ fstrcpy(new_name, p+1);
+ fstrcpy(driver->dependentfiles[i], new_name);
+ }
+ }
+ }
+
+ get_short_archi(architecture, driver->environment);
+
+ /* jfm:7/16/2000 the client always sends the cversion=0.
+ * The server should check which version the driver is by reading
+ * the PE header of driver->driverpath.
+ *
+ * For Windows 95/98 the version is 0 (so the value sent is correct)
+ * For Windows NT (the architecture doesn't matter)
+ * NT 3.1: cversion=0
+ * NT 3.5/3.51: cversion=1
+ * NT 4: cversion=2
+ * NT2K: cversion=3
+ */
+ if ((driver->version = get_correct_cversion(architecture,
+ driver->driverpath, user, &err)) == -1)
+ return err;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+ uint32 level, struct current_user *user)
+{
+ switch (level) {
+ case 3:
+ {
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
+ driver=driver_abstract.info_3;
+ return clean_up_driver_struct_level_3(driver, user);
+ }
+ case 6:
+ {
+ NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
+ driver=driver_abstract.info_6;
+ return clean_up_driver_struct_level_6(driver, user);
+ }
+ default:
+ return ERRinvalidparam;
+ }
+}
+
+/****************************************************************************
+ This function sucks and should be replaced. JRA.
+****************************************************************************/
+
+static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
+{
+ dst->cversion = src->version;
+
+ fstrcpy( dst->name, src->name);
+ fstrcpy( dst->environment, src->environment);
+ fstrcpy( dst->driverpath, src->driverpath);
+ fstrcpy( dst->datafile, src->datafile);
+ fstrcpy( dst->configfile, src->configfile);
+ fstrcpy( dst->helpfile, src->helpfile);
+ fstrcpy( dst->monitorname, src->monitorname);
+ fstrcpy( dst->defaultdatatype, src->defaultdatatype);
+ dst->dependentfiles = src->dependentfiles;
+}
+
+#if 0 /* Debugging function */
+
+static char* ffmt(unsigned char *c){
+ int i;
+ static char ffmt_str[17];
+
+ for (i=0; i<16; i++) {
+ if ((c[i] < ' ') || (c[i] > '~'))
+ ffmt_str[i]='.';
+ else
+ ffmt_str[i]=c[i];
+ }
+ ffmt_str[16]='\0';
+ return ffmt_str;
+}
+
+#endif
+
+/****************************************************************************
****************************************************************************/
BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user, uint32 *perr)
{
@@ -1489,7 +1533,16 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
}
if (len != buflen) {
- buf = (char *)Realloc(buf, len);
+ char *tb;
+
+ tb = (char *)Realloc(buf, len);
+ if (!tb) {
+ DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
+ ret = -1;
+ goto done;
+ }
+ else
+ buf = tb;
buflen = len;
goto again;
}
@@ -1500,8 +1553,9 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
dbuf.dptr = buf;
dbuf.dsize = len;
- ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+ ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
+done:
if (ret)
DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
@@ -1548,7 +1602,7 @@ static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in
fstrcpy(info.helpfile, "");
if ((info.dependentfiles=(fstring *)malloc(2*sizeof(fstring))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
memset(info.dependentfiles, '\0', 2*sizeof(fstring));
fstrcpy(info.dependentfiles[0], "");
@@ -1580,7 +1634,7 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
- dbuf = tdb_fetch(tdb, kbuf);
+ dbuf = tdb_fetch(tdb_drivers, kbuf);
#if 0
if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
#else
@@ -1599,10 +1653,15 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
i=0;
while (len < dbuf.dsize) {
- driver.dependentfiles = (fstring *)Realloc(driver.dependentfiles,
- sizeof(fstring)*(i+2));
- if (driver.dependentfiles == NULL)
+ fstring *tddfs;
+
+ tddfs = (fstring *)Realloc(driver.dependentfiles, sizeof(fstring)*(i+2));
+ if (tddfs == NULL) {
+ DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
break;
+ }
+ else
+ driver.dependentfiles = tddfs;
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
&driver.dependentfiles[i]);
@@ -1640,7 +1699,7 @@ uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
- if (!tdb_exists(tdb, kbuf)) return False;
+ if (!tdb_exists(tdb_drivers, kbuf)) return False;
ZERO_STRUCT(info3);
get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
@@ -1831,7 +1890,7 @@ uint32 del_a_printer(char *sharename)
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
- tdb_delete(tdb, kbuf);
+ tdb_delete(tdb_printers, kbuf);
return 0;
}
@@ -1906,7 +1965,15 @@ static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
len += pack_specifics(info->specific, buf+len, buflen-len);
if (buflen != len) {
- buf = (char *)Realloc(buf, len);
+ char *tb;
+
+ tb = (char *)Realloc(buf, len);
+ if (!tb) {
+ DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
+ ret = -1;
+ goto done;
+ } else
+ buf = tb;
buflen = len;
goto again;
}
@@ -1920,8 +1987,9 @@ static uint32 update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
dbuf.dptr = buf;
dbuf.dsize = len;
- ret = tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+ ret = tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
+done:
if (ret == -1)
DEBUG(8, ("error updating printer to tdb on disk\n"));
@@ -2444,7 +2512,7 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
- dbuf = tdb_fetch(tdb, kbuf);
+ dbuf = tdb_fetch(tdb_printers, kbuf);
if (!dbuf.dptr)
return get_a_printer_2_default(info_ptr, sharename);
@@ -2653,6 +2721,316 @@ uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
}
/****************************************************************************
+ Initialize printer devmode & data with previously saved driver init values.
+****************************************************************************/
+static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr)
+{
+ int len = 0;
+ pstring key;
+ TDB_DATA kbuf, dbuf;
+ NT_PRINTER_PARAM *current;
+ NT_PRINTER_INFO_LEVEL_2 info;
+
+ ZERO_STRUCT(info);
+
+ slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
+ dos_to_unix(key, True); /* Convert key to unix-codepage */
+
+ kbuf.dptr = key;
+ kbuf.dsize = strlen(key)+1;
+
+ dbuf = tdb_fetch(tdb_drivers, kbuf);
+ if (!dbuf.dptr)
+ return False;
+
+ /*
+ * Get the saved DEVMODE..
+ */
+ len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
+
+ /*
+ * The saved DEVMODE contains the devicename from the printer used during
+ * the initialization save. Change it to reflect the new printer.
+ */
+ ZERO_STRUCT(info.devmode->devicename);
+ fstrcpy(info.devmode->devicename, info_ptr->printername);
+
+ /*
+ * Bind the saved DEVMODE to the new the printer.
+ */
+ free_nt_devicemode(&info_ptr->devmode);
+ info_ptr->devmode = info.devmode;
+
+ DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n",
+ info_ptr->printername, info_ptr->drivername));
+
+ /*
+ * There should not be any printer data 'specifics' already set during the
+ * add printer operation, if there are delete them.
+ */
+ while ( (current=info_ptr->specific) != NULL ) {
+ info_ptr->specific=current->next;
+ safe_free(current->data);
+ safe_free(current);
+ }
+
+ /*
+ * Add the printer data 'specifics' to the new printer
+ */
+ len += unpack_specifics(&info_ptr->specific,dbuf.dptr+len, dbuf.dsize-len);
+
+ safe_free(dbuf.dptr);
+
+ return True;
+}
+
+/****************************************************************************
+ Initialize printer devmode & data with previously saved driver init values.
+ When a printer is created using AddPrinter, the drivername bound to the
+ printer is used to lookup previously saved driver initialization info, which
+ is bound to the new printer.
+****************************************************************************/
+
+uint32 set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
+{
+ uint32 result;
+
+ switch (level)
+ {
+ case 2:
+ {
+ result=set_driver_init_2(printer->info_2);
+ break;
+ }
+ default:
+ result=1;
+ break;
+ }
+
+ return result;
+}
+
+/****************************************************************************
+ Pack up the DEVMODE and specifics for a printer into a 'driver init' entry
+ in the tdb. Note: this is different from the driver entry and the printer
+ entry. There should be a single driver init entry for each driver regardless
+ of whether it was installed from NT or 2K. Technically, they should be
+ different, but they work out to the same struct.
+****************************************************************************/
+static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
+{
+ pstring key;
+ char *buf;
+ int buflen, len, ret;
+ TDB_DATA kbuf, dbuf;
+
+ buf = NULL;
+ buflen = 0;
+
+ again:
+ len = 0;
+ len += pack_devicemode(info->devmode, buf+len, buflen-len);
+
+ len += pack_specifics(info->specific, buf+len, buflen-len);
+
+ if (buflen != len) {
+ char *tb;
+
+ tb = (char *)Realloc(buf, len);
+ if (!tb) {
+ DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
+ ret = -1;
+ goto done;
+ }
+ else
+ buf = tb;
+ buflen = len;
+ goto again;
+ }
+
+ slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
+ dos_to_unix(key, True); /* Convert key to unix-codepage */
+
+ kbuf.dptr = key;
+ kbuf.dsize = strlen(key)+1;
+ dbuf.dptr = buf;
+ dbuf.dsize = len;
+
+ ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
+
+done:
+ if (ret == -1)
+ DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
+
+ safe_free(buf);
+
+ DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & specifics for driver [%s]\n",
+ info->sharename, info->drivername));
+
+ return ret;
+}
+
+/****************************************************************************
+ Update (i.e. save) the driver init info (DEVMODE and specifics) for a printer
+****************************************************************************/
+
+static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level)
+{
+ uint32 result;
+
+ dump_a_printer(printer, level);
+
+ switch (level)
+ {
+ case 2:
+ {
+ result=update_driver_init_2(printer.info_2);
+ break;
+ }
+ default:
+ result=1;
+ break;
+ }
+
+ return result;
+}
+
+/****************************************************************************
+ Convert the printer data value, a REG_BINARY array, into an initialization
+ DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
+ got to keep the endians happy :).
+****************************************************************************/
+
+static BOOL convert_driver_init(NT_PRINTER_PARAM *param, TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode)
+{
+ BOOL result = False;
+ prs_struct ps;
+ DEVICEMODE devmode;
+
+ ZERO_STRUCT(devmode);
+
+ prs_init(&ps, 0, ctx, UNMARSHALL);
+ ps.data_p = (char *)param->data;
+ ps.buffer_size = param->data_len;
+
+ if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
+ result = convert_devicemode("", &devmode, &nt_devmode);
+ else
+ DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
+
+ return result;
+}
+
+/****************************************************************************
+ Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
+
+ 1. Use the driver's config DLL to this UNC printername and:
+ a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
+ b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
+ 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
+
+ The last step triggers saving the "driver initialization" information for
+ this printer into the tdb. Later, new printers that use this driver will
+ have this initialization information bound to them. This simulates the
+ driver initialization, as if it had run on the Samba server (as it would
+ have done on NT).
+
+ The Win32 client side code requirement sucks! But until we can run arbitrary
+ Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
+
+ It would have been easier to use SetPrinter because all the UNMARSHALLING of
+ the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
+ about it and you will realize why. JRR 010720
+****************************************************************************/
+
+static uint32 save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, NT_PRINTER_PARAM *param)
+{
+ uint32 status = ERRsuccess;
+ TALLOC_CTX *ctx = NULL;
+ NT_DEVICEMODE *nt_devmode = NULL;
+ NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
+
+ /*
+ * Set devmode on printer info, so entire printer initialization can be
+ * saved to tdb.
+ */
+ if ((ctx = talloc_init()) == NULL)
+ return ERRnomem;
+
+ if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
+ status = ERRnomem;
+ goto done;
+ }
+
+ ZERO_STRUCTP(nt_devmode);
+
+ /*
+ * The DEVMODE is held in the 'data' component of the param in raw binary.
+ * Convert it to to a devmode structure
+ */
+ if (!convert_driver_init(param, ctx, nt_devmode)) {
+ DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
+ status = ERRinvalidparam;
+ goto done;
+ }
+
+ /*
+ * Pack up and add (or update) the DEVMODE and any current printer data to
+ * a 'driver init' element in the tdb
+ *
+ */
+ printer->info_2->devmode = nt_devmode;
+ if (update_driver_init(*printer, 2)!=0) {
+ DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
+ status = ERRnomem;
+ goto done;
+ }
+
+ /*
+ * If driver initialization info was successfully saved, set the current
+ * printer to match it. This allows initialization of the current printer
+ * as well as the driver.
+ */
+ if (mod_a_printer(*printer, 2)!=0) {
+ DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
+ printer->info_2->printername));
+ status = ERRinvalidparam;
+ }
+
+ done:
+ talloc_destroy(ctx);
+ if (nt_devmode)
+ safe_free(nt_devmode->private);
+ safe_free(nt_devmode);
+ printer->info_2->devmode = tmp_devmode;
+
+ return status;
+}
+
+/****************************************************************************
+ Update the driver init info (DEVMODE and specifics) for a printer
+****************************************************************************/
+
+uint32 save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, NT_PRINTER_PARAM *param)
+{
+ uint32 status = ERRsuccess;
+
+ switch (level)
+ {
+ case 2:
+ {
+ status=save_driver_init_2(printer, param);
+ break;
+ }
+ default:
+ status=ERRunknownlevel;
+ break;
+ }
+
+ return status;
+}
+
+/****************************************************************************
Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
****************************************************************************/
@@ -2845,17 +3223,18 @@ BOOL printer_driver_in_use (char *arch, char *driver)
NT_PRINTER_INFO_LEVEL_2 info;
int ret;
- if (!tdb)
- nt_printing_init();
+ if (!tdb_printers)
+ if (!nt_printing_init())
+ return False;
DEBUG(5,("printer_driver_in_use: Beginning search through printers.tdb...\n"));
/* loop through the printers.tdb and check for the drivername */
- for (kbuf = tdb_firstkey(tdb); kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
+ for (kbuf = tdb_firstkey(tdb_printers); kbuf.dptr;
+ newkey = tdb_nextkey(tdb_printers, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
{
- dbuf = tdb_fetch(tdb, kbuf);
+ dbuf = tdb_fetch(tdb_printers, kbuf);
if (!dbuf.dptr)
continue;
@@ -2931,7 +3310,7 @@ uint32 delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
- if (tdb_delete(tdb, kbuf) == -1) {
+ if (tdb_delete(tdb_drivers, kbuf) == -1) {
DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
return NT_STATUS_ACCESS_VIOLATION;
}
@@ -2939,7 +3318,7 @@ uint32 delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i)
DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
i->name));
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/****************************************************************************
****************************************************************************/
@@ -3086,17 +3465,17 @@ uint32 nt_printing_setsec(char *printername, SEC_DESC_BUF *secdesc_ctr)
if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
&ps, 1)) {
- status = ERROR_INVALID_FUNCTION;
+ status = ERRbadfunc;
goto out;
}
slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
- if (tdb_prs_store(tdb, key, &ps)==0) {
+ if (tdb_prs_store(tdb_printers, key, &ps)==0) {
status = 0;
} else {
DEBUG(1,("Failed to store secdesc for %s\n", printername));
- status = ERROR_INVALID_FUNCTION;
+ status = ERRbadfunc;
}
/* Free malloc'ed memory */
@@ -3203,7 +3582,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, char *printername, SEC_DESC_BUF **secde
slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
- if (tdb_prs_fetch(tdb, key, &ps, ctx)!=0 ||
+ if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
!sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
DEBUG(4,("using default secdesc for %s\n", printername));
@@ -3355,7 +3734,8 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
/* If user is NULL then use the current_user structure */
- if (!user) user = &current_user;
+ if (!user)
+ user = &current_user;
/* Always allow root or printer admins to do anything */
@@ -3404,7 +3784,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
map_printer_permissions(secdesc->sec);
- result = se_access_check(secdesc->sec, user, access_type,
+ result = se_access_check(secdesc->sec, user->nt_user_token, access_type,
&access_granted, &status);
DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
@@ -3467,7 +3847,7 @@ uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul
return 0;
if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
/*
* Just ignore it if we already have a devmode.
@@ -3485,15 +3865,15 @@ uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul
if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
PRINTER_ACCESS_ADMINISTER) {
DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
- result = ERROR_ACCESS_DENIED;
+ result = ERRnoaccess;
goto done;
}
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
lp_servicename(snum) ));
- result = ERROR_ACCESS_DENIED;
- /*result = NT_STATUS_NO_PROBLEMO;*/
+ result = ERRnoaccess;
+ /*result = NT_STATUS_OK;*/
goto done;
}
@@ -3506,7 +3886,7 @@ uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul
if (!convert_devicemode(printer->info_2->printername,
printer_default->devmode_cont.devmode,
&printer->info_2->devmode)) {
- result = ERROR_NOT_ENOUGH_MEMORY;
+ result = ERRnomem;
goto done;
}
@@ -3515,7 +3895,7 @@ uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul
*/
if (add_a_printer(*printer, 2)!=0) {
- result = ERROR_ACCESS_DENIED;
+ result = ERRnoaccess;
goto done;
}
diff --git a/source/printing/pcap.c b/source/printing/pcap.c
index e9c2e460906..cead9f919e9 100644
--- a/source/printing/pcap.c
+++ b/source/printing/pcap.c
@@ -270,10 +270,10 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
return(False);
}
-#ifdef HAVE_LIBCUPS
+#ifdef HAVE_CUPS
if (strequal(psz, "cups"))
return (cups_printername_ok(pszPrintername));
-#endif /* HAVE_LIBCUPS */
+#endif /* HAVE_CUPS */
#ifdef SYSV
if (strequal(psz, "lpstat"))
@@ -346,12 +346,12 @@ void pcap_printer_fn(void (*fn)(char *, char *))
return;
}
-#ifdef HAVE_LIBCUPS
+#ifdef HAVE_CUPS
if (strequal(psz, "cups")) {
cups_printer_fn(fn);
return;
}
-#endif /* HAVE_LIBCUPS */
+#endif /* HAVE_CUPS */
#ifdef SYSV
if (strequal(psz, "lpstat")) {
diff --git a/source/printing/print_cups.c b/source/printing/print_cups.c
index 3ca0af537f9..565caff30ac 100644
--- a/source/printing/print_cups.c
+++ b/source/printing/print_cups.c
@@ -21,7 +21,7 @@
#include "printing.h"
#include "smb.h"
-#ifdef HAVE_LIBCUPS
+#ifdef HAVE_CUPS
#include <cups/cups.h>
#include <cups/language.h>
@@ -365,7 +365,7 @@ cups_job_delete(int snum, struct printjob *pjob)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, cupsUser());
+ NULL, pjob->user);
/*
* Do the request and get back a response...
@@ -455,7 +455,7 @@ cups_job_pause(int snum, struct printjob *pjob)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, cupsUser());
+ NULL, pjob->user);
/*
* Do the request and get back a response...
@@ -545,7 +545,7 @@ cups_job_resume(int snum, struct printjob *pjob)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, cupsUser());
+ NULL, pjob->user);
/*
* Do the request and get back a response...
@@ -638,7 +638,7 @@ cups_job_submit(int snum, struct printjob *pjob)
"printer-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, cupsUser());
+ NULL, pjob->user);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
pjob->jobname);
@@ -818,17 +818,16 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
{
qalloc += 16;
- if (qalloc == 16)
- temp = malloc(sizeof(print_queue_struct) * qalloc);
- else
- temp = realloc(queue, sizeof(print_queue_struct) * qalloc);
+ temp = Realloc(queue, sizeof(print_queue_struct) * qalloc);
if (temp == NULL)
{
+ DEBUG(0,("cups_queue_get: Not enough memory!"));
ippDelete(response);
httpClose(http);
- return (qcount);
+ free (queue);
+ return (0);
}
queue = temp;
@@ -959,6 +958,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
ippErrorString(cupsLastError())));
httpClose(http);
+ *q = queue;
return (qcount);
}
@@ -968,7 +968,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
ippErrorString(response->request.status.status_code)));
ippDelete(response);
httpClose(http);
-
+ *q = queue;
return (qcount);
}
@@ -1008,6 +1008,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
static int
cups_queue_pause(int snum)
{
+ extern userdom_struct current_user_info;
int ret; /* Return value */
http_t *http; /* HTTP connection to server */
ipp_t *request, /* IPP Request */
@@ -1018,15 +1019,15 @@ cups_queue_pause(int snum)
DEBUG(5,("cups_queue_pause(%d)\n", snum));
- /*
- * Make sure we don't ask for passwords...
- */
+ /*
+ * Make sure we don't ask for passwords...
+ */
cupsSetPasswordCB(cups_passwd_cb);
- /*
- * Try to connect to the server...
- */
+ /*
+ * Try to connect to the server...
+ */
if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
{
@@ -1035,15 +1036,15 @@ cups_queue_pause(int snum)
return (1);
}
- /*
- * Build an IPP_PAUSE_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- */
+ /*
+ * Build an IPP_PAUSE_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requesting-user-name
+ */
request = ippNew();
@@ -1064,7 +1065,7 @@ cups_queue_pause(int snum)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, cupsUser());
+ NULL, current_user_info.unix_name);
/*
* Do the request and get back a response...
@@ -1072,7 +1073,7 @@ cups_queue_pause(int snum)
ret = 1;
- if ((response = cupsDoRequest(http, request, "/admin")) != NULL)
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
{
if (response->request.status.status_code >= IPP_OK_CONFLICT)
DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
@@ -1099,6 +1100,7 @@ cups_queue_pause(int snum)
static int
cups_queue_resume(int snum)
{
+ extern userdom_struct current_user_info;
int ret; /* Return value */
http_t *http; /* HTTP connection to server */
ipp_t *request, /* IPP Request */
@@ -1109,9 +1111,9 @@ cups_queue_resume(int snum)
DEBUG(5,("cups_queue_resume(%d)\n", snum));
- /*
- * Make sure we don't ask for passwords...
- */
+ /*
+ * Make sure we don't ask for passwords...
+ */
cupsSetPasswordCB(cups_passwd_cb);
@@ -1155,15 +1157,15 @@ cups_queue_resume(int snum)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, cupsUser());
+ NULL, current_user_info.unix_name);
- /*
- * Do the request and get back a response...
- */
+ /*
+ * Do the request and get back a response...
+ */
ret = 1;
- if ((response = cupsDoRequest(http, request, "/admin")) != NULL)
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
{
if (response->request.status.status_code >= IPP_OK_CONFLICT)
DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
@@ -1186,4 +1188,4 @@ cups_queue_resume(int snum)
#else
/* this keeps fussy compilers happy */
void print_cups_dummy(void) {}
-#endif /* HAVE_LIBCUPS */
+#endif /* HAVE_CUPS */
diff --git a/source/printing/print_svid.c b/source/printing/print_svid.c
index 58a1d03f498..5d81843b87b 100644
--- a/source/printing/print_svid.c
+++ b/source/printing/print_svid.c
@@ -71,6 +71,19 @@ static void populate_printers(void)
tmp=strchr(tmp, ' ');
tmp++;
}
+
+ /* Eat whitespace. */
+
+ while(*tmp == ' ')
+ ++tmp;
+
+ /*
+ * On HPUX there is an extra line that can be ignored.
+ * d.thibadeau 2001/08/09
+ */
+ if(!strncmp("remote to",tmp,9))
+ continue;
+
name = tmp;
/* truncate the ": ..." */
diff --git a/source/printing/printing.c b/source/printing/printing.c
index aab4c2f43f3..19d6aa2f70c 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -55,7 +55,7 @@ BOOL print_backend_init(void)
char *sversion = "INFO/version";
if (tdb && local_pid == sys_getpid()) return True;
- tdb = tdb_open_log(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
+ tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb) {
DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n",
tdb_errorstr(tdb)));
@@ -72,10 +72,10 @@ BOOL print_backend_init(void)
tdb_unlock_bystring(tdb, sversion);
/* select the appropriate printing interface... */
-#ifdef HAVE_LIBCUPS
+#ifdef HAVE_CUPS
if (strcmp(lp_printcapname(), "cups") == 0)
current_printif = &cups_printif;
-#endif /* HAVE_LIBCUPS */
+#endif /* HAVE_CUPS */
/* do NT print initialization... */
return nt_printing_init();
@@ -623,7 +623,7 @@ BOOL print_job_delete(struct current_user *user, int jobid, int *errcode)
if (!owner &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("delete denied by security descriptor\n"));
- *errcode = ERROR_ACCESS_DENIED;
+ *errcode = ERRnoaccess;
return False;
}
@@ -662,7 +662,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode)
if (!is_owner(user, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("pause denied by security descriptor\n"));
- *errcode = ERROR_ACCESS_DENIED;
+ *errcode = ERRnoaccess;
return False;
}
@@ -670,7 +670,7 @@ BOOL print_job_pause(struct current_user *user, int jobid, int *errcode)
ret = (*(current_printif->job_pause))(snum, pjob);
if (ret != 0) {
- *errcode = ERROR_INVALID_PARAMETER;
+ *errcode = ERRinvalidparam;
return False;
}
@@ -706,14 +706,14 @@ BOOL print_job_resume(struct current_user *user, int jobid, int *errcode)
if (!is_owner(user, jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("resume denied by security descriptor\n"));
- *errcode = ERROR_ACCESS_DENIED;
+ *errcode = ERRnoaccess;
return False;
}
ret = (*(current_printif->job_resume))(snum, pjob);
if (ret != 0) {
- *errcode = ERROR_INVALID_PARAMETER;
+ *errcode = ERRinvalidparam;
return False;
}
@@ -916,8 +916,8 @@ int print_job_start(struct current_user *user, int snum, char *jobname)
tdb_store_int(tdb, "INFO/nextjob", jobid);
/* we have a job entry - now create the spool file */
- slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%sXXXXXX",
- path, PRINT_SPOOL_PREFIX);
+ slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX",
+ path, PRINT_SPOOL_PREFIX, jobid);
pjob.fd = smb_mkstemp(pjob.filename);
if (pjob.fd == -1) {
@@ -1199,14 +1199,14 @@ BOOL print_queue_pause(struct current_user *user, int snum, int *errcode)
int ret;
if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
- *errcode = ERROR_ACCESS_DENIED;
+ *errcode = ERRnoaccess;
return False;
}
ret = (*(current_printif->queue_pause))(snum);
if (ret != 0) {
- *errcode = ERROR_INVALID_PARAMETER;
+ *errcode = ERRinvalidparam;
return False;
}
@@ -1231,14 +1231,14 @@ BOOL print_queue_resume(struct current_user *user, int snum, int *errcode)
int ret;
if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
- *errcode = ERROR_ACCESS_DENIED;
+ *errcode = ERRnoaccess;
return False;
}
ret = (*(current_printif->queue_resume))(snum);
if (ret != 0) {
- *errcode = ERROR_INVALID_PARAMETER;
+ *errcode = ERRinvalidparam;
return False;
}
diff --git a/source/profile/profile.c b/source/profile/profile.c
index 20ad8531d88..430732c6f86 100644
--- a/source/profile/profile.c
+++ b/source/profile/profile.c
@@ -130,10 +130,12 @@ BOOL profile_setup(BOOL rdonly)
return False;
}
+#if 0
if (shm_ds.shm_perm.cuid != 0 || shm_ds.shm_perm.cgid != 0) {
DEBUG(0,("ERROR: root did not create the shmem\n"));
return False;
}
+#endif
if (shm_ds.shm_segsz != sizeof(*profile_h)) {
DEBUG(0,("WARNING: profile size is %d (expected %d). Deleting\n",
diff --git a/source/rpc_client/cli_login.c b/source/rpc_client/cli_login.c
index aaf4fe17aa1..40d6464c56d 100644
--- a/source/rpc_client/cli_login.c
+++ b/source/rpc_client/cli_login.c
@@ -66,7 +66,8 @@ BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
* Receive an auth-2 challenge response and check it.
*/
- if (!cli_net_auth2(cli, SEC_CHAN_WKSTA, 0x000001ff, &srv_chal))
+ if (!cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, &srv_chal))
{
DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n"));
return False;
diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c
index f6424f4d1a1..29c6da172e3 100644
--- a/source/rpc_client/cli_lsarpc.c
+++ b/source/rpc_client/cli_lsarpc.c
@@ -475,7 +475,7 @@ uint32 lsa_lookup_sids(POLICY_HND *hnd, int num_sids, DOM_SID *sids,
return r_l.status;
}
- result = NT_STATUS_NOPROBLEMO;
+ result = NT_STATUS_OK;
if (p) {
if (t_names.ptr_trans_names != 0
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index 9c1f7299ea8..5f58f16d498 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -450,7 +450,7 @@ BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, NET_USER_INF
ret_err_code = cli_net_sam_logon_internal(cli, ctr, user_info3, validation_level);
- if(ret_err_code == NT_STATUS_NOPROBLEMO) {
+ if(ret_err_code == NT_STATUS_OK) {
DEBUG(10,("cli_net_sam_logon: Success \n"));
ok = True;
} else if (ret_err_code == NT_STATUS_INVALID_INFO_CLASS) {
@@ -550,221 +550,3 @@ password ?).\n", cli->desthost ));
return ok;
}
-
-/*********************************************************
- Change the domain password on the PDC.
-**********************************************************/
-
-static BOOL modify_trust_password( char *domain, char *remote_machine,
- unsigned char orig_trust_passwd_hash[16],
- unsigned char new_trust_passwd_hash[16])
-{
- struct cli_state cli;
-
- ZERO_STRUCT(cli);
- if(!cli_initialise(&cli)) {
- DEBUG(0,("modify_trust_password: unable to initialize client connection.\n"));
- return False;
- }
-
- if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
- DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- if (ismyip(cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: Machine %s is one of our addresses. Cannot add \
-to ourselves.\n", remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: unable to connect to SMB server on \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the NetBIOS \
-session request. Error was %s\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- cli.protocol = PROTOCOL_NT1;
-
- if (!cli_negprot(&cli)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the negotiate protocol. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- if (cli.protocol != PROTOCOL_NT1) {
- DEBUG(0,("modify_trust_password: machine %s didn't negotiate NT protocol.\n",
- remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- /*
- * Do an anonymous session setup.
- */
-
- if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
- DEBUG(0,("modify_trust_password: machine %s rejected the session setup. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!(cli.sec_mode & 1)) {
- DEBUG(0,("modify_trust_password: machine %s isn't in user level security mode\n",
- remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the tconX on the IPC$ share. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- /*
- * Ok - we have an anonymous connection to the IPC$ share.
- * Now start the NT Domain stuff :-).
- */
-
- if(cli_lsa_get_domain_sid(&cli, remote_machine) == False) {
- DEBUG(0,("modify_trust_password: unable to obtain domain sid from %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
- if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) {
- DEBUG(0,("modify_trust_password: unable to open the domain client session to \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
- if(cli_nt_setup_creds(&cli, orig_trust_passwd_hash) == False) {
- DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \
-%s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
- if( cli_nt_srv_pwset( &cli,new_trust_passwd_hash ) == False) {
- DEBUG(0,("modify_trust_password: unable to change password for machine %s in domain \
-%s to Domain controller %s. Error was %s.\n", global_myname, domain, remote_machine,
- cli_errstr(&cli)));
- cli_close(&cli, cli.nt_pipe_fnum);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
-
- return True;
-}
-
-/************************************************************************
- Change the trust account password for a domain.
- The user of this function must have locked the trust password file for
- update.
-************************************************************************/
-
-BOOL change_trust_account_password( char *domain, char *remote_machine_list)
-{
- fstring remote_machine;
- unsigned char old_trust_passwd_hash[16];
- unsigned char new_trust_passwd_hash[16];
- time_t lct;
- BOOL res = False;
-
- if(!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, &lct)) {
- DEBUG(0,("change_trust_account_password: unable to read the machine \
-account password for domain %s.\n", domain));
- return False;
- }
-
- /*
- * Create the new (random) password.
- */
- generate_random_buffer( new_trust_passwd_hash, 16, True);
-
- while(remote_machine_list &&
- next_token(&remote_machine_list, remote_machine,
- LIST_SEP, sizeof(remote_machine))) {
- strupper(remote_machine);
- if(strequal(remote_machine, "*")) {
-
- /*
- * We have been asked to dynamcially determine the IP addresses of the PDC.
- */
-
- struct in_addr *ip_list = NULL;
- int count = 0;
- int i;
-
- /* Use the PDC *only* for this. */
- if(!get_dc_list(True, domain, &ip_list, &count))
- continue;
-
- /*
- * Try and connect to the PDC/BDC list in turn as an IP
- * address used as a string.
- */
-
- for(i = 0; i < count; i++) {
- fstring dc_name;
- if(!lookup_pdc_name(global_myname, domain, &ip_list[i], dc_name))
- continue;
- if((res = modify_trust_password( domain, dc_name,
- old_trust_passwd_hash, new_trust_passwd_hash)))
- break;
- }
-
- if(ip_list != NULL)
- free((char *)ip_list);
-
- } else {
- res = modify_trust_password( domain, remote_machine,
- old_trust_passwd_hash, new_trust_passwd_hash);
- }
-
- if(res) {
- DEBUG(0,("%s : change_trust_account_password: Changed password for \
-domain %s.\n", timestring(False), domain));
- /*
- * Return the result of trying to write the new password
- * back into the trust account file.
- */
- res = secrets_store_trust_account_password(domain, new_trust_passwd_hash);
- memset(new_trust_passwd_hash, 0, 16);
- memset(old_trust_passwd_hash, 0, 16);
- return res;
- }
- }
-
- memset(new_trust_passwd_hash, 0, 16);
- memset(old_trust_passwd_hash, 0, 16);
-
- DEBUG(0,("%s : change_trust_account_password: Failed to change password for \
-domain %s.\n", timestring(False), domain));
- return False;
-}
diff --git a/source/rpc_parse/parse_creds.c b/source/rpc_parse/parse_creds.c
index 7bdbe658800..fcc8e59d100 100644
--- a/source/rpc_parse/parse_creds.c
+++ b/source/rpc_parse/parse_creds.c
@@ -52,7 +52,8 @@ reads or writes a structure.
********************************************************************/
BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "creds_io_unix");
depth++;
@@ -111,7 +112,8 @@ BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int dept
{
uint32 i;
- if (r_u == NULL) return False;
+ if (r_u == NULL)
+ return False;
prs_debug(ps, depth, desc, "creds_io_unix_sec");
depth++;
@@ -121,21 +123,21 @@ BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int dept
prs_uint32("uid", ps, depth, &(r_u->uid));
prs_uint32("gid", ps, depth, &(r_u->gid));
prs_uint32("num_grps", ps, depth, (uint32 *)&(r_u->num_grps));
- if (r_u->num_grps != 0)
- {
- r_u->grps = (uint32*)Realloc(r_u->grps,
- sizeof(r_u->grps[0]) *
- r_u->num_grps);
- if (r_u->grps == NULL)
- {
+ if (r_u->num_grps != 0) {
+ uint32 *tgr;
+
+ tgr = (uint32*)Realloc(r_u->grps,
+ sizeof(r_u->grps[0]) *
+ r_u->num_grps);
+ if (tgr == NULL) {
creds_free_unix_sec(r_u);
return False;
- }
+ } else
+ r_u->grps = tgr;
}
+
for (i = 0; i < r_u->num_grps; i++)
- {
prs_uint32("", ps, depth, &(r_u->grps[i]));
- }
return True;
}
@@ -197,16 +199,17 @@ BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth)
prs_align(ps);
prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
- if (r_u->num_grps != 0)
- {
- r_u->grp_rids = (uint32*)Realloc(r_u->grp_rids,
- sizeof(r_u->grp_rids[0]) *
- r_u->num_grps);
- if (r_u->grp_rids == NULL)
- {
+ if (r_u->num_grps != 0) {
+ uint32 *tgr;
+
+ tgr = (uint32*)Realloc(r_u->grp_rids,
+ sizeof(r_u->grp_rids[0]) *
+ r_u->num_grps);
+ if (tgr == NULL) {
creds_free_nt_sec(r_u);
return False;
- }
+ } else
+ r_u->grp_rids = tgr;
}
for (i = 0; i < r_u->num_grps; i++)
{
diff --git a/source/rpc_parse/parse_dfs.c b/source/rpc_parse/parse_dfs.c
index 6bae2ae4a6b..7e0959d2f35 100644
--- a/source/rpc_parse/parse_dfs.c
+++ b/source/rpc_parse/parse_dfs.c
@@ -112,8 +112,6 @@ BOOL dfs_io_q_dfs_remove(char *desc, DFS_Q_DFS_REMOVE *q_d, prs_struct *ps, int
if(q_d->ptr_ShareName)
if (!smb_io_unistr2("ShareName",&q_d->ShareName, q_d->ptr_ShareName, ps, depth))
return False;
- if(!prs_align(ps))
- return False;
return True;
}
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index 5abcfb9eef8..5128bb1dbbc 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -530,7 +530,7 @@ BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e,
Inits an LSA_R_ENUM_TRUST_DOM structure.
********************************************************************/
-void init_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
+void init_r_enum_trust_dom(TALLOC_CTX *ctx, LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
char *domain_name, DOM_SID *domain_sid,
uint32 status)
{
@@ -545,14 +545,14 @@ void init_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, uint32 enum_context,
r_e->ptr_enum_domains = 1;
r_e->num_domains2 = 1;
- if (!(r_e->hdr_domain_name = (UNIHDR2 *)
- malloc(sizeof(UNIHDR2)))) return;
+ if (!(r_e->hdr_domain_name = (UNIHDR2 *)talloc(ctx,sizeof(UNIHDR2))))
+ return;
- if (!(r_e->uni_domain_name = (UNISTR2 *)
- malloc(sizeof(UNISTR2)))) return;
+ if (!(r_e->uni_domain_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2))))
+ return;
- if (!(r_e->domain_sid = (DOM_SID2 *)
- malloc(sizeof(DOM_SID2)))) return;
+ if (!(r_e->domain_sid = (DOM_SID2 *)talloc(ctx,sizeof(DOM_SID2))))
+ return;
init_uni_hdr2(&r_e->hdr_domain_name[0], len_domain_name);
init_unistr2 (&r_e->uni_domain_name[0], domain_name,
diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c
index 4b118dd2b45..541738413a0 100644
--- a/source/rpc_parse/parse_misc.c
+++ b/source/rpc_parse/parse_misc.c
@@ -1238,6 +1238,7 @@ BOOL smb_io_cred(char *desc, DOM_CRED *cred, prs_struct *ps, int depth)
if(!smb_io_chal ("", &cred->challenge, ps, depth))
return False;
+
if(!smb_io_utime("", &cred->timestamp, ps, depth))
return False;
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index 587407b3dd3..a4964e4b422 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -1192,64 +1192,62 @@ static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int d
Init
*************************************************************************/
-void init_net_user_info3(TALLOC_CTX *ctx,
- NET_USER_INFO_3 *usr,
- NTTIME *logon_time,
- NTTIME *logoff_time,
- NTTIME *kickoff_time,
- NTTIME *pass_last_set_time,
- NTTIME *pass_can_change_time,
- NTTIME *pass_must_change_time,
-
- char *user_name,
- char *full_name,
- char *logon_script,
- char *profile_path,
- char *home_dir,
- char *dir_drive,
-
- uint16 logon_count,
- uint16 bad_pw_count,
-
- uint32 user_id,
- uint32 group_id,
- uint32 num_groups,
- DOM_GID *gids,
- uint32 user_flgs,
-
- char *sess_key,
-
- char *logon_srv,
- char *logon_dom,
-
- DOM_SID *dom_sid,
- char *other_sids)
+void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
+ uint16 logon_count, uint16 bad_pw_count,
+ uint32 num_groups, DOM_GID *gids,
+ uint32 user_flgs, char *sess_key,
+ char *logon_srv, char *logon_dom,
+ DOM_SID *dom_sid, char *other_sids)
{
/* only cope with one "other" sid, right now. */
/* need to count the number of space-delimited sids */
int i;
int num_other_sids = 0;
-
- int len_user_name = strlen(user_name );
- int len_full_name = strlen(full_name );
- int len_logon_script = strlen(logon_script);
- int len_profile_path = strlen(profile_path);
- int len_home_dir = strlen(home_dir );
- int len_dir_drive = strlen(dir_drive );
+
+ NTTIME logon_time, logoff_time, kickoff_time,
+ pass_last_set_time, pass_can_change_time,
+ pass_must_change_time;
+
+ int len_user_name, len_full_name, len_home_dir,
+ len_dir_drive, len_logon_script, len_profile_path;
+
+ char* user_name = pdb_get_username(sampw);
+ char* full_name = pdb_get_fullname(sampw);
+ char* home_dir = pdb_get_homedir(sampw);
+ char* dir_drive = pdb_get_dirdrive(sampw);
+ char* logon_script = pdb_get_logon_script(sampw);
+ char* profile_path = pdb_get_profile_path(sampw);
int len_logon_srv = strlen(logon_srv);
int len_logon_dom = strlen(logon_dom);
- memset(usr, '\0', sizeof(*usr));
+ len_user_name = strlen(user_name );
+ len_full_name = strlen(full_name );
+ len_home_dir = strlen(home_dir );
+ len_dir_drive = strlen(dir_drive );
+ len_logon_script = strlen(logon_script);
+ len_profile_path = strlen(profile_path);
+
+
+ ZERO_STRUCTP(usr);
usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
- usr->logon_time = *logon_time;
- usr->logoff_time = *logoff_time;
- usr->kickoff_time = *kickoff_time;
- usr->pass_last_set_time = *pass_last_set_time;
- usr->pass_can_change_time = *pass_can_change_time;
- usr->pass_must_change_time = *pass_must_change_time;
+
+ /* Create NTTIME structs */
+ unix_to_nt_time (&logon_time, pdb_get_logon_time(sampw));
+ unix_to_nt_time (&logoff_time, pdb_get_logoff_time(sampw));
+ unix_to_nt_time (&kickoff_time, pdb_get_kickoff_time(sampw));
+ unix_to_nt_time (&pass_last_set_time, pdb_get_pass_last_set_time(sampw));
+ unix_to_nt_time (&pass_can_change_time, pdb_get_pass_can_change_time(sampw));
+ unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_time(sampw));
+
+ usr->logon_time = logon_time;
+ usr->logoff_time = logoff_time;
+ usr->kickoff_time = kickoff_time;
+ usr->pass_last_set_time = pass_last_set_time;
+ usr->pass_can_change_time = pass_can_change_time;
+ usr->pass_must_change_time = pass_must_change_time;
init_uni_hdr(&usr->hdr_user_name, len_user_name);
init_uni_hdr(&usr->hdr_full_name, len_full_name);
@@ -1261,9 +1259,10 @@ void init_net_user_info3(TALLOC_CTX *ctx,
usr->logon_count = logon_count;
usr->bad_pw_count = bad_pw_count;
- usr->user_id = user_id;
- usr->group_id = group_id;
- usr->num_groups = num_groups;
+ usr->user_id = pdb_get_user_rid(sampw);
+ usr->group_id = pdb_get_group_rid(sampw);
+ usr->num_groups = num_groups+1;
+
usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
usr->user_flgs = user_flgs;
@@ -1291,15 +1290,20 @@ void init_net_user_info3(TALLOC_CTX *ctx,
init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
- usr->num_groups2 = num_groups;
+ /* always have at least one group == the user's primary group */
+ usr->num_groups2 = num_groups+1;
- if (num_groups > 0) {
- usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * num_groups);
- if (usr->gids == NULL)
- return;
- for (i = 0; i < num_groups; i++)
- usr->gids[i] = gids[i];
- }
+ usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * (num_groups+1));
+ if (usr->gids == NULL)
+ return;
+
+ /* primary group **MUST** go first. NT4's winmsd.exe will give
+ "The Network statistics are currently not available. 9-5"
+ What the heck is this? -- jerry */
+ usr->gids[0].g_rid = usr->group_id;
+ usr->gids[0].attr = 0x07;
+ for (i = 0; i < num_groups; i++)
+ usr->gids[i+1] = gids[i];
init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
@@ -1338,17 +1342,17 @@ static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
if (usr->ptr_user_info == 0)
return True;
- if(!smb_io_time("time", &usr->logon_time, ps, depth)) /* logon time */
+ if(!smb_io_time("logon time", &usr->logon_time, ps, depth)) /* logon time */
return False;
- if(!smb_io_time("time", &usr->logoff_time, ps, depth)) /* logoff time */
+ if(!smb_io_time("logoff time", &usr->logoff_time, ps, depth)) /* logoff time */
return False;
- if(!smb_io_time("time", &usr->kickoff_time, ps, depth)) /* kickoff time */
+ if(!smb_io_time("kickoff time", &usr->kickoff_time, ps, depth)) /* kickoff time */
return False;
- if(!smb_io_time("time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
+ if(!smb_io_time("last set time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
return False;
- if(!smb_io_time("time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
+ if(!smb_io_time("can change time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
return False;
- if(!smb_io_time("time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
+ if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
return False;
if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 0ad79b5f953..e0e61efffaa 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -1404,7 +1404,7 @@ uint32 init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 *num_ent
max_entries, max_data_size));
if (max_entries==0)
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
sam->sam=(SAM_ENTRY1 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY1));
if (!sam->sam)
@@ -1442,7 +1442,7 @@ uint32 init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 *num_ent
*num_entries = i;
*data_size = dsize;
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -1515,7 +1515,7 @@ uint32 init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 *num_ent
max_data_size = *data_size;
if (max_entries==0)
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
if (!(sam->sam=(SAM_ENTRY2 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY2))))
return NT_STATUS_NO_MEMORY;
@@ -1547,7 +1547,7 @@ uint32 init_sam_dispinfo_2(TALLOC_CTX *ctx, SAM_DISPINFO_2 *sam, uint32 *num_ent
*num_entries = i;
*data_size = dsize;
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -1622,7 +1622,7 @@ uint32 init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 *num_ent
max_data_size = *data_size;
if (max_entries==0)
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
if (!(sam->sam=(SAM_ENTRY3 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY3))))
return NT_STATUS_NO_MEMORY;
@@ -1650,7 +1650,7 @@ uint32 init_sam_dispinfo_3(TALLOC_CTX *ctx, SAM_DISPINFO_3 *sam, uint32 *num_ent
*num_entries = i;
*data_size = dsize;
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -1726,7 +1726,7 @@ uint32 init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 *num_ent
max_data_size = *data_size;
if (max_entries==0)
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
if (!(sam->sam=(SAM_ENTRY4 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY4))))
return NT_STATUS_NO_MEMORY;
@@ -1752,7 +1752,7 @@ uint32 init_sam_dispinfo_4(TALLOC_CTX *ctx, SAM_DISPINFO_4 *sam, uint32 *num_ent
*num_entries = i;
*data_size = dsize;
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -1828,7 +1828,7 @@ uint32 init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 *num_ent
max_data_size = *data_size;
if (max_entries==0)
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
if (!(sam->sam=(SAM_ENTRY5 *)talloc(ctx, max_entries*sizeof(SAM_ENTRY5))))
return NT_STATUS_NO_MEMORY;
@@ -1852,7 +1852,7 @@ uint32 init_sam_dispinfo_5(TALLOC_CTX *ctx, SAM_DISPINFO_5 *sam, uint32 *num_ent
*num_entries = i;
*data_size = dsize;
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -4461,7 +4461,7 @@ uint32 init_samr_q_lookup_names(TALLOC_CTX *ctx, SAMR_Q_LOOKUP_NAMES * q_u,
init_unistr2(&q_u->uni_name[i], name[i], len_name); /* unicode string for machine account */
}
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -4570,7 +4570,7 @@ uint32 init_samr_r_lookup_names(TALLOC_CTX *ctx, SAMR_R_LOOKUP_NAMES * r_u,
r_u->status = status;
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -5149,10 +5149,11 @@ static BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 * usr,
*************************************************************************/
-void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516])
+void init_sam_user_info24(SAM_USER_INFO_24 * usr, char newpass[516], uint16 pw_len)
{
DEBUG(10, ("init_sam_user_info24:\n"));
memcpy(usr->pass, newpass, sizeof(usr->pass));
+ usr->pw_len = pw_len;
}
/*******************************************************************
@@ -5174,6 +5175,10 @@ static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 * usr,
if(!prs_uint8s(False, "password", ps, depth, usr->pass, sizeof(usr->pass)))
return False;
+ if (MARSHALLING(ps) && (usr->pw_len != 0)) {
+ if (!prs_uint16("pw_len", ps, depth, &usr->pw_len))
+ return False;
+ }
if(!prs_align(ps))
return False;
@@ -5717,48 +5722,54 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
*************************************************************************/
-void init_sam_user_info21A(SAM_USER_INFO_21 * usr,
- NTTIME * logon_time,
- NTTIME * logoff_time,
- NTTIME * kickoff_time,
- NTTIME * pass_last_set_time,
- NTTIME * pass_can_change_time,
- NTTIME * pass_must_change_time,
- char *user_name,
- char *full_name,
- char *home_dir,
- char *dir_drive,
- char *log_scr,
- char *prof_path,
- char *desc,
- char *wkstas,
- char *unk_str,
- char *mung_dial,
- uint32 user_rid,
- uint32 group_rid,
- uint32 acb_info,
- uint32 unknown_3,
- uint16 logon_divs,
- LOGON_HRS * hrs,
- uint32 unknown_5, uint32 unknown_6)
-{
- int len_user_name = user_name != NULL ? strlen(user_name) : 0;
- int len_full_name = full_name != NULL ? strlen(full_name) : 0;
- int len_home_dir = home_dir != NULL ? strlen(home_dir) : 0;
- int len_dir_drive = dir_drive != NULL ? strlen(dir_drive) : 0;
- int len_logon_script = log_scr != NULL ? strlen(log_scr) : 0;
- int len_profile_path = prof_path != NULL ? strlen(prof_path) : 0;
- int len_description = desc != NULL ? strlen(desc) : 0;
- int len_workstations = wkstas != NULL ? strlen(wkstas) : 0;
- int len_unknown_str = unk_str != NULL ? strlen(unk_str) : 0;
- int len_munged_dial = mung_dial != NULL ? strlen(mung_dial) : 0;
-
- usr->logon_time = *logon_time;
- usr->logoff_time = *logoff_time;
- usr->kickoff_time = *kickoff_time;
- usr->pass_last_set_time = *pass_last_set_time;
- usr->pass_can_change_time = *pass_can_change_time;
- usr->pass_must_change_time = *pass_must_change_time;
+void init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw)
+{
+ NTTIME logon_time, logoff_time, kickoff_time,
+ pass_last_set_time, pass_can_change_time,
+ pass_must_change_time;
+
+ int len_user_name, len_full_name, len_home_dir,
+ len_dir_drive, len_logon_script, len_profile_path,
+ len_description, len_workstations, len_unknown_str,
+ len_munged_dial;
+
+ char* user_name = pdb_get_username(pw);
+ char* full_name = pdb_get_fullname(pw);
+ char* home_dir = pdb_get_homedir(pw);
+ char* dir_drive = pdb_get_dirdrive(pw);
+ char* logon_script = pdb_get_logon_script(pw);
+ char* profile_path = pdb_get_profile_path(pw);
+ char* description = pdb_get_acct_desc(pw);
+ char* workstations = pdb_get_workstations(pw);
+ char* munged_dial = pdb_get_munged_dial(pw);
+
+ len_user_name = user_name != NULL ? strlen(user_name )+1 : 0;
+ len_full_name = full_name != NULL ? strlen(full_name )+1 : 0;
+ len_home_dir = home_dir != NULL ? strlen(home_dir )+1 : 0;
+ len_dir_drive = dir_drive != NULL ? strlen(dir_drive )+1 : 0;
+ len_logon_script = logon_script != NULL ? strlen(logon_script)+1 : 0;
+ len_profile_path = profile_path != NULL ? strlen(profile_path)+1 : 0;
+ len_description = description != NULL ? strlen(description )+1 : 0;
+ len_workstations = workstations != NULL ? strlen(workstations)+1 : 0;
+ len_unknown_str = 0;
+ len_munged_dial = munged_dial != NULL ? strlen(munged_dial )+1 : 0;
+
+
+ /* Create NTTIME structs */
+ unix_to_nt_time (&logon_time, pdb_get_logon_time(pw));
+ unix_to_nt_time (&logoff_time, pdb_get_logoff_time(pw));
+ unix_to_nt_time (&kickoff_time, pdb_get_kickoff_time(pw));
+ unix_to_nt_time (&pass_last_set_time, pdb_get_pass_last_set_time(pw));
+ unix_to_nt_time (&pass_can_change_time, pdb_get_pass_can_change_time(pw));
+ unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_time(pw));
+
+ /* structure assignment */
+ usr->logon_time = logon_time;
+ usr->logoff_time = logoff_time;
+ usr->kickoff_time = kickoff_time;
+ usr->pass_last_set_time = pass_last_set_time;
+ usr->pass_can_change_time = pass_can_change_time;
+ usr->pass_must_change_time = pass_must_change_time;
init_uni_hdr(&usr->hdr_user_name, len_user_name);
init_uni_hdr(&usr->hdr_full_name, len_full_name);
@@ -5774,14 +5785,14 @@ void init_sam_user_info21A(SAM_USER_INFO_21 * usr,
ZERO_STRUCT(usr->nt_pwd);
ZERO_STRUCT(usr->lm_pwd);
- usr->user_rid = user_rid;
- usr->group_rid = group_rid;
- usr->acb_info = acb_info;
- usr->unknown_3 = unknown_3; /* 0x00ff ffff */
+ usr->user_rid = pdb_get_user_rid(pw);
+ usr->group_rid = pdb_get_group_rid(pw);
+ usr->acb_info = pdb_get_acct_ctrl(pw);
+ usr->unknown_3 = pdb_get_unknown3(pw);
- usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
- usr->ptr_logon_hrs = hrs ? 1 : 0;
- usr->unknown_5 = unknown_5; /* 0x0002 0000 */
+ usr->logon_divs = pdb_get_logon_divs(pw);
+ usr->ptr_logon_hrs = pdb_get_hours(pw) ? 1 : 0;
+ usr->unknown_5 = pdb_get_unknown5(pw); /* 0x0002 0000 */
ZERO_STRUCT(usr->padding1);
@@ -5789,17 +5800,21 @@ void init_sam_user_info21A(SAM_USER_INFO_21 * usr,
init_unistr2(&usr->uni_full_name, full_name, len_full_name);
init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
- init_unistr2(&usr->uni_logon_script, log_scr, len_logon_script);
- init_unistr2(&usr->uni_profile_path, prof_path, len_profile_path);
- init_unistr2(&usr->uni_acct_desc, desc, len_description);
- init_unistr2(&usr->uni_workstations, wkstas, len_workstations);
- init_unistr2(&usr->uni_unknown_str, unk_str, len_unknown_str);
- init_unistr2(&usr->uni_munged_dial, mung_dial, len_munged_dial);
-
- usr->unknown_6 = unknown_6; /* 0x0000 04ec */
+ init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
+ init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
+ init_unistr2(&usr->uni_acct_desc, description, len_description);
+ init_unistr2(&usr->uni_workstations, workstations, len_workstations);
+ init_unistr2(&usr->uni_unknown_str, NULL, len_unknown_str);
+ init_unistr2(&usr->uni_munged_dial, munged_dial, len_munged_dial);
+
+ usr->unknown_6 = pdb_get_unknown6(pw);
usr->padding4 = 0;
- memcpy(&usr->logon_hrs, hrs, sizeof(usr->logon_hrs));
+ if (pdb_get_hours(pw)) {
+ usr->logon_hrs.len = pdb_get_hours_len(pw);
+ memcpy(&usr->logon_hrs.hours, pdb_get_hours(pw), MAX_HOURS_LEN);
+ } else
+ memset(&usr->logon_hrs, 0xff, sizeof(usr->logon_hrs));
}
/*******************************************************************
@@ -5984,7 +5999,7 @@ uint32 make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
return NT_STATUS_INVALID_INFO_CLASS;
}
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c
index 2b81a7708c0..cbdd961066d 100644
--- a/source/rpc_parse/parse_spoolss.c
+++ b/source/rpc_parse/parse_spoolss.c
@@ -539,7 +539,7 @@ static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps,
* on reading allocate memory for the private member
********************************************************************/
-static BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
+BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
{
prs_debug(ps, depth, desc, "spoolss_io_devmode");
depth++;
@@ -1861,12 +1861,19 @@ static BOOL smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16
an extra NULL for termination */
if (l_chaine > 0)
{
+ uint16 *tc2;
+
realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
/* Yes this should be realloc - it's freed below. JRA */
- if((chaine2=(uint16 *)Realloc(chaine2, realloc_size)) == NULL)
+ if((tc2=(uint16 *)Realloc(chaine2, realloc_size)) == NULL) {
+ if (chaine2)
+ free(chaine2);
return False;
+ } else
+ chaine2 = tc2;
+
memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
l_chaine2+=l_chaine+1;
}
@@ -4703,7 +4710,7 @@ BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_
********************************************************************/
static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
{
- fstring f;
+ fstring f, *tar;
int n = 0;
char *src;
@@ -4715,7 +4722,11 @@ static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
unistr_to_dos(f, src, sizeof(f)-1);
src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
- *ar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
+ tar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
+ if (!tar)
+ return False;
+ else
+ *ar = tar;
fstrcpy((*ar)[n], f);
n++;
}
diff --git a/source/rpc_server/srv_dfs_nt.c b/source/rpc_server/srv_dfs_nt.c
index 54c3fbf324c..9bc12e2a965 100644
--- a/source/rpc_server/srv_dfs_nt.c
+++ b/source/rpc_server/srv_dfs_nt.c
@@ -56,7 +56,11 @@ uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
if (user.uid != 0) {
DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
- return ERROR_ACCESS_DENIED;
+
+ /* RPC calls return Windows errors. NT_STATUS_ACCESS_DENIED
+ doesn't work as a return code for RPC calls
+ */
+ return ERRnoaccess;
}
unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1);
@@ -70,10 +74,7 @@ uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
pstrcat(altpath, "\\");
pstrcat(altpath, sharename);
- if(!create_junction(dfspath, &jn))
- return NERR_DfsNoSuchServer;
-
- if(get_referred_path(&jn))
+ if(get_referred_path(dfspath, &jn, NULL, NULL))
{
exists = True;
jn.referral_count += 1;
@@ -106,7 +107,7 @@ uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u)
if(!create_msdfs_link(&jn, exists))
return NERR_DfsCantCreateJunctionPoint;
- return NT_STATUS_NOPROBLEMO;
+ return ERRsuccess;
}
uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u)
@@ -122,7 +123,10 @@ uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u
if (user.uid != 0) {
DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
- return ERROR_ACCESS_DENIED;
+ /* NT_STATUS_ACCESS_DENIED will not work as a status code
+ for RPC calls
+ */
+ return ERRnoaccess;
}
unistr2_to_ascii(dfspath, &q_u->DfsEntryPath, sizeof(dfspath)-1);
@@ -137,16 +141,14 @@ uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u
pstrcpy(altpath, servername);
pstrcat(altpath, "\\");
pstrcat(altpath, sharename);
+ strlower(altpath);
}
DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n",
dfspath, servername, sharename));
- if(!create_junction(dfspath, &jn))
- return NERR_DfsNoSuchServer;
-
- if(!get_referred_path(&jn))
- return NERR_DfsNoSuchVolume;
+ if(!get_referred_path(dfspath, &jn, NULL, NULL))
+ return NERR_DfsNoSuchVolume;
/* if no server-share pair given, remove the msdfs link completely */
if(!q_u->ptr_ServerName && !q_u->ptr_ShareName)
@@ -158,14 +160,18 @@ uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u
{
int i=0;
/* compare each referral in the list with the one to remove */
+ DEBUG(10,("altpath: .%s. refcnt: %d\n", altpath, jn.referral_count));
for(i=0;i<jn.referral_count;i++)
{
pstring refpath;
pstrcpy(refpath,jn.referral_list[i].alternate_path);
trim_string(refpath, "\\", "\\");
+ DEBUG(10,("_dfs_remove: refpath: .%s.\n", refpath));
if(strequal(refpath, altpath))
{
*(jn.referral_list[i].alternate_path)='\0';
+ DEBUG(10,("_dfs_remove: Removal request matches referral %s\n",
+ refpath));
found = True;
}
}
@@ -185,7 +191,7 @@ uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u
}
}
- return NT_STATUS_NOPROBLEMO;
+ return ERRsuccess;
}
static BOOL init_reply_dfs_info_1(struct junction_map* j, DFS_INFO_1* dfs1, int num_j)
@@ -227,8 +233,13 @@ static BOOL init_reply_dfs_info_3(TALLOC_CTX *ctx, struct junction_map* j, DFS_I
{
pstring str;
dfs3[i].ptr_entrypath = 1;
- slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname,
- j[i].service_name, j[i].volume_name);
+ if (j[i].volume_name[0] == '\0')
+ slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s",
+ global_myname, j[i].service_name);
+ else
+ slprintf(str, sizeof(pstring)-1, "\\\\%s\\%s\\%s", global_myname,
+ j[i].service_name, j[i].volume_name);
+
init_unistr2(&dfs3[i].entrypath, str, strlen(str)+1);
dfs3[i].ptr_comment = 1;
init_unistr2(&dfs3[i].comment, "", 1);
@@ -309,7 +320,7 @@ static uint32 init_reply_dfs_ctr(TALLOC_CTX *ctx, uint32 level, DFS_INFO_CTR* ct
default:
return NT_STATUS_INVALID_LEVEL;
}
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
uint32 _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u)
@@ -353,7 +364,7 @@ uint32 _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INF
if(!create_junction(path, &jn))
return NERR_DfsNoSuchServer;
- if(!get_referred_path(&jn))
+ if(!get_referred_path(path, &jn, NULL, NULL))
return NERR_DfsNoSuchVolume;
r_u->level = level;
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index afcace3f9c8..a14a479984b 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -176,7 +176,7 @@ static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
if (mapped_count == 0)
r_l->status = NT_STATUS_NONE_MAPPED;
else
- r_l->status = NT_STATUS_NO_PROBLEMO;
+ r_l->status = NT_STATUS_OK;
}
/***************************************************************************
@@ -276,7 +276,7 @@ static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
if (mapped_count == 0)
r_l->status = NT_STATUS_NONE_MAPPED;
else
- r_l->status = NT_STATUS_NO_PROBLEMO;
+ r_l->status = NT_STATUS_OK;
}
/***************************************************************************
@@ -291,7 +291,7 @@ uint32 _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL2
if (!create_policy_hnd(p, &r_u->pol, NULL, NULL))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/***************************************************************************
@@ -306,7 +306,7 @@ uint32 _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *r_
if (!create_policy_hnd(p, &r_u->pol, NULL, NULL))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/***************************************************************************
@@ -323,8 +323,8 @@ uint32 _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_ENU
return NT_STATUS_INVALID_HANDLE;
/* set up the LSA QUERY INFO response */
- init_r_enum_trust_dom(r_u, enum_context, dom_name, dom_sid,
- dom_name != NULL ? NT_STATUS_NO_PROBLEMO : NT_STATUS_UNABLE_TO_FREE_VM);
+ init_r_enum_trust_dom(p->mem_ctx, r_u, enum_context, dom_name, dom_sid,
+ dom_name != NULL ? NT_STATUS_OK : NT_STATUS_UNABLE_TO_FREE_VM);
return r_u->status;
}
@@ -341,7 +341,7 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO
char *name = NULL;
DOM_SID *sid = NULL;
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
if (!find_policy_by_hnd(p, &q_u->pol, NULL))
return NT_STATUS_INVALID_HANDLE;
@@ -434,7 +434,7 @@ uint32 _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INFO
break;
}
- if(r_u->status == NT_STATUS_NO_PROBLEMO) {
+ if(r_u->status == NT_STATUS_OK) {
r_u->undoc_buffer = 0x22000000; /* bizarre */
r_u->info_class = q_u->info_class;
}
@@ -508,7 +508,7 @@ uint32 _lsa_close(pipes_struct *p, LSA_Q_CLOSE *q_u, LSA_R_CLOSE *r_u)
return NT_STATUS_INVALID_HANDLE;
close_policy_hnd(p, &q_u->pol);
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/***************************************************************************
@@ -532,8 +532,8 @@ uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R
fstrcpy(username, vuser->user.smb_name);
fstrcpy(domname, vuser->user.domain);
- ulen = strlen(username);
- dlen = strlen(domname);
+ ulen = strlen(username) + 1;
+ dlen = strlen(domname) + 1;
init_uni_hdr(&r_u->hdr_user_name, ulen);
r_u->ptr_user_name = 1;
@@ -545,7 +545,7 @@ uint32 _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA_R
r_u->ptr_dom_name = 1;
init_unistr2(&r_u->uni2_dom_name, domname, dlen);
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
return r_u->status;
}
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c
index 5a7505869c5..62c49f5b89a 100644
--- a/source/rpc_server/srv_netlog_nt.c
+++ b/source/rpc_server/srv_netlog_nt.c
@@ -117,7 +117,9 @@ static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
static BOOL get_md4pw(char *md4pw, char *mach_acct)
{
- struct smb_passwd *smb_pass;
+ SAM_ACCOUNT *sampass = NULL;
+ uint8 *pass;
+ BOOL ret;
#if 0
/*
@@ -136,22 +138,29 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
return False;
}
#endif /* 0 */
+ if(!pdb_init_sam(&sampass))
+ return False;
/* JRA. This is ok as it is only used for generating the challenge. */
-
become_root();
- smb_pass = getsmbpwnam(mach_acct);
+ ret=pdb_getsampwnam(sampass, mach_acct);
unbecome_root();
- if ((smb_pass) != NULL && !(smb_pass->acct_ctrl & ACB_DISABLED) &&
- (smb_pass->smb_nt_passwd != NULL))
- {
- memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
- dump_data(5, md4pw, 16);
+ if (ret==False) {
+ DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
+ pdb_free_sam(sampass);
+ return False;
+ }
+ if (!(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) && ((pass=pdb_get_nt_passwd(sampass)) != NULL)) {
+ memcpy(md4pw, pass, 16);
+ dump_data(5, md4pw, 16);
+ pdb_free_sam(sampass);
return True;
}
+
DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
+ pdb_free_sam(sampass);
return False;
}
@@ -161,7 +170,7 @@ static BOOL get_md4pw(char *md4pw, char *mach_acct)
uint32 _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
fstring mach_acct;
if (!get_valid_user_struct(p->vuid))
@@ -220,7 +229,7 @@ static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, int status)
uint32 _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
DOM_CHAL srv_cred;
UTIME srv_time;
@@ -266,7 +275,7 @@ static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
DOM_CHAL srv_cred;
UTIME srv_time;
NEG_FLAGS srv_flgs;
@@ -303,11 +312,11 @@ uint32 _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u)
uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
DOM_CRED srv_cred;
pstring mach_acct;
- struct smb_passwd *smb_pass;
- BOOL ret;
+ SAM_ACCOUNT *sampass=NULL;
+ BOOL ret=False;
unsigned char pwd[16];
int i;
@@ -325,24 +334,33 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
pstrcpy(mach_acct, dos_unistrn2(q_u->clnt_id.login.uni_acct_name.buffer,
q_u->clnt_id.login.uni_acct_name.uni_str_len));
+ DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
+
+ pdb_init_sam(&sampass);
+
+ become_root();
+ ret=pdb_getsampwnam(sampass, mach_acct);
+ unbecome_root();
+
+ /* Ensure the account exists and is a machine account. */
+
+ if (ret==False || !(pdb_get_acct_ctrl(sampass) & ACB_WSTRUST)) {
+ pdb_free_sam(sampass);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+
/*
* Check the machine account name we're changing is the same
* as the one we've authenticated from. This prevents arbitrary
* machines changing other machine account passwords.
*/
- if (!strequal(mach_acct, p->dc.mach_acct))
+ if (!strequal(mach_acct, p->dc.mach_acct)) {
+ pdb_free_sam(sampass);
return NT_STATUS_ACCESS_DENIED;
+ }
- DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
-
- become_root();
- smb_pass = getsmbpwnam(mach_acct);
- unbecome_root();
-
- /* Ensure the account exists and is a machine account. */
- if (smb_pass == NULL || !(smb_pass->acct_ctrl & ACB_WSTRUST))
- return NT_STATUS_NO_SUCH_USER;
DEBUG(100,("Server password set : new given value was :\n"));
for(i = 0; i < 16; i++)
@@ -352,20 +370,27 @@ uint32 _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_
cred_hash3( pwd, q_u->pwd, p->dc.sess_key, 0);
/* lies! nt and lm passwords are _not_ the same: don't care */
- smb_pass->smb_passwd = pwd;
- smb_pass->smb_nt_passwd = pwd;
- smb_pass->acct_ctrl = ACB_WSTRUST;
-
+ if (!pdb_set_lanman_passwd (sampass, pwd)) {
+ pdb_free_sam(sampass);
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (!pdb_set_nt_passwd(sampass, pwd)) {
+ pdb_free_sam(sampass);
+ return NT_STATUS_NO_MEMORY;
+ }
+ pdb_set_acct_ctrl (sampass, ACB_WSTRUST);
+
become_root();
- ret = mod_smbpwd_entry(smb_pass,False);
+ ret = pdb_update_sam_account (sampass,False);
unbecome_root();
- if (!ret)
- status = NT_STATUS_WRONG_PASSWORD;
+ if (ret)
+ status = NT_STATUS_OK;
/* set up the LSA Server Password Set response */
init_net_r_srv_pwset(r_u, &srv_cred, status);
+ pdb_free_sam(sampass);
return r_u->status;
}
@@ -392,7 +417,7 @@ uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF
r_u->buffer_creds = 1; /* yes, we have valid server credentials */
memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
return r_u->status;
}
@@ -401,10 +426,9 @@ uint32 _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF
net_login_interactive:
*************************************************************************/
-static uint32 net_login_interactive(NET_ID_INFO_1 *id1, struct smb_passwd *smb_pass, pipes_struct *p)
+static uint32 net_login_interactive(NET_ID_INFO_1 *id1, SAM_ACCOUNT *sampass, pipes_struct *p)
{
- uint32 status = 0x0;
-
+ uint8 *stored_nt_pwd, *stored_lanman_pwd;
char nt_pwd[16];
char lm_pwd[16];
unsigned char key[16];
@@ -437,21 +461,42 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1, struct smb_passwd *smb_p
dump_data(100, nt_pwd, 16);
#endif
- if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 ||
- memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
- {
- status = NT_STATUS_WRONG_PASSWORD;
+ /* JRA. Check the NT password first if it exists - this is a higher quality
+ password, if it exists and it doesn't match - fail. */
+
+ stored_nt_pwd = pdb_get_nt_passwd(sampass);
+
+ if (stored_nt_pwd) {
+ if (memcmp(stored_nt_pwd, nt_pwd, 16) != 0) {
+ DEBUG(10,("net_login_interactive: NT password for user %s doesn't match.\n",
+ sampass->username));
+ return NT_STATUS_WRONG_PASSWORD;
+ } else
+ return NT_STATUS_OK;
}
- return status;
+ stored_lanman_pwd = pdb_get_lanman_passwd(sampass);
+
+ if (stored_lanman_pwd && lp_lanman_auth()) {
+ if (memcmp(stored_lanman_pwd, lm_pwd, 16) != 0) {
+ DEBUG(10,("net_login_interactive: lanman password for user %s doesn't match.\n",
+ sampass->username));
+ return NT_STATUS_WRONG_PASSWORD;
+ } else
+ return NT_STATUS_OK;
+ }
+
+ return NT_STATUS_WRONG_PASSWORD;
}
/*************************************************************************
_net_login_network:
*************************************************************************/
-static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
+static uint32 net_login_network(NET_ID_INFO_2 *id2, SAM_ACCOUNT *sampass)
{
+ uint8 *nt_pwd, *lanman_pwd;
+
DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
id2->hdr_lm_chal_resp.str_str_len,
id2->hdr_nt_chal_resp.str_str_len));
@@ -459,13 +504,12 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
/* JRA. Check the NT password first if it exists - this is a higher quality
password, if it exists and it doesn't match - fail. */
- if (id2->hdr_nt_chal_resp.str_str_len == 24 &&
- smb_pass->smb_nt_passwd != NULL)
- {
- if(smb_password_check((char *)id2->nt_chal_resp.buffer,
- smb_pass->smb_nt_passwd,
- id2->lm_chal))
- return NT_STATUS_NO_PROBLEMO;
+ nt_pwd = pdb_get_nt_passwd(sampass);
+ lanman_pwd = pdb_get_lanman_passwd(sampass);
+
+ if (id2->hdr_nt_chal_resp.str_str_len == 24 && nt_pwd != NULL) {
+ if(smb_password_check((char *)id2->nt_chal_resp.buffer, nt_pwd, id2->lm_chal))
+ return NT_STATUS_OK;
else
return NT_STATUS_WRONG_PASSWORD;
}
@@ -478,13 +522,11 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
not do, for various security-hole reasons).
*/
- if (lp_lanman_auth() &&
- id2->hdr_lm_chal_resp.str_str_len == 24 &&
+ if (lp_lanman_auth() && id2->hdr_lm_chal_resp.str_str_len == 24 &&
smb_password_check((char *)id2->lm_chal_resp.buffer,
- smb_pass->smb_passwd,
- id2->lm_chal))
+ lanman_pwd, id2->lm_chal))
{
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
@@ -499,13 +541,14 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
NET_USER_INFO_3 *usr_info = NULL;
DOM_CRED srv_cred;
- struct smb_passwd *smb_pass = NULL;
- struct sam_passwd *sam_pass = NULL;
+ SAM_ACCOUNT *sampass = NULL;
UNISTR2 *uni_samlogon_user = NULL;
fstring nt_username;
+ BOOL ret;
+ uint16 acct_ctrl;
usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3));
if (!usr_info)
@@ -560,92 +603,62 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
map_username(nt_username);
- /*
- * We previously called Get_Pwnam(ntusername, True) here which could
- * have modified the case of the username. Beaware of this
- * is the username case in smbpasswd does not match that in /etc/passwd
- * and domain logons begin to fail. -- jerry
- */
-
- /* XXXX hack to get standard_sub_basic() to use sam logon username */
- /* possibly a better way would be to do a become_user() call */
- sam_logon_in_ssb = True;
- pstrcpy(samlogon_user, nt_username);
-
+ /* get the account information */
+ pdb_init_sam(&sampass);
become_root();
- sam_pass = getsam21pwnam(nt_username);
+ ret = pdb_getsampwnam(sampass, nt_username);
unbecome_root();
- smb_pass = pdb_sam_to_smb(sam_pass);
- sam_logon_in_ssb = False;
-
- if ((smb_pass=pdb_sam_to_smb(sam_pass)) == NULL)
+ if (!ret)
return NT_STATUS_NO_SUCH_USER;
- else if (smb_pass->acct_ctrl & ACB_DISABLED)
- return NT_STATUS_ACCOUNT_DISABLED;
-
- /* Validate password - if required. */
-
- if (smb_pass->acct_ctrl & ACB_PWNOTREQ) {
- if (!lp_null_passwords()) {
- DEBUG(3,("Account for user %s has a null password and null passwords are NOT allowed",nt_username));
- return NT_STATUS_ACCOUNT_DISABLED;
- }
- }
-#ifdef WITH_PAM
- become_root();
-#if 0 /* JERRY */
- status = smb_pam_accountcheck(nt_username);
-#else
- status = smb_pam_accountcheck(sam_pass->smb_name);
-#endif
- unbecome_root();
- if (status != NT_STATUS_NOPROBLEMO)
- return status;
-#endif
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
- if (!(smb_pass->acct_ctrl & ACB_PWNOTREQ)) {
+ /* Validate password - if required. */
+
+ if (!(acct_ctrl & ACB_PWNOTREQ)) {
switch (q_u->sam_id.logon_level) {
case INTERACTIVE_LOGON_TYPE:
/* interactive login. */
- status = net_login_interactive(&q_u->sam_id.ctr->auth.id1, smb_pass, p);
+ status = net_login_interactive(&q_u->sam_id.ctr->auth.id1, sampass, p);
break;
case NET_LOGON_TYPE:
/* network login. lm challenge and 24 byte responses */
- status = net_login_network(&q_u->sam_id.ctr->auth.id2, smb_pass);
+ status = net_login_network(&q_u->sam_id.ctr->auth.id2, sampass);
break;
}
}
-
- if (status != NT_STATUS_NOPROBLEMO)
+
+ if (status != NT_STATUS_OK)
return status;
+#ifdef WITH_PAM
+ become_root();
+ status = smb_pam_accountcheck(pdb_get_username(sampass));
+ unbecome_root();
+ if (status != NT_STATUS_OK)
+ return status;
+#endif
+
+ if (acct_ctrl & ACB_DISABLED)
+ return NT_STATUS_ACCOUNT_DISABLED;
+
/* lkclXXXX this is the point at which, if the login was
successful, that the SAM Local Security Authority should
record that the user is logged in to the domain.
*/
- /* return the profile plus other bits :-) */
-
{
DOM_GID *gids = NULL;
int num_gids = 0;
- NTTIME dummy_time;
pstring my_name;
pstring my_workgroup;
pstring domain_groups;
- uint32 r_uid;
- uint32 r_gid;
/* set up pointer indicating user/password failed to be found */
usr_info->ptr_user_info = 0;
- dummy_time.low = 0xffffffff;
- dummy_time.high = 0x7fffffff;
-
pstrcpy(my_workgroup, lp_workgroup());
-
pstrcpy(my_name, global_myname);
strupper(my_name);
@@ -665,44 +678,17 @@ uint32 _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_
gids = NULL;
num_gids = make_dom_gids(p->mem_ctx, domain_groups, &gids);
- if (pdb_name_to_rid(nt_username, &r_uid, &r_gid))
- {
- init_net_user_info3(p->mem_ctx, usr_info,
- &dummy_time, /* logon_time */
- &dummy_time, /* logoff_time */
- &dummy_time, /* kickoff_time */
- &dummy_time, /* pass_last_set_time */
- &dummy_time, /* pass_can_change_time */
- &dummy_time, /* pass_must_change_time */
-
- nt_username , /* user_name */
- sam_pass->full_name, /* full_name */
- sam_pass->logon_script , /* logon_script */
- sam_pass->profile_path , /* profile_path */
- sam_pass->home_dir , /* home_dir */
- sam_pass->dir_drive , /* dir_drive */
-
- 0, /* logon_count */
- 0, /* bad_pw_count */
-
- r_uid , /* RID user_id */
- r_gid , /* RID group_id */
- num_gids, /* uint32 num_groups */
- gids , /* DOM_GID *gids */
- 0x20 , /* uint32 user_flgs (?) */
-
- NULL, /* char sess_key[16] */
-
- my_name , /* char *logon_srv */
- my_workgroup, /* char *logon_dom */
-
- &global_sam_sid, /* DOM_SID *dom_sid */
- NULL); /* char *other_sids */
- }
- else
- {
- return NT_STATUS_NO_SUCH_USER;
- }
+ init_net_user_info3(p->mem_ctx, usr_info, sampass,
+ 0, /* logon_count */
+ 0, /* bad_pw_count */
+ num_gids, /* uint32 num_groups */
+ gids , /* DOM_GID *gids */
+ 0x20 , /* uint32 user_flgs (?) */
+ NULL, /* char sess_key[16] */
+ my_name , /* char *logon_srv */
+ my_workgroup, /* char *logon_dom */
+ &global_sam_sid, /* DOM_SID *dom_sid */
+ NULL); /* char *other_sids */
}
diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index d16290985ec..174a21a4c50 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/rpc_server/srv_pipe.c
@@ -269,8 +269,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
fstring domain;
fstring wks;
BOOL guest_user = False;
- struct smb_passwd *smb_pass = NULL;
- struct passwd *pass = NULL;
+ SAM_ACCOUNT *sampass = NULL;
uchar null_smb_passwd[16];
uchar *smb_passwd_ptr = NULL;
@@ -359,15 +358,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
}
- /*
- * Find the user in the unix password db.
- */
-
- if(!(pass = Get_Pwnam(pipe_user_name,True))) {
- DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",pipe_user_name));
- return(False);
- }
-
if(!guest_user) {
become_root();
@@ -380,33 +370,32 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name
return False;
}
- if(!(smb_pass = getsmbpwnam(pipe_user_name))) {
+ pdb_init_sam(&sampass);
+
+ if(!pdb_getsampwnam(sampass, pipe_user_name)) {
DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n",
pipe_user_name));
+ pdb_free_sam(sampass);
unbecome_root();
return False;
}
-
+
unbecome_root();
- if (smb_pass == NULL) {
- DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n",
- pipe_user_name));
- return(False);
- }
-
- /* Quit if the account was disabled. */
- if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) {
+ /* Quit if the account was disabled. */
+ if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) {
DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name));
- return(False);
- }
-
- if(!smb_pass->smb_nt_passwd) {
+ pdb_free_sam(sampass);
+ return False;
+ }
+
+ if(!pdb_get_nt_passwd(sampass)) {
DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name));
- return(False);
- }
-
- smb_passwd_ptr = smb_pass->smb_passwd;
+ pdb_free_sam(sampass);
+ return False;
+ }
+
+ smb_passwd_ptr = pdb_get_lanman_passwd(sampass);
}
/*
@@ -457,8 +446,8 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name
* Store the UNIX credential data (uid/gid pair) in the pipe structure.
*/
- p->pipe_user.uid = pass->pw_uid;
- p->pipe_user.gid = pass->pw_gid;
+ p->pipe_user.uid = pdb_get_uid(sampass);
+ p->pipe_user.gid = pdb_get_gid(sampass);
/* Set up pipe user group membership. */
initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid);
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index f91df7c4ef4..c9fb06da4db 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -775,10 +775,15 @@ ssize_t read_from_pipe(pipes_struct *p, char *data, size_t n)
* read request.
*/
+ /*
+ * This condition should result in the connection being closed.
+ * Netapp filers seem to set it to 0xffff which results in domain
+ * authentications failing. Just ignore it so things work.
+ */
+
if(n > MAX_PDU_FRAG_LEN) {
- DEBUG(0,("read_from_pipe: loo large read (%u) requested on pipe %s. We can \
-only service %d sized reads.\n", (unsigned int)n, p->name, MAX_PDU_FRAG_LEN ));
- return -1;
+ DEBUG(5,("read_from_pipe: too large read (%u) requested on \
+pipe %s. We can only service %d sized reads.\n", (unsigned int)n, p->name, MAX_PDU_FRAG_LEN ));
}
/*
diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c
index 502d5514378..c3b4a1a7a5d 100644
--- a/source/rpc_server/srv_reg_nt.c
+++ b/source/rpc_server/srv_reg_nt.c
@@ -55,7 +55,7 @@ uint32 _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
if (!close_policy_hnd(p, &q_u->pol))
return NT_STATUS_OBJECT_NAME_INVALID;
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -67,7 +67,7 @@ uint32 _reg_open(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
if (!create_policy_hnd(p, &r_u->pol, free_reg_info, NULL))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -103,7 +103,7 @@ uint32 _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
if (!create_policy_hnd(p, &pol, free_reg_info, (void *)info))
return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
- init_reg_r_open_entry(r_u, &pol, NT_STATUS_NOPROBLEMO);
+ init_reg_r_open_entry(r_u, &pol, NT_STATUS_OK);
DEBUG(5,("reg_open_entry: %d\n", __LINE__));
@@ -116,7 +116,7 @@ uint32 _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY
uint32 _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
char *key = NULL;
uint32 type=0x1; /* key type: REG_SZ */
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index e0d80a3f9a1..9c2f37d4ce0 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -65,134 +65,156 @@ static uint32 get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
int *total_entries, int *num_entries,
int max_num_entries, uint16 acb_mask)
{
- void *vp = NULL;
- struct sam_passwd *pwd = NULL;
+ SAM_ACCOUNT *pwd = NULL;
+ BOOL not_finished = True;
- (*num_entries) = 0;
- (*total_entries) = 0;
+ (*num_entries) = 0;
+ (*total_entries) = 0;
- if (pw_buf == NULL)
- return NT_STATUS_NO_MEMORY;
+ if (pw_buf == NULL)
+ return NT_STATUS_NO_MEMORY;
- vp = startsmbpwent(False);
- if (!vp) {
- DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
+ pdb_init_sam(&pwd);
- while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries) {
- int user_name_len;
+ if (!pdb_setsampwent(False)) {
+ DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n"));
+ pdb_free_sam(pwd);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ while (((not_finished = pdb_getsampwent(pwd)) != False)
+ && (*num_entries) < max_num_entries)
+ {
+ int user_name_len;
- if (start_idx > 0) {
- /* skip the requested number of entries.
- not very efficient, but hey...
- */
- start_idx--;
- continue;
+ if (start_idx > 0) {
+ /* skip the requested number of entries.
+ not very efficient, but hey... */
+ pdb_reset_sam(pwd);
+ start_idx--;
+ continue;
}
- user_name_len = strlen(pwd->smb_name)+1;
- init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->smb_name, user_name_len);
- init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
- pw_buf[(*num_entries)].user_rid = pwd->user_rid;
- memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
+ user_name_len = strlen(pdb_get_username(pwd))+1;
+ init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
+ init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
+ pw_buf[(*num_entries)].user_rid = pwd->user_rid;
+ memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
- /* Now check if the NT compatible password is available. */
- if (pwd->smb_nt_passwd != NULL) {
- memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
- }
+ /* Now check if the NT compatible password is available. */
+ if (pdb_get_nt_passwd(pwd))
+ memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
- pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
+ pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
- DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
- (*num_entries), pwd->smb_name, pwd->user_rid, pwd->acct_ctrl));
+ DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
+ (*num_entries), pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
- if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
- DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
- (*num_entries)++;
- }
- else
- DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
+ if (acb_mask == 0 || (pwd->acct_ctrl & acb_mask)) {
+ DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
+ (*num_entries)++;
+ } else
+ DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
- (*total_entries)++;
- }
+ (*total_entries)++;
+ pdb_reset_sam(pwd);
+ }
- endsmbpwent(vp);
+ pdb_endsampwent();
+ pdb_free_sam(pwd);
- if (pwd!=NULL)
+ if (not_finished)
return STATUS_MORE_ENTRIES;
else
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
static uint32 jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx,
int *total_entries, uint32 *num_entries,
int max_num_entries, uint16 acb_mask)
{
- void *vp = NULL;
- struct sam_passwd *pwd = NULL;
+ SAM_ACCOUNT *pwd = NULL;
+ BOOL not_finished = True;
*num_entries = 0;
*total_entries = 0;
if (pw_buf == NULL)
return NT_STATUS_NO_MEMORY;
+
+ DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n",
+ start_idx, max_num_entries, acb_mask));
- vp = startsmbpwent(False);
- if (!vp) {
- DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
+ if (!pdb_setsampwent(False)) {
+ DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n"));
return NT_STATUS_ACCESS_DENIED;
}
- while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries) {
+ pdb_init_sam(&pwd);
+
+ while (((not_finished = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) {
int user_name_len;
int full_name_len;
- if (acb_mask != 0 && !(pwd->acct_ctrl & acb_mask))
+ if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
+ pdb_reset_sam(pwd);
continue;
+ }
if (start_idx > 0) {
/* skip the requested number of entries.
not very efficient, but hey...
*/
start_idx--;
+ pdb_reset_sam(pwd);
continue;
}
ZERO_STRUCTP(&pw_buf[(*num_entries)]);
- user_name_len = strlen(pwd->smb_name);
- init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pwd->smb_name, user_name_len);
+ user_name_len = strlen(pdb_get_username(pwd));
+ init_unistr2(&pw_buf[(*num_entries)].uni_user_name, pdb_get_username(pwd), user_name_len);
init_uni_hdr(&pw_buf[(*num_entries)].hdr_user_name, user_name_len);
- full_name_len = strlen(pwd->full_name);
- init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pwd->full_name, full_name_len);
+ full_name_len = strlen(pdb_get_fullname(pwd));
+ init_unistr2(&pw_buf[(*num_entries)].uni_full_name, pdb_get_fullname(pwd), full_name_len);
init_uni_hdr(&pw_buf[(*num_entries)].hdr_full_name, full_name_len);
- pw_buf[(*num_entries)].user_rid = pwd->user_rid;
+ pw_buf[(*num_entries)].user_rid = pdb_get_user_rid(pwd);
memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
/* Now check if the NT compatible password is available. */
- if (pwd->smb_nt_passwd != NULL) {
- memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
- }
+ if (pdb_get_nt_passwd(pwd))
+ memcpy( pw_buf[(*num_entries)].nt_pwd , pdb_get_nt_passwd(pwd), 16);
+
+ pw_buf[(*num_entries)].acb_info = pdb_get_acct_ctrl(pwd);
- pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
+ DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries),
+ pdb_get_username(pwd), pdb_get_user_rid(pwd), pdb_get_acct_ctrl(pwd) ));
- DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x\n", (*num_entries), pwd->smb_name, pwd->user_rid, pwd->acct_ctrl));
(*num_entries)++;
+
+ pdb_reset_sam(pwd);
}
- endsmbpwent(vp);
+ pdb_endsampwent();
*total_entries = *num_entries;
+
+ pdb_free_sam(pwd);
- if (pwd!=NULL)
+ if (not_finished)
return STATUS_MORE_ENTRIES;
else
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
+/*
+ * These next two functions are not used. Tagged
+ * for deletion
+ */
+
+#if 0
/*******************************************************************
This function uses the username map file and tries to map a UNIX
user name to an DOS name. (Sort of the reverse of the
@@ -439,6 +461,7 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
done:
return (*num_entries) > 0;
}
+#endif
/*******************************************************************
_samr_close_hnd
@@ -446,7 +469,7 @@ done:
uint32 _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
{
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* close the policy handle */
if (!close_policy_hnd(p, &q_u->pol))
@@ -465,7 +488,7 @@ uint32 _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_D
{
struct samr_info *info;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, &q_u->pol, NULL))
@@ -505,7 +528,7 @@ uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, S
{
struct samr_info *info = NULL;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info)) {
@@ -517,7 +540,7 @@ uint32 _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, S
return NT_STATUS_OBJECT_TYPE_MISMATCH;
}
- init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_NOPROBLEMO);
+ init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
@@ -567,7 +590,7 @@ static uint32 samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC_BUF **buf, DOM_SID
if((*buf = make_sec_desc_buf(ctx, sd_size, psd)) == NULL)
return NT_STATUS_NO_MEMORY;
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid)
@@ -593,7 +616,7 @@ uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QU
{
DOM_SID pol_sid;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* Get the SID. */
@@ -602,7 +625,7 @@ uint32 _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QU
r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &r_u->buf, &pol_sid);
- if (r_u->status == NT_STATUS_NOPROBLEMO)
+ if (r_u->status == NT_STATUS_OK)
r_u->ptr = 1;
return r_u->status;
@@ -625,9 +648,9 @@ static void make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR
if (num_sam_entries == 0)
return;
- sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
+ sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
- uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
+ uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
if (sam == NULL || uni_name == NULL) {
DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
@@ -662,15 +685,13 @@ static void samr_clear_passwd_fields( SAM_USER_INFO_21 *pass, int num_entries)
}
}
-static void samr_clear_sam_passwd( struct sam_passwd *sam_pass)
+static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
{
if (!sam_pass)
return;
- if (sam_pass->smb_passwd)
- memset(sam_pass->smb_passwd, '\0', 16);
- if (sam_pass->smb_nt_passwd)
- memset(sam_pass->smb_nt_passwd, '\0', 16);
+ if (sam_pass->lm_pw) memset(sam_pass->lm_pw, '\0', 16);
+ if (sam_pass->nt_pw) memset(sam_pass->nt_pw, '\0', 16);
}
/*******************************************************************
@@ -683,7 +704,7 @@ uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_
int num_entries = 0;
int total_entries = 0;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
if (!find_policy_by_hnd(p, &q_u->pol, NULL))
@@ -696,7 +717,7 @@ uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_
MAX_SAM_ENTRIES, q_u->acb_mask);
unbecome_root();
- if (r_u->status != NT_STATUS_NOPROBLEMO && r_u->status != STATUS_MORE_ENTRIES)
+ if (r_u->status != NT_STATUS_OK && r_u->status != STATUS_MORE_ENTRIES)
return r_u->status;
samr_clear_passwd_fields(pass, num_entries);
@@ -740,9 +761,9 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST
if (num_sam_entries == 0)
return;
- sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
+ sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
- uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
+ uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
if (sam == NULL || uni_name == NULL) {
DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
@@ -767,7 +788,7 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST
Get the group entries - similar to get_sampwd_entries().
********************************************************************/
-static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
+static uint32 get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 start_idx,
uint32 *p_num_entries, uint32 max_entries)
{
fstring sid_str;
@@ -809,7 +830,7 @@ static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 star
* libc grent structures overwrites by called functions */
grp = glist = getgrent_list();
if (grp == NULL)
- return False;
+ return NT_STATUS_NO_MEMORY;
for (;(num_entries < max_entries) && (grp != NULL); grp = grp->next) {
int i;
@@ -859,7 +880,9 @@ static BOOL get_group_alias_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 star
*p_num_entries = num_entries;
- return True;
+ if (num_entries >= max_entries)
+ return STATUS_MORE_ENTRIES;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -894,7 +917,7 @@ static uint32 get_group_domain_entries(DOMAIN_GRP *d_grp, DOM_SID *sid, uint32 s
*p_num_entries = num_entries;
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -909,7 +932,7 @@ uint32 _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_
uint32 num_entries;
DOM_SID sid;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
return NT_STATUS_INVALID_HANDLE;
@@ -939,7 +962,7 @@ uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAM
fstring sid_str;
DOM_SID sid;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid))
return NT_STATUS_INVALID_HANDLE;
@@ -947,12 +970,15 @@ uint32 _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAM
sid_to_string(sid_str, &sid);
DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
- if (!get_group_alias_entries(grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))
- return NT_STATUS_ACCESS_DENIED;
+ r_u->status = get_group_alias_entries(grp, &sid, q_u->start_idx,
+ &num_entries, MAX_SAM_ENTRIES);
+
+ if (r_u->status != NT_STATUS_OK && r_u->status != STATUS_MORE_ENTRIES)
+ return r_u->status;
make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
- init_samr_r_enum_dom_aliases(r_u, q_u->start_idx, num_entries);
+ init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
@@ -978,7 +1004,7 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_
DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid))
return NT_STATUS_INVALID_HANDLE;
@@ -1013,7 +1039,7 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_
MAX_SAM_ENTRIES, acb_mask);
#endif
unbecome_root();
- if (r_u->status!=STATUS_MORE_ENTRIES && r_u->status!=NT_STATUS_NO_PROBLEMO) {
+ if (r_u->status!=STATUS_MORE_ENTRIES && r_u->status!=NT_STATUS_OK) {
DEBUG(5, ("get_sampwd_entries: failed\n"));
return r_u->status;
}
@@ -1021,7 +1047,7 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_
case 0x3:
case 0x5:
r_u->status = get_group_domain_entries(grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES);
- if (r_u->status!=NT_STATUS_NO_PROBLEMO)
+ if (r_u->status!=NT_STATUS_OK)
return NT_STATUS_ACCESS_DENIED;
break;
default:
@@ -1044,45 +1070,57 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_
data_size = q_u->max_size;
- ctr = (SAM_DISPINFO_CTR *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_CTR));
+ ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR));
if (!ctr)
return NT_STATUS_NO_MEMORY;
+ ZERO_STRUCTP(ctr);
+
/* Now create reply structure */
switch (q_u->switch_level) {
case 0x1:
- if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1))))
- return NT_STATUS_NO_MEMORY;
+ if (num_entries) {
+ if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_1))))
+ return NT_STATUS_NO_MEMORY;
+ }
disp_ret = init_sam_dispinfo_1(p->mem_ctx,ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass);
- if (disp_ret != NT_STATUS_NO_PROBLEMO)
+ if (disp_ret != NT_STATUS_OK)
return disp_ret;
break;
case 0x2:
- if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2))))
- return NT_STATUS_NO_MEMORY;
+ if (num_entries) {
+ if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_2))))
+ return NT_STATUS_NO_MEMORY;
+ }
disp_ret = init_sam_dispinfo_2(p->mem_ctx,ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass);
- if (disp_ret != NT_STATUS_NO_PROBLEMO)
+ if (disp_ret != NT_STATUS_OK)
return disp_ret;
break;
case 0x3:
- if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3))))
- return NT_STATUS_NO_MEMORY;
+ if (num_entries) {
+ if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_3))))
+ return NT_STATUS_NO_MEMORY;
+ }
disp_ret = init_sam_dispinfo_3(p->mem_ctx,ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps);
- if (disp_ret != NT_STATUS_NO_PROBLEMO)
+ if (disp_ret != NT_STATUS_OK)
return disp_ret;
break;
case 0x4:
- if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4))))
- return NT_STATUS_NO_MEMORY;
+ if (num_entries) {
+ if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_4))))
+ return NT_STATUS_NO_MEMORY;
+ }
disp_ret = init_sam_dispinfo_4(p->mem_ctx,ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass);
- if (disp_ret != NT_STATUS_NO_PROBLEMO)
+ if (disp_ret != NT_STATUS_OK)
return disp_ret;
break;
case 0x5:
- if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5))))
- return NT_STATUS_NO_MEMORY;
+ if (num_entries) {
+ if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,num_entries*sizeof(SAM_DISPINFO_5))))
+ return NT_STATUS_NO_MEMORY;
+ }
disp_ret = init_sam_dispinfo_5(p->mem_ctx,ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps);
- if (disp_ret != NT_STATUS_NO_PROBLEMO)
+ if (disp_ret != NT_STATUS_OK)
return disp_ret;
break;
default:
@@ -1112,7 +1150,7 @@ uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_
uint32 alias_rid;
struct samr_info *info = NULL;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
@@ -1152,7 +1190,7 @@ uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_
uint32 rid[MAX_SAM_ENTRIES];
int num_rids = q_u->num_sids1;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
@@ -1194,7 +1232,7 @@ uint32 _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_
num_rids = 1;
rid[0] = BUILTIN_ALIAS_RID_USERS;
- init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_NOPROBLEMO);
+ init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
@@ -1214,7 +1252,7 @@ uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOK
int num_rids = q_u->num_names2;
DOM_SID pol_sid;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
@@ -1245,7 +1283,7 @@ uint32 _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOK
DOM_SID sid;
if(local_lookup_name(global_myname, name, &sid, &type[i])) {
sid_split_rid( &sid, &rid[i]);
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
}
}
}
@@ -1268,7 +1306,7 @@ uint32 _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_
DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
@@ -1313,11 +1351,11 @@ static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring nam
*pp_hdr_name = NULL;
if (num_names != 0) {
- hdr_name = (UNIHDR *)talloc(ctx, sizeof(UNIHDR)*num_names);
+ hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
if (hdr_name == NULL)
return False;
- uni_name = (UNISTR2 *)talloc(ctx,sizeof(UNISTR2)*num_names);
+ uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
if (uni_name == NULL)
return False;
}
@@ -1349,7 +1387,7 @@ uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP
int num_rids = q_u->num_rids1;
int i;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
@@ -1363,7 +1401,7 @@ uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP
}
if (num_rids) {
- if ((group_attrs = (uint32 *)talloc(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
+ if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
return NT_STATUS_NO_MEMORY;
}
@@ -1383,7 +1421,7 @@ uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP
sid_append_rid(&sid, q_u->rid[i]);
if (lookup_sid(&sid, domname, tmpname, &type)) {
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
group_attrs[i] = (uint32)type;
fstrcpy(group_names[i],tmpname);
}
@@ -1406,49 +1444,55 @@ uint32 _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP
uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
{
- struct sam_passwd *sam_pass;
- DOM_SID sid;
- POLICY_HND domain_pol = q_u->domain_pol;
- uint32 user_rid = q_u->user_rid;
- POLICY_HND *user_pol = &r_u->user_pol;
+ SAM_ACCOUNT *sampass=NULL;
+ DOM_SID sid;
+ POLICY_HND domain_pol = q_u->domain_pol;
+ uint32 user_rid = q_u->user_rid;
+ POLICY_HND *user_pol = &r_u->user_pol;
struct samr_info *info = NULL;
+ BOOL ret;
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
- /* find the domain policy handle. */
- if (!find_policy_by_hnd(p, &domain_pol, NULL))
- return NT_STATUS_INVALID_HANDLE;
+ /* find the domain policy handle. */
+ if (!find_policy_by_hnd(p, &domain_pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
- become_root();
- sam_pass = getsam21pwrid(user_rid);
- unbecome_root();
+ pdb_init_sam(&sampass);
- /* check that the RID exists in our domain. */
- if (sam_pass == NULL)
- return NT_STATUS_NO_SUCH_USER;
+ become_root();
+ ret=pdb_getsampwrid(sampass, user_rid);
+ unbecome_root();
- samr_clear_sam_passwd(sam_pass);
+ /* check that the RID exists in our domain. */
+ if (ret == False) {
+ pdb_free_sam(sampass);
+ return NT_STATUS_NO_SUCH_USER;
+ }
- /* Get the domain SID stored in the domain policy */
- if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
- return NT_STATUS_INVALID_HANDLE;
+ samr_clear_sam_passwd(sampass);
+ pdb_free_sam(sampass);
- /* append the user's RID to it */
- if(!sid_append_rid(&sid, user_rid))
- return NT_STATUS_NO_SUCH_USER;
+ /* Get the domain SID stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(p, &domain_pol, &sid))
+ return NT_STATUS_INVALID_HANDLE;
- /* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
+ /* append the user's RID to it */
+ if(!sid_append_rid(&sid, user_rid))
+ return NT_STATUS_NO_SUCH_USER;
- ZERO_STRUCTP(info);
- info->sid = sid;
+ /* associate the user's SID with the new handle. */
+ if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
+ return NT_STATUS_NO_MEMORY;
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ ZERO_STRUCTP(info);
+ info->sid = sid;
- return r_u->status;
+ /* get a (unique) handle. open a policy on it. */
+ if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ return r_u->status;
}
/*************************************************************************
@@ -1457,28 +1501,35 @@ uint32 _api_samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_U
static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
{
- struct smb_passwd *smb_pass;
+ SAM_ACCOUNT *smbpass=NULL;
+ BOOL ret;
- if (!pdb_rid_is_user(user_rid)) {
- DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
- return False;
- }
+ if (!pdb_rid_is_user(user_rid)) {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
- become_root();
- smb_pass = getsmbpwrid(user_rid);
- unbecome_root();
+ pdb_init_sam(&smbpass);
- if (smb_pass == NULL)
- {
- DEBUG(4,("User 0x%x not found\n", user_rid));
- return False;
- }
+ become_root();
+ ret = pdb_getsampwrid(smbpass, user_rid);
+ unbecome_root();
- DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
+ if (ret==False) {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ pdb_free_sam(smbpass);
+ return False;
+ }
+
+ DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
- init_sam_user_info10(id10, smb_pass->acct_ctrl);
+ ZERO_STRUCTP(id10);
+ init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
- return True;
+ samr_clear_sam_passwd(smbpass);
+ pdb_free_sam(smbpass);
+
+ return True;
}
/*************************************************************************
@@ -1489,7 +1540,8 @@ static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
static BOOL get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 user_rid)
{
- struct smb_passwd *smb_pass;
+ SAM_ACCOUNT *smbpass=NULL;
+ BOOL ret;
if (!p->ntlmssp_auth_validated)
return NT_STATUS_ACCESS_DENIED;
@@ -1500,95 +1552,106 @@ static BOOL get_user_info_12(pipes_struct *p, SAM_USER_INFO_12 * id12, uint32 us
/*
* Do *NOT* do become_root()/unbecome_root() here ! JRA.
*/
+ pdb_init_sam(&smbpass);
- smb_pass = getsmbpwrid(user_rid);
+ ret = pdb_getsampwrid(smbpass, user_rid);
- if (smb_pass == NULL) {
+ if (ret == False) {
DEBUG(4, ("User 0x%x not found\n", user_rid));
+ pdb_free_sam(smbpass);
return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
}
- DEBUG(3,("User:[%s] 0x%x\n", smb_pass->smb_name, smb_pass->acct_ctrl));
+ DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
- if (smb_pass->acct_ctrl & ACB_DISABLED)
- return NT_STATUS_ACCOUNT_DISABLED;
+ if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
+ pdb_free_sam(smbpass);
+ return NT_STATUS_ACCOUNT_DISABLED;
+ }
- init_sam_user_info12(id12, smb_pass->smb_passwd, smb_pass->smb_nt_passwd);
+ ZERO_STRUCTP(id12);
+ init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
+
+ pdb_free_sam(smbpass);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
+#if 0 /* JERRY */
/*************************************************************************
- get_user_info_21
+ get_user_info_20
*************************************************************************/
-static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
+static BOOL get_user_info_20(SAM_USER_INFO_20 *id20, uint32 user_rid)
{
- NTTIME dummy_time;
- struct sam_passwd *sam_pass;
- LOGON_HRS hrs;
- int i;
+ SAM_ACCOUNT *sampass=NULL;
+ BOOL ret;
- if (!pdb_rid_is_user(user_rid)) {
- DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
- return False;
- }
+ if (!pdb_rid_is_user(user_rid)) {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
- become_root();
- sam_pass = getsam21pwrid(user_rid);
- unbecome_root();
+ pdb_init_sam(&sampass);
- if (sam_pass == NULL) {
- DEBUG(4,("User 0x%x not found\n", user_rid));
- return False;
- }
+ become_root();
+ ret = pdb_getsampwrid(sampass, user_rid);
+ unbecome_root();
- samr_clear_sam_passwd(sam_pass);
+ if (ret == False) {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ pdb_free_sam(sampass);
+ return False;
+ }
+
+ samr_clear_sam_passwd(sampass);
- DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
+ DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
+
+ ZERO_STRUCTP(id20);
+ init_sam_user_info20A(id20, sampass);
+
+ pdb_free_sam(sampass);
+
+ return True;
+}
+#endif
+/*************************************************************************
+ get_user_info_21
+ *************************************************************************/
- dummy_time.low = 0xffffffff;
- dummy_time.high = 0x7fffffff;
+static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
+{
+ SAM_ACCOUNT *sampass=NULL;
+ BOOL ret;
- DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
+ if (!pdb_rid_is_user(user_rid)) {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
- /* create a LOGON_HRS structure */
- hrs.len = sam_pass->hours_len;
- SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
- for (i = 0; i < hrs.len; i++)
- hrs.hours[i] = sam_pass->hours[i];
+ pdb_init_sam(&sampass);
- init_sam_user_info21A(id21,
+ become_root();
+ ret = pdb_getsampwrid(sampass, user_rid);
+ unbecome_root();
- &dummy_time, /* logon_time */
- &dummy_time, /* logoff_time */
- &dummy_time, /* kickoff_time */
- &dummy_time, /* pass_last_set_time */
- &dummy_time, /* pass_can_change_time */
- &dummy_time, /* pass_must_change_time */
+ if (ret == False) {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ pdb_free_sam(sampass);
+ return False;
+ }
- sam_pass->smb_name, /* user_name */
- sam_pass->full_name, /* full_name */
- sam_pass->home_dir, /* home_dir */
- sam_pass->dir_drive, /* dir_drive */
- sam_pass->logon_script, /* logon_script */
- sam_pass->profile_path, /* profile_path */
- sam_pass->acct_desc, /* description */
- sam_pass->workstations, /* workstations user can log in from */
- sam_pass->unknown_str, /* don't know, yet */
- sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
+ samr_clear_sam_passwd(sampass);
- sam_pass->user_rid, /* RID user_id */
- sam_pass->group_rid, /* RID group_id */
- sam_pass->acct_ctrl,
+ DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
- sam_pass->unknown_3, /* unknown_3 */
- sam_pass->logon_divs, /* divisions per week */
- &hrs, /* logon hours */
- sam_pass->unknown_5,
- sam_pass->unknown_6);
+ ZERO_STRUCTP(id21);
+ init_sam_user_info21A(id21, sampass);
+
+ pdb_free_sam(sampass);
- return True;
+ return True;
}
/*******************************************************************
@@ -1601,7 +1664,7 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
uint32 rid = 0;
struct samr_info *info = NULL;
- r_u->status=NT_STATUS_NO_PROBLEMO;
+ r_u->status=NT_STATUS_OK;
/* search for the handle */
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
@@ -1613,7 +1676,7 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
DEBUG(5,("_samr_query_userinfo: rid:0x%x\n", rid));
- ctr = (SAM_USERINFO_CTR *)talloc(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
+ ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
if (!ctr)
return NT_STATUS_NO_MEMORY;
@@ -1624,7 +1687,7 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
switch (q_u->switch_value) {
case 0x10:
- ctr->info.id10 = (SAM_USER_INFO_10 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_10));
+ ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
if (ctr->info.id10 == NULL)
return NT_STATUS_NO_MEMORY;
@@ -1642,7 +1705,7 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
expire.low = 0xffffffff;
expire.high = 0x7fffffff;
- ctr->info.id = (SAM_USER_INFO_11 *)talloc(p->mem_ctx,
+ ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
sizeof
(*ctr->
info.
@@ -1658,16 +1721,16 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
#endif
case 0x12:
- ctr->info.id12 = (SAM_USER_INFO_12 *)talloc(p->mem_ctx, sizeof(SAM_USER_INFO_12));
+ ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
if (ctr->info.id12 == NULL)
return NT_STATUS_NO_MEMORY;
- if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid))!=NT_STATUS_NOPROBLEMO)
+ if ((r_u->status = get_user_info_12(p, ctr->info.id12, rid))!=NT_STATUS_OK)
return r_u->status;
break;
case 21:
- ctr->info.id21 = (SAM_USER_INFO_21 *)talloc(p->mem_ctx,sizeof(SAM_USER_INFO_21));
+ ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
if (ctr->info.id21 == NULL)
return NT_STATUS_NO_MEMORY;
if (!get_user_info_21(ctr->info.id21, rid))
@@ -1691,44 +1754,49 @@ uint32 _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_
uint32 _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
{
- struct sam_passwd *sam_pass;
- DOM_GID *gids = NULL;
- int num_groups = 0;
- pstring groups;
- uint32 rid;
+ SAM_ACCOUNT *sam_pass=NULL;
+ DOM_GID *gids = NULL;
+ int num_groups = 0;
+ pstring groups;
+ uint32 rid;
struct samr_info *info = NULL;
+ BOOL ret;
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
- DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
+ DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
- return NT_STATUS_INVALID_HANDLE;
+ /* find the policy handle. open a policy on it. */
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ return NT_STATUS_INVALID_HANDLE;
- /* find the user's rid */
- if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ /* find the user's rid */
+ if ((rid = get_lsa_policy_samr_rid(info)) == 0xffffffff)
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
- become_root();
- sam_pass = getsam21pwrid(rid);
- unbecome_root();
+ pdb_init_sam(&sam_pass);
- if (sam_pass == NULL)
- return NT_STATUS_NO_SUCH_USER;
+ become_root();
+ ret = pdb_getsampwrid(sam_pass, rid);
+ unbecome_root();
- samr_clear_sam_passwd(sam_pass);
+ if (ret == False) {
+ samr_clear_sam_passwd(sam_pass);
+ return NT_STATUS_NO_SUCH_USER;
+ }
- get_domain_user_groups(groups, sam_pass->smb_name);
- gids = NULL;
- num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
+ get_domain_user_groups(groups, pdb_get_username(sam_pass));
+ gids = NULL;
+ num_groups = make_dom_gids(p->mem_ctx, groups, &gids);
- /* construct the response. lkclXXXX: gids are not copied! */
- init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
+ /* construct the response. lkclXXXX: gids are not copied! */
+ init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
- DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
+ DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
+
+ samr_clear_sam_passwd(sam_pass);
- return r_u->status;
+ return r_u->status;
}
/*******************************************************************
@@ -1739,12 +1807,12 @@ uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR
{
SAM_UNK_CTR *ctr;
- if ((ctr = (SAM_UNK_CTR *)talloc(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
+ if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
return NT_STATUS_NO_MEMORY;
ZERO_STRUCTP(ctr);
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
@@ -1776,7 +1844,7 @@ uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR
return NT_STATUS_INVALID_INFO_CLASS;
}
- init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_NOPROBLEMO);
+ init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
@@ -1789,107 +1857,119 @@ uint32 _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR
uint32 _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
{
- struct sam_passwd *sam_pass = NULL;
- fstring mach_acct;
- pstring err_str;
- pstring msg_str;
- int local_flags=0;
- DOM_SID sid;
- pstring add_script;
- POLICY_HND dom_pol = q_u->domain_pol;
- UNISTR2 user_account = q_u->uni_name;
- uint16 acb_info = q_u->acb_info;
- POLICY_HND *user_pol = &r_u->user_pol;
+ SAM_ACCOUNT *sam_pass=NULL;
+ fstring mach_acct;
+ pstring err_str;
+ pstring msg_str;
+ int local_flags=0;
+ DOM_SID sid;
+ pstring add_script;
+ POLICY_HND dom_pol = q_u->domain_pol;
+ UNISTR2 user_account = q_u->uni_name;
+ uint16 acb_info = q_u->acb_info;
+ POLICY_HND *user_pol = &r_u->user_pol;
struct samr_info *info = NULL;
+ BOOL ret;
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &dom_pol, NULL))
- return NT_STATUS_INVALID_HANDLE;
+ /* find the policy handle. open a policy on it. */
+ if (!find_policy_by_hnd(p, &dom_pol, NULL))
+ return NT_STATUS_INVALID_HANDLE;
- /* find the machine account: tell the caller if it exists.
- lkclXXXX i have *no* idea if this is a problem or not
- or even if you are supposed to construct a different
- reply if the account already exists...
- */
-
- fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
- strlower(mach_acct);
-
- become_root();
- sam_pass = getsam21pwnam(mach_acct);
- unbecome_root();
- if (sam_pass != NULL) {
- /* machine account exists: say so */
- return NT_STATUS_USER_EXISTS;
- }
+ /* find the machine account: tell the caller if it exists.
+ lkclXXXX i have *no* idea if this is a problem or not
+ or even if you are supposed to construct a different
+ reply if the account already exists...
+ */
- local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
- local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
-
- /*
- * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
- * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
- * that only people with write access to the smbpasswd file will be able
- * to create a user. JRA.
- */
-
- /*
- * add the user in the /etc/passwd file or the unix authority system.
- * We don't check if the smb_create_user() function succed or not for 2 reasons:
- * a) local_password_change() checks for us if the /etc/passwd account really exists
- * b) smb_create_user() would return an error if the account already exists
- * and as it could return an error also if it can't create the account, it would be tricky.
- *
- * So we go the easy way, only check after if the account exists.
- * JFM (2/3/2001), to clear any possible bad understanding (-:
- */
-
- pstrcpy(add_script, lp_adduser_script());
-
- if(*add_script)
- smb_create_user(mach_acct, NULL);
-
- /* add the user in the smbpasswd file or the Samba authority database */
- if (!local_password_change(mach_acct, local_flags, NULL, err_str,
- sizeof(err_str), msg_str, sizeof(msg_str)))
- {
- DEBUG(0, ("%s\n", err_str));
- return NT_STATUS_ACCESS_DENIED;
- }
+ fstrcpy(mach_acct, dos_unistrn2(user_account.buffer, user_account.uni_str_len));
+ strlower(mach_acct);
- become_root();
- sam_pass = getsam21pwnam(mach_acct);
- unbecome_root();
- if (sam_pass == NULL) {
- /* account doesn't exist: say so */
- return NT_STATUS_ACCESS_DENIED;
- }
+ pdb_init_sam(&sam_pass);
- /* Get the domain SID stored in the domain policy */
- if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
- return NT_STATUS_INVALID_HANDLE;
- }
+ become_root();
+ ret = pdb_getsampwnam(sam_pass, mach_acct);
+ unbecome_root();
+ if (ret == True) {
+ /* machine account exists: say so */
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_USER_EXISTS;
+ }
- /* append the user's RID to it */
- if(!sid_append_rid(&sid, sam_pass->user_rid)) {
- return NT_STATUS_NO_SUCH_USER;
- }
+ local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
+ local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
- /* associate the user's SID with the new handle. */
- if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
- return NT_STATUS_NO_MEMORY;
+ /*
+ * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
+ * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
+ * that only people with write access to the smbpasswd file will be able
+ * to create a user. JRA.
+ */
- ZERO_STRUCTP(info);
- info->sid = sid;
+ /*
+ * add the user in the /etc/passwd file or the unix authority system.
+ * We don't check if the smb_create_user() function succed or not for 2 reasons:
+ * a) local_password_change() checks for us if the /etc/passwd account really exists
+ * b) smb_create_user() would return an error if the account already exists
+ * and as it could return an error also if it can't create the account, it would be tricky.
+ *
+ * So we go the easy way, only check after if the account exists.
+ * JFM (2/3/2001), to clear any possible bad understanding (-:
+ */
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ pstrcpy(add_script, lp_adduser_script());
+
+ if(*add_script)
+ smb_create_user(mach_acct, NULL);
+ /* add the user in the smbpasswd file or the Samba authority database */
+ if (!local_password_change(mach_acct, local_flags, NULL, err_str,
+ sizeof(err_str), msg_str, sizeof(msg_str))) {
+ DEBUG(0, ("%s\n", err_str));
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_ACCESS_DENIED;
+ }
- r_u->user_rid=sam_pass->user_rid;
- r_u->unknown_0 = 0x000703ff;
+ become_root();
+ ret = pdb_getsampwnam(sam_pass, mach_acct);
+ unbecome_root();
+ if (ret == False) {
+ /* account doesn't exist: say so */
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_ACCESS_DENIED;
+ }
- return NT_STATUS_NO_PROBLEMO;
+ /* Get the domain SID stored in the domain policy */
+ if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* append the user's RID to it */
+ if(!sid_append_rid(&sid, pdb_get_user_rid(sam_pass) )) {
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ /* associate the user's SID with the new handle. */
+ if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL) {
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ZERO_STRUCTP(info);
+ info->sid = sid;
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
+ pdb_free_sam(sam_pass);
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ r_u->user_rid=sam_pass->user_rid;
+ r_u->unknown_0 = 0x000703ff;
+
+ pdb_free_sam(sam_pass);
+
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -1902,7 +1982,7 @@ uint32 _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONN
/* set up the SAMR connect_anon response */
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* associate the user's SID with the new handle. */
if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
@@ -1928,7 +2008,7 @@ uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
DEBUG(5,("_samr_connect: %d\n", __LINE__));
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* associate the user's SID with the new handle. */
if ((info = (struct samr_info *)malloc(sizeof(struct samr_info))) == NULL)
@@ -1952,7 +2032,7 @@ uint32 _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
uint32 _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
{
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
if (!find_policy_by_hnd(p, &q_u->connect_pol, NULL))
return NT_STATUS_INVALID_HANDLE;
@@ -1983,8 +2063,8 @@ static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
if (num_sam_entries == 0)
return True;
- sam = (SAM_ENTRY *)talloc(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
- uni_name = (UNISTR2 *)talloc(ctx, sizeof(UNISTR2)*num_sam_entries);
+ sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
+ uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
if (sam == NULL || uni_name == NULL)
return False;
@@ -2011,7 +2091,7 @@ uint32 _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM
uint32 num_entries = 2;
fstring dom[2];
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
fstrcpy(dom[0],global_myworkgroup);
fstrcpy(dom[1],"Builtin");
@@ -2036,7 +2116,7 @@ uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN
POLICY_HND *alias_pol = &r_u->pol;
struct samr_info *info = NULL;
- r_u->status = NT_STATUS_NO_PROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* get the domain policy. */
if (!find_policy_by_hnd(p, &domain_pol, NULL))
@@ -2075,23 +2155,32 @@ uint32 _api_samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN
static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
{
- struct sam_passwd *pwd = getsam21pwrid(rid);
- struct sam_passwd new_pwd;
+ SAM_ACCOUNT *pwd =NULL;
+ BOOL ret;
+
+ pdb_init_sam(&pwd);
+
+ ret = pdb_getsampwrid(pwd, rid);
+
+ if(ret==False) {
+ pdb_free_sam(pwd);
+ return False;
+ }
if (id10 == NULL) {
DEBUG(5, ("set_user_info_10: NULL id10\n"));
+ pdb_free_sam(pwd);
return False;
}
- if (pwd == NULL)
- return False;
-
- copy_sam_passwd(&new_pwd, pwd);
-
- new_pwd.acct_ctrl = id10->acb_info;
+ pdb_set_acct_ctrl(pwd, id10->acb_info);
- if(!mod_sam21pwd_entry(&new_pwd, True))
+ if(!pdb_update_sam_account(pwd, True)) {
+ pdb_free_sam(pwd);
return False;
+ }
+
+ pdb_free_sam(pwd);
return True;
}
@@ -2102,31 +2191,36 @@ static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
{
- struct sam_passwd *pwd = getsam21pwrid(rid);
- struct sam_passwd new_pwd;
- static uchar nt_hash[16];
- static uchar lm_hash[16];
+ SAM_ACCOUNT *pwd = NULL;
- if (pwd == NULL)
+ pdb_init_sam(&pwd);
+
+ if(!pdb_getsampwrid(pwd, rid)) {
+ pdb_free_sam(pwd);
return False;
+ }
if (id12 == NULL) {
DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
+ pdb_free_sam(pwd);
return False;
}
-
- pdb_init_sam(&new_pwd);
- copy_sam_passwd(&new_pwd, pwd);
-
- memcpy(nt_hash, id12->nt_pwd, sizeof(nt_hash));
- memcpy(lm_hash, id12->lm_pwd, sizeof(lm_hash));
-
- new_pwd.smb_passwd = lm_hash;
- new_pwd.smb_nt_passwd = nt_hash;
-
- if(!mod_sam21pwd_entry(&new_pwd, True))
+
+ if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd)) {
+ pdb_free_sam(pwd);
+ return False;
+ }
+ if (!pdb_set_nt_passwd(pwd, id12->nt_pwd)) {
+ pdb_free_sam(pwd);
return False;
+ }
+
+ if(!pdb_update_sam_account(pwd, True)) {
+ pdb_free_sam(pwd);
+ return False;
+ }
+ pdb_free_sam(pwd);
return True;
}
@@ -2136,39 +2230,44 @@ static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
{
- struct sam_passwd *pwd = getsam21pwrid(rid);
- struct sam_passwd new_pwd;
- static uchar nt_hash[16];
- static uchar lm_hash[16];
-
+ SAM_ACCOUNT *pwd = NULL;
+ SAM_ACCOUNT *new_pwd = NULL;
+
if (id21 == NULL) {
DEBUG(5, ("set_user_info_21: NULL id21\n"));
return False;
}
-
- if (pwd == NULL)
- return False;
-
+
+ pdb_init_sam(&pwd);
pdb_init_sam(&new_pwd);
- /* we make a copy so that we can modify stuff */
- copy_sam_passwd(&new_pwd, pwd);
- copy_id21_to_sam_passwd(&new_pwd, id21);
-
- if (pwd->smb_nt_passwd != NULL) {
- memcpy(nt_hash, pwd->smb_nt_passwd, 16);
- new_pwd.smb_nt_passwd = nt_hash;
- } else
- new_pwd.smb_nt_passwd = NULL;
-
- if (pwd->smb_nt_passwd != NULL) {
- memcpy(lm_hash, pwd->smb_passwd, 16);
- new_pwd.smb_passwd = lm_hash;
- } else
- new_pwd.smb_passwd = NULL;
-
- if(!mod_sam21pwd_entry(&new_pwd, True))
+
+ if (!pdb_getsampwrid(pwd, rid)) {
+ pdb_free_sam(pwd);
+ pdb_free_sam(new_pwd);
return False;
-
+ }
+
+ /* we make a copy so that we can modify stuff */
+ copy_sam_passwd(new_pwd, pwd);
+ copy_id21_to_sam_passwd(new_pwd, id21);
+
+ /*
+ * The funny part about the previous two calls is
+ * that pwd still has the password hashes from the
+ * passdb entry. These have not been updated from
+ * id21. I don't know if they need to be set. --jerry
+ */
+
+ /* write the change out */
+ if(!pdb_update_sam_account(new_pwd, True)) {
+ pdb_free_sam(pwd);
+ pdb_free_sam(new_pwd);
+ return False;
+ }
+
+ pdb_free_sam(pwd);
+ pdb_free_sam(new_pwd);
+
return True;
}
@@ -2178,51 +2277,72 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
{
- struct sam_passwd *pwd = getsam21pwrid(rid);
- struct sam_passwd new_pwd;
- static uchar nt_hash[16];
- static uchar lm_hash[16];
+ SAM_ACCOUNT *pwd = NULL;
+ SAM_ACCOUNT *new_pwd = NULL;
+ uint8 nt_hash[16];
+ uint8 lm_hash[16];
pstring buf;
uint32 len;
-
+ uint16 acct_ctrl;
+
if (id23 == NULL) {
DEBUG(5, ("set_user_info_23: NULL id23\n"));
return False;
}
-
- if (pwd == NULL)
- return False;
-
+
+ pdb_init_sam(&pwd);
pdb_init_sam(&new_pwd);
- copy_sam_passwd(&new_pwd, pwd);
- copy_id23_to_sam_passwd(&new_pwd, id23);
-
- memset(buf, 0, sizeof(pstring));
-
- if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash))
+
+ if (!pdb_getsampwrid(pwd, rid)) {
+ pdb_free_sam(pwd);
+ pdb_free_sam(new_pwd);
return False;
+ }
- new_pwd.smb_passwd = lm_hash;
- new_pwd.smb_nt_passwd = nt_hash;
+ acct_ctrl = pdb_get_acct_ctrl(pwd);
+ copy_sam_passwd(new_pwd, pwd);
+ pdb_free_sam(pwd);
+
+ copy_id23_to_sam_passwd(new_pwd, id23);
+
+ if (!decode_pw_buffer((char*)id23->pass, buf, 256, &len, nt_hash, lm_hash)) {
+ pdb_free_sam(new_pwd);
+ return False;
+ }
+
+ if (!pdb_set_lanman_passwd (new_pwd, lm_hash)) {
+ pdb_free_sam(new_pwd);
+ return False;
+ }
+ if (!pdb_set_nt_passwd(new_pwd, nt_hash)) {
+ pdb_free_sam(new_pwd);
+ return False;
+ }
+
/* if it's a trust account, don't update /etc/passwd */
- if ( ( (new_pwd.acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
- ( (new_pwd.acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
- ( (new_pwd.acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
+ if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
+ ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
+ ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
- } else {
-
+ } else {
/* update the UNIX password */
if (lp_unix_password_sync() )
- if(!chgpasswd(new_pwd.smb_name, "", buf, True))
+ if(!chgpasswd(pdb_get_username(new_pwd), "", buf, True)) {
+ pdb_free_sam(new_pwd);
return False;
+ }
}
-
+
memset(buf, 0, sizeof(buf));
-
- if(!mod_sam21pwd_entry(&new_pwd, True))
+
+ if(!pdb_update_sam_account(new_pwd, True)) {
+ pdb_free_sam(new_pwd);
return False;
-
+ }
+
+ pdb_free_sam(new_pwd);
+
return True;
}
@@ -2232,47 +2352,63 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
static BOOL set_user_info_pw(char *pass, uint32 rid)
{
- struct sam_passwd *pwd = getsam21pwrid(rid);
- struct sam_passwd new_pwd;
- static uchar nt_hash[16];
- static uchar lm_hash[16];
+ SAM_ACCOUNT *pwd = NULL;
+ uchar nt_hash[16];
+ uchar lm_hash[16];
uint32 len;
pstring buf;
-
- if (pwd == NULL)
+ uint16 acct_ctrl;
+
+ pdb_init_sam(&pwd);
+
+ if (!pdb_getsampwrid(pwd, rid)) {
+ pdb_free_sam(pwd);
return False;
+ }
+
+ acct_ctrl = pdb_get_acct_ctrl(pwd);
- pdb_init_sam(&new_pwd);
- copy_sam_passwd(&new_pwd, pwd);
-
- memset(buf, 0, sizeof(pstring));
-
- if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash))
+ memset(buf, 0, sizeof(buf));
+
+ if (!decode_pw_buffer(pass, buf, 256, &len, nt_hash, lm_hash)) {
+ pdb_free_sam(pwd);
return False;
+ }
- new_pwd.smb_passwd = lm_hash;
- new_pwd.smb_nt_passwd = nt_hash;
-
+ if (!pdb_set_lanman_passwd (pwd, lm_hash)) {
+ pdb_free_sam(pwd);
+ return False;
+ }
+ if (!pdb_set_nt_passwd(pwd, nt_hash)) {
+ pdb_free_sam(pwd);
+ return False;
+ }
+
/* if it's a trust account, don't update /etc/passwd */
- if ( ( (new_pwd.acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
- ( (new_pwd.acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
- ( (new_pwd.acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
+ if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
+ ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
+ ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
} else {
-
/* update the UNIX password */
- if (lp_unix_password_sync() )
- if(!chgpasswd(new_pwd.smb_name, "", buf, True))
+ if (lp_unix_password_sync())
+ if(!chgpasswd(pdb_get_username(pwd), "", buf, True)) {
+ pdb_free_sam(pwd);
return False;
+ }
}
-
+
memset(buf, 0, sizeof(buf));
-
+
DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
-
+
/* update the SAMBA password */
- if(!mod_sam21pwd_entry(&new_pwd, True))
+ if(!pdb_update_sam_account(pwd, True)) {
+ pdb_free_sam(pwd);
return False;
+ }
+
+ pdb_free_sam(pwd);
return True;
}
@@ -2286,15 +2422,16 @@ uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_
uint32 rid = 0x0;
DOM_SID sid;
struct current_user user;
- struct smb_passwd *smb_pass;
+ SAM_ACCOUNT *sam_pass=NULL;
unsigned char sess_key[16];
POLICY_HND *pol = &q_u->pol;
uint16 switch_value = q_u->switch_value;
SAM_USERINFO_CTR *ctr = q_u->ctr;
+ BOOL ret;
DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
if (p->ntlmssp_auth_validated) {
memcpy(&user, &p->pipe_user, sizeof(user));
@@ -2317,6 +2454,8 @@ uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_
}
+ pdb_init_sam(&sam_pass);
+
/*
* We need the NT hash of the user who is changing the user's password.
* This NT hash is used to generate a "user session key"
@@ -2324,21 +2463,18 @@ uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_
*/
become_root();
- smb_pass = getsmbpwuid(user.uid);
+ ret = pdb_getsampwuid(sam_pass, user.uid);
unbecome_root();
- if(smb_pass == NULL) {
+ if(ret == False) {
DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd entry for uid %u\n", (unsigned int)user.uid ));
+ pdb_free_sam(sam_pass);
return NT_STATUS_ACCESS_DENIED;
}
-
- if (smb_pass->smb_nt_passwd == NULL) {
- DEBUG(0,("_samr_set_userinfo: Unable to get smbpasswd NT password entry entry for uid %u\n",
- (unsigned int)user.uid ));
- return NT_STATUS_ACCESS_DENIED;
- }
-
+
memset(sess_key, '\0', 16);
- mdfour(sess_key, smb_pass->smb_nt_passwd, 16);
+ mdfour(sess_key, pdb_get_nt_passwd(sam_pass), 16);
+
+ pdb_free_sam(sam_pass);
/* ok! user info levels (lots: see MSDEV help), off we go... */
switch (switch_value) {
@@ -2352,7 +2488,7 @@ uint32 _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_
dump_data(100, (char *)ctr->info.id24->pass, 516);
- if (!set_user_info_pw((char *)(ctr->info.id24->pass), rid))
+ if (!set_user_info_pw((char *)ctr->info.id24->pass, rid))
return NT_STATUS_ACCESS_DENIED;
break;
@@ -2406,7 +2542,7 @@ uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SE
DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
if (!get_lsa_policy_samr_sid(p, pol, &sid))
@@ -2451,8 +2587,21 @@ uint32 _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SE
uint32 _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
{
- DEBUG(0,("_samr_query_useraliases: Not yet implemented.\n"));
- return False;
+ uint32 *rid=NULL;
+ int num_rids;
+
+ num_rids = 1;
+ rid=(uint32 *)talloc_zero(p->mem_ctx, num_rids*sizeof(uint32));
+ if (rid == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ /* until i see a real useraliases query, we fack one up */
+
+ rid[0] = BUILTIN_ALIAS_RID_USERS;
+
+ init_samr_r_query_useraliases(r_u, num_rids, rid, NT_STATUS_OK);
+
+ return r_u->status;
}
/*********************************************************************
@@ -2592,7 +2741,7 @@ uint32 _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SE
uint32 _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
{
/* Actually, returning zeros here works quite well :-). */
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/*********************************************************************
diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c
index 63bbc5f87b7..011efb1bace 100755
--- a/source/rpc_server/srv_spoolss.c
+++ b/source/rpc_server/srv_spoolss.c
@@ -1110,7 +1110,7 @@ static BOOL api_spoolss_addprintprocessor(pipes_struct *p)
automatically set the winprint processor for printer
entries later. Used to debug the LexMark Optra S 1855 PCL
driver --jerry */
- r_u.status = NT_STATUS_NO_PROBLEMO;
+ r_u.status = NT_STATUS_OK;
if(!spoolss_io_r_addprintprocessor("", &r_u, rdata, 0)) {
DEBUG(0,("spoolss_io_r_addprintprocessor: unable to marshall SPOOL_R_ADDPRINTPROCESSOR.\n"));
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 3fcb08891df..86f4fe77ac3 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -22,6 +22,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
+ up, all the errors returned are DOS errors, not NT status codes. */
+
#include "includes.h"
extern int DEBUGLEVEL;
@@ -31,6 +34,7 @@ extern pstring global_myname;
#define MAX_OPEN_PRINTER_EXS 50
#endif
+#define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
#define PRINTER_HANDLE_IS_PRINTER 0
#define PRINTER_HANDLE_IS_PRINTSERVER 1
@@ -272,12 +276,12 @@ static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
if (!Printer) {
DEBUG(0,("delete_printer_handle: Invalid handle (%s)\n", OUR_HANDLE(hnd)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
if (del_a_printer(Printer->dev.handlename) != 0) {
DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
/* Check calling user has permission to delete printer. Note that
@@ -287,7 +291,7 @@ static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
if (!print_access_check(NULL, -1, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(3, ("printer delete denied by security descriptor\n"));
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
if (*lp_deleteprinter_cmd()) {
@@ -305,7 +309,7 @@ static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
DEBUG(10,("Running [%s]\n", command));
ret = smbrun(command, NULL);
if (ret != 0) {
- return ERROR_INVALID_HANDLE; /* What to return here? */
+ return ERRbadfid; /* What to return here? */
}
DEBUGADD(10,("returned [%d]\n", ret));
@@ -314,12 +318,12 @@ static uint32 delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) >= 0 ) {
lp_killservice( i );
- return ERROR_SUCCESS;
+ return ERRsuccess;
} else
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
- return ERROR_SUCCESS;
+ return ERRsuccess;
}
/****************************************************************************
@@ -706,7 +710,7 @@ static BOOL srv_spoolss_sendnotify(pipes_struct *p, POLICY_HND *handle)
uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
{
#if 0
- uint32 result = NT_STATUS_NO_PROBLEMO;
+ uint32 result = ERRsuccess;
#endif
UNISTR2 *printername = NULL;
@@ -723,7 +727,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
printername = &q_u->printername;
if (printername == NULL)
- return ERROR_INVALID_PRINTER_NAME;
+ return ERRinvalidprintername;
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
@@ -732,7 +736,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
DEBUGADD(3,("checking name: %s\n",name));
if (!open_printer_hnd(p, handle, name))
- return ERROR_INVALID_PRINTER_NAME;
+ return ERRinvalidprintername;
/*
if (printer_default->datatype_ptr != NULL)
@@ -746,7 +750,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
if (!set_printer_hnd_accesstype(p, handle, printer_default->access_required)) {
close_printer_handle(p, handle);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
/*
@@ -776,7 +780,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
if (handle_is_printserver(p, handle)) {
if (printer_default->access_required == 0) {
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
else if ((printer_default->access_required & SERVER_ACCESS_ADMINISTER ) == SERVER_ACCESS_ADMINISTER) {
@@ -785,14 +789,14 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
if (!lp_ms_add_printer_wizard()) {
close_printer_handle(p, handle);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
else if (user.uid == 0 || user_in_list(uidtoname(user.uid), lp_printer_admin(snum))) {
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
else {
close_printer_handle(p, handle);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
}
}
@@ -802,16 +806,29 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
doesn't have print permission. */
if (!get_printer_snum(p, handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
/* map an empty access mask to the minimum access mask */
if (printer_default->access_required == 0x0)
printer_default->access_required = PRINTER_ACCESS_USE;
+
+
+ /*
+ * If we are not serving the printer driver for this printer,
+ * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
+ * will keep NT clients happy --jerry
+ */
+
+ if (lp_use_client_driver(snum)
+ && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
+ {
+ printer_default->access_required = PRINTER_ACCESS_USE;
+ }
if (!print_access_check(&user, snum, printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
close_printer_handle(p, handle);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
/*
@@ -890,7 +907,7 @@ uint32 _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
#endif
}
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -1008,7 +1025,7 @@ static uint32 _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handl
if (!Printer) {
DEBUG(0,("_spoolss_enddocprinter_internal: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
Printer->document_started=False;
@@ -1034,9 +1051,9 @@ uint32 _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R
memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
if (!close_printer_handle(p, handle))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -1058,7 +1075,7 @@ uint32 _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL
result = delete_printer_handle(p, handle);
- if (result == ERROR_SUCCESS) {
+ if (result == ERRsuccess) {
srv_spoolss_sendnotify(p, handle);
}
@@ -1120,20 +1137,20 @@ uint32 _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
/* check that we have a valid driver name first */
if ((version=get_version_id(arch)) == -1) {
/* this is what NT returns */
- return ERROR_INVALID_ENVIRONMENT;
+ return ERRinvalidenvironment;
}
ZERO_STRUCT(info);
if (get_a_printer_driver (&info, 3, driver, arch, version) != 0) {
/* this is what NT returns */
- return ERROR_UNKNOWN_PRINTER_DRIVER;
+ return ERRunknownprinterdriver;
}
if (printer_driver_in_use(arch, driver))
{
/* this is what NT returns */
- return ERROR_PRINTER_DRIVER_IN_USE;
+ return ERRprinterdriverinuse;
}
return delete_printer_driver(info.info_3);
@@ -1309,9 +1326,9 @@ uint32 _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
if (!Printer) {
if((*data=(uint8 *)malloc(4*sizeof(uint8))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
DEBUG(0,("_spoolss_getprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
unistr2_to_ascii(value, valuename, sizeof(value)-1);
@@ -1326,18 +1343,18 @@ uint32 _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
/* reply this param doesn't exist */
if (*out_size) {
if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
} else {
*data = NULL;
}
- return ERROR_INVALID_PARAMETER;
+ return ERRinvalidparam;
}
if (*needed > *out_size)
- return ERROR_MORE_DATA;
+ return ERRmoredata;
else {
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
}
@@ -1399,7 +1416,7 @@ uint32 _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
if (!Printer) {
DEBUG(0,("_spoolss_rffpcnex: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
Printer->notify.flags=flags;
@@ -1419,7 +1436,7 @@ uint32 _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
&Printer->notify.client_hnd))
Printer->notify.client_connected=True;
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/*******************************************************************
@@ -2209,7 +2226,7 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
uint16 type;
uint16 field;
- SPOOL_NOTIFY_INFO_DATA *current_data;
+ SPOOL_NOTIFY_INFO_DATA *current_data, *tid;
NT_PRINTER_INFO_LEVEL *printer = NULL;
print_queue_struct *queue=NULL;
@@ -2228,10 +2245,13 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int
if (!search_notify(type, field, &j) )
continue;
-
- if((info->data=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+
+ if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+ DEBUG(0,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
return False;
}
+ else info->data = tid;
+
current_data=&info->data[info->count];
construct_info_data(current_data, type, field, id);
@@ -2265,7 +2285,7 @@ static BOOL construct_notify_jobs_info(print_queue_struct *queue,
uint16 type;
uint16 field;
- SPOOL_NOTIFY_INFO_DATA *current_data;
+ SPOOL_NOTIFY_INFO_DATA *current_data, *tid;
DEBUG(4,("construct_notify_jobs_info\n"));
@@ -2281,9 +2301,11 @@ static BOOL construct_notify_jobs_info(print_queue_struct *queue,
if (!search_notify(type, field, &j) )
continue;
- if((info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+ if((tid=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+ DEBUG(0,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
return False;
- }
+ } else
+ info->data = tid;
current_data=&(info->data[info->count]);
@@ -2374,7 +2396,7 @@ static uint32 printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
}
*/
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/*******************************************************************
@@ -2457,7 +2479,7 @@ static uint32 printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
info->data[i].id, info->data[i].size, info->data[i].enc_type));
}
*/
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -2472,7 +2494,7 @@ uint32 _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
SPOOL_NOTIFY_INFO *info = &r_u->info;
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
- uint32 result = ERROR_INVALID_HANDLE;
+ uint32 result = ERRbadfid;
/* we always have a NOTIFY_INFO struct */
r_u->info_ptr=0x1;
@@ -2886,7 +2908,7 @@ static BOOL enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 of
int snum;
int i;
int n_services=lp_numservices();
- PRINTER_INFO_1 *printers=NULL;
+ PRINTER_INFO_1 *tp, *printers=NULL;
PRINTER_INFO_1 current_prt;
DEBUG(4,("enum_all_printers_info_1\n"));
@@ -2896,10 +2918,13 @@ static BOOL enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 of
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
if (construct_printer_info_1(flags, &current_prt, snum)) {
- if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
+ if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
+ DEBUG(0,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
+ safe_free(printers);
*returned=0;
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ return ERRnomem;
+ } else
+ printers = tp;
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_1));
(*returned)++;
@@ -2912,7 +2937,7 @@ static BOOL enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 of
(*needed) += spoolss_size_printer_info_1(&printers[i]);
if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
/* fill the buffer with the structures */
for (i=0; i<*returned; i++)
@@ -2923,10 +2948,10 @@ static BOOL enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 of
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -2954,7 +2979,7 @@ static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint
return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
}
else
- return ERROR_INVALID_NAME;
+ return ERRinvalidname;
}
/********************************************************************
@@ -2976,7 +3001,7 @@ static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, ui
*/
if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
*returned=1;
@@ -2994,7 +3019,7 @@ static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, ui
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(printer);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3005,10 +3030,10 @@ static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, ui
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -3033,7 +3058,7 @@ static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32
int snum;
int i;
int n_services=lp_numservices();
- PRINTER_INFO_2 *printers=NULL;
+ PRINTER_INFO_2 *tp, *printers=NULL;
PRINTER_INFO_2 current_prt;
for (snum=0; snum<n_services; snum++) {
@@ -3041,8 +3066,13 @@ static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
if (construct_printer_info_2(&current_prt, snum)) {
- if((printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) {
+ DEBUG(0,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
+ safe_free(printers);
+ *returned = 0;
+ return ERRnomem;
+ } else
+ printers = tp;
DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned));
memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_2));
(*returned)++;
@@ -3059,7 +3089,7 @@ static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32
free_devmode(printers[i].devmode);
}
safe_free(printers);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3074,10 +3104,10 @@ static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -3101,7 +3131,7 @@ static uint32 enumprinters_level1( uint32 flags, fstring name,
if (flags & PRINTER_ENUM_NETWORK)
return enum_all_printers_info_1_network(buffer, offered, needed, returned);
- return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */
+ return ERRsuccess; /* NT4sp5 does that */
}
/********************************************************************
@@ -3127,13 +3157,13 @@ static uint32 enumprinters_level2( uint32 flags, fstring servername,
if (strequal(servername, temp))
return enum_all_printers_info_2(buffer, offered, needed, returned);
else
- return ERROR_INVALID_NAME;
+ return ERRinvalidname;
}
if (flags & PRINTER_ENUM_REMOTE)
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -3144,7 +3174,7 @@ static uint32 enumprinters_level5( uint32 flags, fstring servername,
uint32 *needed, uint32 *returned)
{
/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -3200,7 +3230,7 @@ uint32 _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
case 3:
case 4:
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -3211,7 +3241,7 @@ static uint32 getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, u
PRINTER_INFO_0 *printer=NULL;
if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
construct_printer_info_0(printer, snum);
@@ -3220,7 +3250,7 @@ static uint32 getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, u
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(printer);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3230,10 +3260,10 @@ static uint32 getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, u
safe_free(printer);
if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3243,7 +3273,7 @@ static uint32 getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, u
PRINTER_INFO_1 *printer=NULL;
if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
construct_printer_info_1(PRINTER_ENUM_ICON8, printer, snum);
@@ -3252,7 +3282,7 @@ static uint32 getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, u
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(printer);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3262,10 +3292,10 @@ static uint32 getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, u
safe_free(printer);
if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3275,7 +3305,7 @@ static uint32 getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, u
PRINTER_INFO_2 *printer=NULL;
if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
construct_printer_info_2(printer, snum);
@@ -3284,23 +3314,23 @@ static uint32 getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, u
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_info_2(printer);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
if (!smb_io_printer_info_2("", buffer, printer, 0)) {
free_printer_info_2(printer);
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
/* clear memory */
free_printer_info_2(printer);
if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3310,14 +3340,14 @@ static uint32 getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, u
PRINTER_INFO_3 *printer=NULL;
if (!construct_printer_info_3(&printer, snum))
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
/* check the required size. */
*needed += spoolss_size_printer_info_3(printer);
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_info_3(printer);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3327,10 +3357,10 @@ static uint32 getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, u
free_printer_info_3(printer);
if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3353,7 +3383,7 @@ uint32 _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
*needed=0;
if (!get_printer_snum(p, handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
switch (level) {
case 0:
@@ -3365,7 +3395,7 @@ uint32 _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
case 3:
return getprinter_level_3(snum, buffer, offered, needed);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -3388,16 +3418,16 @@ static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fst
ZERO_STRUCT(driver);
if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
- return ERROR_INVALID_PRINTER_NAME;
+ return ERRinvalidprintername;
if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
- return ERROR_UNKNOWN_PRINTER_DRIVER;
+ return ERRunknownprinterdriver;
fill_printer_driver_info_1(info, driver, servername, architecture);
free_a_printer(&printer,2);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -3446,16 +3476,16 @@ static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fst
ZERO_STRUCT(driver);
if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
- return ERROR_INVALID_PRINTER_NAME;
+ return ERRinvalidprintername;
if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
- return ERROR_UNKNOWN_PRINTER_DRIVER;
+ return ERRunknownprinterdriver;
fill_printer_driver_info_2(info, driver, servername);
free_a_printer(&printer,2);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -3469,6 +3499,7 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *ser
int j=0;
char *v;
pstring line;
+ uint16 *tuary;
DEBUG(6,("init_unistr_array\n"));
*uni_array=NULL;
@@ -3483,10 +3514,11 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *ser
if (strlen(v) == 0) break;
slprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
- if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
+ if((tuary=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
DEBUG(0,("init_unistr_array: Realloc error\n" ));
return;
- }
+ } else
+ *uni_array = tuary;
j += (dos_PutUniCode((char *)(*uni_array+j), line , sizeof(uint16)*strlen(line), True) / sizeof(uint16) );
i++;
}
@@ -3558,20 +3590,20 @@ static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst
status=get_a_printer(&printer, 2, lp_servicename(snum) );
DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
if (status != 0)
- return ERROR_INVALID_PRINTER_NAME;
+ return ERRinvalidprintername;
status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
if (status != 0) {
free_a_printer(&printer,2);
- return ERROR_UNKNOWN_PRINTER_DRIVER;
+ return ERRunknownprinterdriver;
}
fill_printer_driver_info_3(info, driver, servername);
free_a_printer(&printer,2);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -3652,7 +3684,7 @@ static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fst
status=get_a_printer(&printer, 2, lp_servicename(snum) );
DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
if (status != 0)
- return ERROR_INVALID_PRINTER_NAME;
+ return ERRinvalidprintername;
status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
@@ -3663,7 +3695,7 @@ static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fst
if (version < 3) {
free_a_printer(&printer,2);
- return ERROR_UNKNOWN_PRINTER_DRIVER;
+ return ERRunknownprinterdriver;
}
/* Yes - try again with a WinNT driver. */
@@ -3672,7 +3704,7 @@ static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fst
DEBUG(8,("construct_printer_driver_info_6: status: %d\n", status));
if (status != 0) {
free_a_printer(&printer,2);
- return ERROR_UNKNOWN_PRINTER_DRIVER;
+ return ERRunknownprinterdriver;
}
}
@@ -3680,7 +3712,7 @@ static uint32 construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, fst
free_a_printer(&printer,2);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3708,10 +3740,10 @@ static uint32 getprinterdriver2_level1(fstring servername, fstring architecture,
uint32 status;
if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
- if (status != NT_STATUS_NO_PROBLEMO) {
+ if (status != ERRsuccess) {
safe_free(info);
return status;
}
@@ -3721,7 +3753,7 @@ static uint32 getprinterdriver2_level1(fstring servername, fstring architecture,
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(info);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3731,9 +3763,9 @@ static uint32 getprinterdriver2_level1(fstring servername, fstring architecture,
safe_free(info);
if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3744,10 +3776,10 @@ static uint32 getprinterdriver2_level2(fstring servername, fstring architecture,
uint32 status;
if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
- if (status != NT_STATUS_NO_PROBLEMO) {
+ if (status != ERRsuccess) {
safe_free(info);
return status;
}
@@ -3757,7 +3789,7 @@ static uint32 getprinterdriver2_level2(fstring servername, fstring architecture,
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(info);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3767,9 +3799,9 @@ static uint32 getprinterdriver2_level2(fstring servername, fstring architecture,
safe_free(info);
if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3782,7 +3814,7 @@ static uint32 getprinterdriver2_level3(fstring servername, fstring architecture,
ZERO_STRUCT(info);
status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
- if (status != NT_STATUS_NO_PROBLEMO) {
+ if (status != ERRsuccess) {
return status;
}
@@ -3791,7 +3823,7 @@ static uint32 getprinterdriver2_level3(fstring servername, fstring architecture,
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_driver_info_3(&info);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3800,9 +3832,9 @@ static uint32 getprinterdriver2_level3(fstring servername, fstring architecture,
free_printer_driver_info_3(&info);
if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3815,7 +3847,7 @@ static uint32 getprinterdriver2_level6(fstring servername, fstring architecture,
ZERO_STRUCT(info);
status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
- if (status != NT_STATUS_NO_PROBLEMO) {
+ if (status != ERRsuccess) {
return status;
}
@@ -3824,7 +3856,7 @@ static uint32 getprinterdriver2_level6(fstring servername, fstring architecture,
if (!alloc_buffer_size(buffer, *needed)) {
free_printer_driver_info_6(&info);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -3833,9 +3865,9 @@ static uint32 getprinterdriver2_level6(fstring servername, fstring architecture,
free_printer_driver_info_6(&info);
if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -3872,7 +3904,7 @@ uint32 _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
if (!get_printer_snum(p, handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
switch (level) {
case 1:
@@ -3884,7 +3916,7 @@ uint32 _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
case 6:
return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -3903,7 +3935,7 @@ uint32 _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u,
}
DEBUG(3,("Error in startpageprinter printer handle\n"));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
/****************************************************************************
@@ -3917,12 +3949,12 @@ uint32 _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPO
if (!Printer) {
DEBUG(0,("_spoolss_endpageprinter: Invalid handle (%s).\n",OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
Printer->page_started=False;
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/********************************************************************
@@ -3947,7 +3979,7 @@ uint32 _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
if (!Printer) {
DEBUG(0,("_spoolss_startdocprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
get_current_user(&user, p);
@@ -3968,13 +4000,13 @@ uint32 _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
if (strcmp(datatype, "RAW") != 0) {
(*jobid)=0;
- return ERROR_INVALID_DATATYPE;
+ return ERRinvaliddatatype;
}
}
/* get the share number of the printer */
if (!get_printer_snum(p, handle, &snum)) {
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
@@ -4022,7 +4054,7 @@ uint32 _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
if (!Printer) {
DEBUG(0,("_spoolss_writeprinter: Invalid handle (%s)\n",OUR_HANDLE(handle)));
r_u->buffer_written = q_u->buffer_size2;
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
(*buffer_written) = print_job_write(Printer->jobid, (char *)buffer, buffer_size);
@@ -4042,18 +4074,18 @@ static uint32 control_printer(POLICY_HND *handle, uint32 command,
pipes_struct *p)
{
struct current_user user;
- int snum, errcode = ERROR_INVALID_FUNCTION;
+ int snum, errcode = ERRbadfunc;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
get_current_user(&user, p);
if (!Printer) {
DEBUG(0,("control_printer: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
if (!get_printer_snum(p, handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
switch (command) {
case PRINTER_CONTROL_PAUSE:
@@ -4073,7 +4105,7 @@ static uint32 control_printer(POLICY_HND *handle, uint32 command,
}
break;
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
return errcode;
@@ -4109,7 +4141,7 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
DEBUG(0,("update_printer_sec: Invalid handle (%s)\n",
OUR_HANDLE(handle)));
- result = ERROR_INVALID_HANDLE;
+ result = ERRbadfid;
goto done;
}
@@ -4159,7 +4191,7 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) {
- result = NT_STATUS_NO_PROBLEMO;
+ result = ERRsuccess;
goto done;
}
@@ -4173,7 +4205,7 @@ static uint32 update_printer_sec(POLICY_HND *handle, uint32 level,
information. */
if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
- result = ERROR_ACCESS_DENIED;
+ result = ERRnoaccess;
goto done;
}
@@ -4519,28 +4551,28 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
DEBUG(8,("update_printer\n"));
- result = NT_STATUS_NO_PROBLEMO;
+ result = ERRsuccess;
if (level!=2) {
DEBUG(0,("Send a mail to samba@samba.org\n"));
DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
- result = ERROR_INVALID_LEVEL;
+ result = ERRunknownlevel;
goto done;
}
if (!Printer) {
- result = ERROR_INVALID_HANDLE;
+ result = ERRbadfid;
goto done;
}
if (!get_printer_snum(p, handle, &snum)) {
- result = ERROR_INVALID_HANDLE;
+ result = ERRbadfid;
goto done;
}
if((get_a_printer(&printer, 2, lp_servicename(snum)) != 0) ||
(get_a_printer(&old_printer, 2, lp_servicename(snum)) != 0)) {
- result = ERROR_INVALID_HANDLE;
+ result = ERRbadfid;
goto done;
}
@@ -4561,7 +4593,7 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
DEBUGADD(8,("Converting the devicemode struct\n"));
if (!convert_devicemode(printer->info_2->printername, devmode,
&printer->info_2->devmode)) {
- result = ERROR_NOT_ENOUGH_MEMORY;
+ result = ERRnomem;
goto done;
}
}
@@ -4569,7 +4601,7 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
/* Do sanity check on the requested changes for Samba */
if (!check_printer_ok(printer->info_2, snum)) {
- result = ERROR_INVALID_PARAMETER;
+ result = ERRinvalidparam;
goto done;
}
@@ -4579,7 +4611,7 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
if (nt_printer_info_level_equal(printer, old_printer)) {
DEBUG(3, ("printer info has not changed\n"));
- result = NT_STATUS_NO_PROBLEMO;
+ result = ERRsuccess;
goto done;
}
@@ -4588,7 +4620,7 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(3, ("printer property change denied by security "
"descriptor\n"));
- result = ERROR_ACCESS_DENIED;
+ result = ERRnoaccess;
goto done;
}
@@ -4596,7 +4628,7 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
if (*lp_addprinter_cmd() )
if ( !add_printer_hook(printer) ) {
- result = ERROR_ACCESS_DENIED;
+ result = ERRnoaccess;
goto done;
}
@@ -4604,7 +4636,7 @@ static uint32 update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
if (add_a_printer(*printer, 2)!=0) {
/* I don't really know what to return here !!! */
- result = ERROR_ACCESS_DENIED;
+ result = ERRnoaccess;
goto done;
}
@@ -4633,7 +4665,7 @@ uint32 _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
if (!Printer) {
DEBUG(0,("_spoolss_setprinter: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
/* check the level */
@@ -4646,7 +4678,7 @@ uint32 _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
return update_printer_sec(handle, level, info, p,
secdesc_ctr);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -4661,7 +4693,7 @@ uint32 _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
if (!Printer) {
DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
if (Printer->notify.client_connected==True)
@@ -4675,7 +4707,7 @@ uint32 _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
free_spool_notify_option(&Printer->notify.option);
Printer->notify.client_connected=False;
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -4687,7 +4719,7 @@ uint32 _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u
spoolss_move_buffer(q_u->buffer, &r_u->buffer);
r_u->needed = 0;
- return ERROR_INVALID_PARAMETER; /* this is what a NT server
+ return ERRinvalidparam; /* this is what a NT server
returns for AddJob. AddJob
must fail on non-local
printers */
@@ -4784,7 +4816,7 @@ static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
if (info==NULL) {
safe_free(queue);
*returned=0;
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
for (i=0; i<*returned; i++)
@@ -4798,7 +4830,7 @@ static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(info);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -4810,10 +4842,10 @@ static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -4830,12 +4862,12 @@ static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
if (info==NULL) {
*returned=0;
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0) {
*returned = 0;
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
for (i=0; i<*returned; i++)
@@ -4850,7 +4882,7 @@ static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(info);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the structures */
@@ -4865,10 +4897,10 @@ static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -4902,14 +4934,14 @@ uint32 _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
*returned=0;
if (!get_printer_snum(p, handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
*returned = print_queue_status(snum, &queue, &prt_status);
DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
if (*returned == 0) {
safe_free(queue);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
switch (level) {
@@ -4920,7 +4952,7 @@ uint32 _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
default:
safe_free(queue);
*returned=0;
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -4945,16 +4977,16 @@ uint32 _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
struct current_user user;
print_status_struct prt_status;
- int snum, errcode = ERROR_INVALID_FUNCTION;
+ int snum, errcode = ERRbadfunc;
memset(&prt_status, 0, sizeof(prt_status));
if (!get_printer_snum(p, handle, &snum)) {
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
if (!print_job_exists(jobid)) {
- return ERROR_INVALID_PRINTER_NAME;
+ return ERRinvalidprintername;
}
get_current_user(&user, p);
@@ -4978,7 +5010,7 @@ uint32 _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
}
break;
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
return errcode;
@@ -4995,7 +5027,7 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
fstring *list = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- DRIVER_INFO_1 *driver_info_1=NULL;
+ DRIVER_INFO_1 *tdi1, *driver_info_1=NULL;
*returned=0;
@@ -5007,13 +5039,16 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
if(ndrivers == -1)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
if(ndrivers != 0) {
- if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
+ if((tdi1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
+ DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
+ safe_free(driver_info_1);
safe_free(list);
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ return ERRnomem;
+ } else
+ driver_info_1 = tdi1;
}
for (i=0; i<ndrivers; i++) {
@@ -5040,7 +5075,7 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(driver_info_1);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the driver structures */
@@ -5053,10 +5088,10 @@ static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -5070,7 +5105,7 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
fstring *list = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- DRIVER_INFO_2 *driver_info_2=NULL;
+ DRIVER_INFO_2 *tdi2, *driver_info_2=NULL;
*returned=0;
@@ -5082,13 +5117,16 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
if(ndrivers == -1)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
if(ndrivers != 0) {
- if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
+ if((tdi2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
+ DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
+ safe_free(driver_info_2);
safe_free(list);
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ return ERRnomem;
+ } else
+ driver_info_2 = tdi2;
}
for (i=0; i<ndrivers; i++) {
@@ -5116,7 +5154,7 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(driver_info_2);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the form structures */
@@ -5129,10 +5167,10 @@ static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -5146,7 +5184,7 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
fstring *list = NULL;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- DRIVER_INFO_3 *driver_info_3=NULL;
+ DRIVER_INFO_3 *tdi3, *driver_info_3=NULL;
*returned=0;
@@ -5158,13 +5196,16 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
if(ndrivers == -1)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
if(ndrivers != 0) {
- if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
+ if((tdi3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
+ DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
+ safe_free(driver_info_3);
safe_free(list);
- return ERROR_NOT_ENOUGH_MEMORY;
- }
+ return ERRnomem;
+ } else
+ driver_info_3 = tdi3;
}
for (i=0; i<ndrivers; i++) {
@@ -5192,7 +5233,7 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(driver_info_3);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the driver structures */
@@ -5208,10 +5249,10 @@ static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -5253,7 +5294,7 @@ uint32 _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
default:
*returned=0;
safe_free(list);
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -5305,13 +5346,13 @@ uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
*numofforms += numbuiltinforms;
- if (*numofforms == 0) return ERROR_NO_MORE_ITEMS;
+ if (*numofforms == 0) return ERRnomoreitems;
switch (level) {
case 1:
if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
*numofforms=0;
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
/* construct the list of form structures */
@@ -5343,7 +5384,7 @@ uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
if (!alloc_buffer_size(buffer, buffer_size)){
safe_free(forms_1);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the form structures */
@@ -5360,15 +5401,15 @@ uint32 _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
if (*needed > offered) {
*numofforms=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
default:
safe_free(list);
safe_free(builtinlist);
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -5409,7 +5450,7 @@ uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
DEBUGADD(5,("Number of forms [%d]\n", numofforms));
if (numofforms == 0)
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
switch (level) {
@@ -5432,7 +5473,7 @@ uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
safe_free(list);
if (i == numofforms) {
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
}
/* check the required size. */
@@ -5440,22 +5481,22 @@ uint32 _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
*needed=spoolss_size_form_1(&form_1);
if (!alloc_buffer_size(buffer, buffer_size)){
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the form structures */
DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
smb_io_form_1("", buffer, &form_1, 0);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
default:
safe_free(list);
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -5503,7 +5544,7 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if (fd != -1)
close(fd);
/* Is this the best error to return here? */
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
numlines = 0;
@@ -5513,9 +5554,9 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if(numlines) {
if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
- DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
+ DEBUG(10,("Returning ERRnomem [%x]\n", ERRnomem));
file_lines_free(qlines);
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
for (i=0; i<numlines; i++) {
@@ -5532,7 +5573,7 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
*returned = 1; /* Sole Samba port returned. */
if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
@@ -5547,7 +5588,7 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(ports);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the ports structures */
@@ -5560,10 +5601,10 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -5601,7 +5642,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if (fd != -1)
close(fd);
/* Is this the best error to return here? */
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
numlines = 0;
@@ -5611,9 +5652,9 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if(numlines) {
if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
- DEBUG(10,("Returning ERROR_NOT_ENOUGH_MEMORY [%x]\n", ERROR_NOT_ENOUGH_MEMORY));
+ DEBUG(10,("Returning ERRnomem [%x]\n", ERRnomem));
file_lines_free(qlines);
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
for (i=0; i<numlines; i++) {
@@ -5631,7 +5672,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
*returned = 1;
if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
@@ -5646,7 +5687,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(ports);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
/* fill the buffer with the ports structures */
@@ -5659,10 +5700,10 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -5693,7 +5734,7 @@ uint32 _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUM
case 2:
return enumports_level_2(buffer, offered, needed, returned);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -5711,7 +5752,7 @@ static uint32 spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
ZERO_STRUCTP(printer);
@@ -5722,7 +5763,7 @@ static uint32 spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
if (*lp_addprinter_cmd() )
if ( !add_printer_hook(printer) ) {
free_a_printer(&printer,2);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname,
@@ -5730,13 +5771,13 @@ static uint32 spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
free_a_printer(&printer,2);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
/* you must be a printer admin to add a new printer */
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
free_a_printer(&printer,2);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
/*
@@ -5745,27 +5786,34 @@ static uint32 spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
if (!check_printer_ok(printer->info_2, snum)) {
free_a_printer(&printer,2);
- return ERROR_INVALID_PARAMETER;
+ return ERRinvalidparam;
}
+ /*
+ * When a printer is created, the drivername bound to the printer is used
+ * to lookup previously saved driver initialization info, which is then
+ * bound to the new printer, simulating what happens in the Windows arch.
+ */
+ set_driver_init(printer, 2);
+
/* write the ASCII on disk */
if (add_a_printer(*printer, 2) != 0) {
free_a_printer(&printer,2);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
if (!open_printer_hnd(p, handle, name)) {
/* Handle open failed - remove addition. */
del_a_printer(printer->info_2->sharename);
free_a_printer(&printer,2);
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
free_a_printer(&printer,2);
srv_spoolss_sendnotify(p, handle);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -5788,13 +5836,13 @@ uint32 _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_
case 1:
/* we don't handle yet */
/* but I know what to do ... */
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
case 2:
return spoolss_addprinterex_level_2(p, uni_srv_name, info,
unk0, unk1, unk2, unk3,
user_switch, user, handle);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -5807,7 +5855,7 @@ uint32 _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
uint32 level = q_u->level;
SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
- uint32 err = NT_STATUS_NO_PROBLEMO;
+ uint32 err = ERRsuccess;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
struct current_user user;
@@ -5818,18 +5866,18 @@ uint32 _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
convert_printer_driver_info(info, &driver, level);
DEBUG(5,("Cleaning driver's information\n"));
- if ((err = clean_up_driver_struct(driver, level, &user)) != NT_STATUS_NO_PROBLEMO )
+ if ((err = clean_up_driver_struct(driver, level, &user)) != ERRsuccess )
goto done;
DEBUG(5,("Moving driver to final destination\n"));
if(!move_driver_to_download_area(driver, level, &user, &err)) {
if (err == 0)
- err = ERROR_ACCESS_DENIED;
+ err = ERRnoaccess;
goto done;
}
if (add_a_printer_driver(driver, level)!=0) {
- err = ERROR_ACCESS_DENIED;
+ err = ERRnoaccess;
goto done;
}
@@ -5856,11 +5904,11 @@ static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
- if (get_short_archi(short_archi, long_archi)==FALSE)
- return ERROR_INVALID_ENVIRONMENT;
+ if (get_short_archi(short_archi, long_archi)==False)
+ return ERRinvalidenvironment;
if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
@@ -5872,7 +5920,7 @@ static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(info);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
smb_io_driverdir_1("", buffer, info, 0);
@@ -5880,9 +5928,9 @@ static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
safe_free(info);
if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -5909,7 +5957,7 @@ uint32 _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI
case 1:
return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -5959,14 +6007,14 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if (!Printer) {
DEBUG(0,("_spoolss_enumprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
if (!get_printer_snum(p,handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
/*
* The NT machine wants to know the biggest size of value and data
@@ -5989,7 +6037,7 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
safe_free(data);
free_a_printer(&printer, 2);
- return ERROR_NO_MORE_ITEMS;
+ return ERRnomoreitems;
}
#endif
@@ -6020,7 +6068,7 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if (param_index == 0) {
/* No parameters found. */
free_a_printer(&printer, 2);
- return ERROR_NO_MORE_ITEMS;
+ return ERRnomoreitems;
}
/* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
@@ -6030,7 +6078,7 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
free_a_printer(&printer, 2);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/*
@@ -6041,7 +6089,7 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
if (!get_specific_param_by_index(*printer, 2, idx, value, &data, &type, &data_len)) {
safe_free(data);
free_a_printer(&printer, 2);
- return ERROR_NO_MORE_ITEMS;
+ return ERRnomoreitems;
}
free_a_printer(&printer, 2);
@@ -6058,7 +6106,7 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
*out_max_value_len=(in_value_len/sizeof(uint16));
if((*out_value=(uint16 *)talloc_zero(p->mem_ctx,in_value_len*sizeof(uint8))) == NULL) {
safe_free(data);
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
*out_value_len = (uint32)dos_PutUniCode((char *)*out_value, value, in_value_len, True);
@@ -6069,7 +6117,7 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
*out_max_data_len=in_data_len;
if((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) {
safe_free(data);
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
memcpy(*data_out, data, (size_t)data_len);
@@ -6077,7 +6125,7 @@ uint32 _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
safe_free(data);
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -6103,22 +6151,41 @@ uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
if (!Printer) {
DEBUG(0,("_spoolss_setprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
if (!get_printer_snum(p,handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
+
+ ZERO_STRUCT(old_param);
+
+ /*
+ * Access check : NT returns "access denied" if you make a
+ * SetPrinterData call without the necessary privildge.
+ * we were originally returning OK if nothing changed
+ * which made Win2k issue **a lot** of SetPrinterData
+ * when connecting to a printer --jerry
+ */
+
+ if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
+ DEBUG(3, ("security descriptor change denied by existing "
+ "security descriptor\n"));
+ status = ERRnoaccess;
+ goto done;
+ }
+
+
+ /* Check if we are making any changes or not. Return true if
+ nothing is actually changing. This is not needed anymore but
+ has been left in as an optimization to keep from from
+ writing to disk as often --jerry */
status = get_a_printer(&printer, 2, lp_servicename(snum));
if (status != 0x0)
- return ERROR_INVALID_NAME;
+ return ERRinvalidname;
convert_specific_param(&param, value , type, data, real_len);
- /* Check if we are making any changes or not. Return true if
- nothing is actually changing. */
-
- ZERO_STRUCT(old_param);
if (get_specific_param(*printer, 2, param->value, &old_param.data,
&old_param.type, (uint32 *)&old_param.data_len)) {
@@ -6129,24 +6196,28 @@ uint32 _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
old_param.data_len) == 0) {
DEBUG(3, ("setprinterdata hasn't changed\n"));
- status = NT_STATUS_NO_PROBLEMO;
+ status = ERRsuccess;
goto done;
}
}
- /* Access check */
-
- if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
- DEBUG(3, ("security descriptor change denied by existing "
- "security descriptor\n"));
- status = ERROR_ACCESS_DENIED;
- goto done;
- }
-
unlink_specific_param_if_exist(printer->info_2, param);
- add_a_specific_param(printer->info_2, &param);
- status = mod_a_printer(*printer, 2);
+ /*
+ * When client side code sets a magic printer data key, detect it and save
+ * the current printer data and the magic key's data (its the DEVMODE) for
+ * future printer/driver initializations.
+ */
+ if (param->type==3 && !strcmp( param->value, PHANTOM_DEVMODE_KEY)) {
+ /*
+ * Set devmode and printer initialization info
+ */
+ status = save_driver_init(printer, 2, param);
+ }
+ else {
+ add_a_specific_param(printer->info_2, &param);
+ status = mod_a_printer(*printer, 2);
+ }
done:
free_a_printer(&printer, 2);
@@ -6175,27 +6246,27 @@ uint32 _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
if (!Printer) {
DEBUG(0,("_spoolss_deleteprinterdata: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
if (!get_printer_snum(p, handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(3, ("_spoolss_deleteprinterdata: printer properties "
"change denied by existing security descriptor\n"));
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
status = get_a_printer(&printer, 2, lp_servicename(snum));
if (status != 0x0)
- return ERROR_INVALID_NAME;
+ return ERRinvalidname;
ZERO_STRUCTP(&param);
unistr2_to_ascii(param.value, value, sizeof(param.value)-1);
if(!unlink_specific_param_if_exist(printer->info_2, &param))
- status = ERROR_INVALID_PARAMETER;
+ status = ERRinvalidparam;
else
status = mod_a_printer(*printer, 2);
@@ -6221,17 +6292,17 @@ uint32 _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM
if (!Printer) {
DEBUG(0,("_spoolss_addform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
/* can't add if builtin */
if (get_a_builtin_ntform(&form->name,&tmpForm)) {
- return ERROR_INVALID_PARAMETER;
+ return ERRinvalidparam;
}
count=get_ntforms(&list);
if(!add_a_form(&list, form, &count))
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
write_ntforms(&list, count);
safe_free(list);
@@ -6256,17 +6327,17 @@ uint32 _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DE
if (!Printer) {
DEBUG(0,("_spoolss_deleteform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
/* can't delete if builtin */
if (get_a_builtin_ntform(form_name,&tmpForm)) {
- return ERROR_INVALID_PARAMETER;
+ return ERRinvalidparam;
}
count = get_ntforms(&list);
if(!delete_a_form(&list, form_name, &count, &ret))
- return ERROR_INVALID_PARAMETER;
+ return ERRinvalidparam;
safe_free(list);
@@ -6292,11 +6363,11 @@ uint32 _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *
if (!Printer) {
DEBUG(0,("_spoolss_setform: Invalid handle (%s).\n", OUR_HANDLE(handle)));
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
}
/* can't set if builtin */
if (get_a_builtin_ntform(&form->name,&tmpForm)) {
- return ERROR_INVALID_PARAMETER;
+ return ERRinvalidparam;
}
count=get_ntforms(&list);
@@ -6316,7 +6387,7 @@ static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
PRINTPROCESSOR_1 *info_1=NULL;
if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
(*returned) = 0x1;
@@ -6325,7 +6396,7 @@ static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
*needed += spoolss_size_printprocessor_info_1(info_1);
if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
smb_io_printprocessor_info_1("", buffer, info_1, 0);
@@ -6333,10 +6404,10 @@ static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -6372,7 +6443,7 @@ uint32 _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS
case 1:
return enumprintprocessors_level_1(buffer, offered, needed, returned);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -6384,7 +6455,7 @@ static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
PRINTPROCDATATYPE_1 *info_1=NULL;
if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
(*returned) = 0x1;
@@ -6393,7 +6464,7 @@ static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
*needed += spoolss_size_printprocdatatype_info_1(info_1);
if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
@@ -6401,10 +6472,10 @@ static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -6433,7 +6504,7 @@ uint32 _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT
case 1:
return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -6446,7 +6517,7 @@ static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint
PRINTMONITOR_1 *info_1=NULL;
if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
(*returned) = 0x1;
@@ -6455,7 +6526,7 @@ static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint
*needed += spoolss_size_printmonitor_info_1(info_1);
if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
smb_io_printmonitor_info_1("", buffer, info_1, 0);
@@ -6463,10 +6534,10 @@ static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -6477,7 +6548,7 @@ static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
PRINTMONITOR_2 *info_2=NULL;
if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
(*returned) = 0x1;
@@ -6488,7 +6559,7 @@ static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
*needed += spoolss_size_printmonitor_info_2(info_2);
if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
smb_io_printmonitor_info_2("", buffer, info_2, 0);
@@ -6496,10 +6567,10 @@ static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
if (*needed > offered) {
*returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -6536,7 +6607,7 @@ uint32 _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
case 2:
return enumprintmonitors_level_2(buffer, offered, needed, returned);
default:
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
@@ -6552,7 +6623,7 @@ static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uin
if (info_1 == NULL) {
safe_free(queue);
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
for (i=0; i<count && found==False; i++) {
@@ -6563,8 +6634,8 @@ static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uin
if (found==False) {
safe_free(queue);
safe_free(info_1);
- /* I shoud reply something else ... I can't find the good one */
- return NT_STATUS_NO_PROBLEMO;
+ /* NT treats not found as bad param... yet another bad choice */
+ return ERRinvalidparam;
}
fill_job_info_1(info_1, &(queue[i-1]), i, snum);
@@ -6575,7 +6646,7 @@ static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uin
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(info_1);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
smb_io_job_info_1("", buffer, info_1, 0);
@@ -6583,9 +6654,9 @@ static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uin
safe_free(info_1);
if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
@@ -6604,7 +6675,7 @@ static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uin
if (info_2 == NULL) {
safe_free(queue);
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
for (i=0; i<count && found==False; i++) {
@@ -6615,13 +6686,13 @@ static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uin
if (found==False) {
safe_free(queue);
safe_free(info_2);
- /* I shoud reply something else ... I can't find the good one */
- return NT_STATUS_NO_PROBLEMO;
+ /* NT treats not found as bad param... yet another bad choice */
+ return ERRinvalidparam;
}
if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0) {
safe_free(queue);
- return ERROR_NOT_ENOUGH_MEMORY;
+ return ERRnomem;
}
fill_job_info_2(info_2, &(queue[i-1]), i, snum, ntprinter);
@@ -6633,7 +6704,7 @@ static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uin
if (!alloc_buffer_size(buffer, *needed)) {
safe_free(info_2);
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
}
smb_io_job_info_2("", buffer, info_2, 0);
@@ -6642,9 +6713,9 @@ static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uin
free(info_2);
if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
+ return ERRinsufficientbuffer;
else
- return NT_STATUS_NO_PROBLEMO;
+ return ERRsuccess;
}
/****************************************************************************
@@ -6675,7 +6746,7 @@ uint32 _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
*needed=0;
if (!get_printer_snum(p, handle, &snum))
- return ERROR_INVALID_HANDLE;
+ return ERRbadfid;
count = print_queue_status(snum, &queue, &prt_status);
@@ -6689,6 +6760,6 @@ uint32 _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
return getjob_level_2(queue, count, snum, jobid, buffer, offered, needed);
default:
safe_free(queue);
- return ERROR_INVALID_LEVEL;
+ return ERRunknownlevel;
}
}
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index b487eb1c824..b50cdf3dc4d 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -33,7 +33,7 @@ extern pstring global_myname;
Fill in a share info level 1 structure.
********************************************************************/
-static void init_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, int snum)
+static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum)
{
int len_net_name;
pstring net_name;
@@ -42,7 +42,7 @@ static void init_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, int snum)
pstrcpy(net_name, lp_servicename(snum));
pstrcpy(remark, lp_comment(snum));
- pstring_sub(remark,"%S",lp_servicename(snum));
+ standard_sub_conn(p->conn, remark);
len_net_name = strlen(net_name);
/* work out the share type */
@@ -63,7 +63,7 @@ static void init_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, int snum)
Fill in a share info level 2 structure.
********************************************************************/
-static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum)
+static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum)
{
int len_net_name;
pstring net_name;
@@ -74,7 +74,7 @@ static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum)
pstrcpy(net_name, lp_servicename(snum));
pstrcpy(remark, lp_comment(snum));
- pstring_sub(remark,"%S",lp_servicename(snum));
+ standard_sub_conn(p->conn, remark);
pstrcpy(path, "C:");
pstrcat(path, lp_pathname(snum));
@@ -125,7 +125,7 @@ BOOL share_info_db_init(void)
char *vstring = "INFO/version";
if (share_tdb && local_pid == sys_getpid()) return True;
- share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
+ share_tdb = tdb_open_log(lock_path("share_info.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!share_tdb) {
DEBUG(0,("Failed to open share info database %s (%s)\n",
lock_path("share_info.tdb"), strerror(errno) ));
@@ -226,7 +226,7 @@ static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC
prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL);
- if (!sec_io_desc("nt_printing_setsec", &psd, &ps, 1)) {
+ if (!sec_io_desc("share_security", &psd, &ps, 1)) {
goto out;
}
@@ -307,8 +307,7 @@ BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 d
TALLOC_CTX *mem_ctx = NULL;
SEC_DESC *psd = NULL;
size_t sd_size;
- struct current_user tmp_user;
- struct current_user *puser = NULL;
+ NT_USER_TOKEN *token = NULL;
user_struct *vuser = get_valid_user_struct(vuid);
BOOL ret = True;
@@ -321,26 +320,12 @@ BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 d
if (!psd)
goto out;
- ZERO_STRUCT(tmp_user);
- if (vuser) {
- tmp_user.vuid = vuid;
- tmp_user.uid = vuser->uid;
- tmp_user.gid = vuser->gid;
- tmp_user.ngroups = vuser->n_groups;
- tmp_user.groups = vuser->groups;
- tmp_user.nt_user_token = vuser->nt_user_token;
- } else {
- tmp_user.vuid = vuid;
- tmp_user.uid = conn->uid;
- tmp_user.gid = conn->gid;
- tmp_user.ngroups = conn->ngroups;
- tmp_user.groups = conn->groups;
- tmp_user.nt_user_token = conn->nt_user_token;
- }
-
- puser = &tmp_user;
+ if (vuser)
+ token = vuser->nt_user_token;
+ else
+ token = conn->nt_user_token;
- ret = se_access_check(psd, puser, desired_access, &granted, &status);
+ ret = se_access_check(psd, token, desired_access, &granted, &status);
out:
@@ -353,7 +338,7 @@ BOOL share_access_check(connection_struct *conn, int snum, uint16 vuid, uint32 d
Fill in a share info level 502 structure.
********************************************************************/
-static void init_srv_share_info_502(TALLOC_CTX *ctx, SRV_SHARE_INFO_502 *sh502, int snum)
+static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
{
int len_net_name;
pstring net_name;
@@ -363,12 +348,14 @@ static void init_srv_share_info_502(TALLOC_CTX *ctx, SRV_SHARE_INFO_502 *sh502,
uint32 type;
SEC_DESC *sd;
size_t sd_size;
+ TALLOC_CTX *ctx = p->mem_ctx;
+
ZERO_STRUCTP(sh502);
pstrcpy(net_name, lp_servicename(snum));
pstrcpy(remark, lp_comment(snum));
- pstring_sub(remark,"%S",lp_servicename(snum));
+ standard_sub_conn(p->conn, remark);
pstrcpy(path, "C:");
pstrcat(path, lp_pathname(snum));
@@ -429,12 +416,13 @@ static BOOL is_admin_share(int snum)
Fill in a share info structure.
********************************************************************/
-static BOOL init_srv_share_info_ctr(TALLOC_CTX *ctx, SRV_SHARE_INFO_CTR *ctr,
+static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr,
uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares)
{
int num_entries = 0;
int num_services = lp_numservices();
int snum;
+ TALLOC_CTX *ctx = p->mem_ctx;
DEBUG(5,("init_srv_share_info_ctr\n"));
@@ -466,7 +454,7 @@ static BOOL init_srv_share_info_ctr(TALLOC_CTX *ctx, SRV_SHARE_INFO_CTR *ctr,
for (snum = *resume_hnd; snum < num_services; snum++) {
if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
- init_srv_share_info_1(&info1[i++], snum);
+ init_srv_share_info_1(p, &info1[i++], snum);
}
}
@@ -483,7 +471,7 @@ static BOOL init_srv_share_info_ctr(TALLOC_CTX *ctx, SRV_SHARE_INFO_CTR *ctr,
for (snum = *resume_hnd; snum < num_services; snum++) {
if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
- init_srv_share_info_2(&info2[i++], snum);
+ init_srv_share_info_2(p, &info2[i++], snum);
}
}
@@ -500,7 +488,7 @@ static BOOL init_srv_share_info_ctr(TALLOC_CTX *ctx, SRV_SHARE_INFO_CTR *ctr,
for (snum = *resume_hnd; snum < num_services; snum++) {
if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) {
- init_srv_share_info_502(ctx, &info502[i++], snum);
+ init_srv_share_info_502(p, &info502[i++], snum);
}
}
@@ -520,14 +508,14 @@ static BOOL init_srv_share_info_ctr(TALLOC_CTX *ctx, SRV_SHARE_INFO_CTR *ctr,
Inits a SRV_R_NET_SHARE_ENUM structure.
********************************************************************/
-static void init_srv_r_net_share_enum(TALLOC_CTX *ctx, SRV_R_NET_SHARE_ENUM *r_n,
+static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n,
uint32 info_level, uint32 resume_hnd, BOOL all)
{
DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
- if (init_srv_share_info_ctr(ctx, &r_n->ctr, info_level,
+ if (init_srv_share_info_ctr(p, &r_n->ctr, info_level,
&resume_hnd, &r_n->total_entries, all)) {
- r_n->status = NT_STATUS_NOPROBLEMO;
+ r_n->status = NT_STATUS_OK;
} else {
r_n->status = NT_STATUS_INVALID_INFO_CLASS;
}
@@ -539,10 +527,10 @@ static void init_srv_r_net_share_enum(TALLOC_CTX *ctx, SRV_R_NET_SHARE_ENUM *r_n
Inits a SRV_R_NET_SHARE_GET_INFO structure.
********************************************************************/
-static void init_srv_r_net_share_get_info(TALLOC_CTX *ctx, SRV_R_NET_SHARE_GET_INFO *r_n,
+static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n,
char *share_name, uint32 info_level)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
int snum;
DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
@@ -554,13 +542,13 @@ static void init_srv_r_net_share_get_info(TALLOC_CTX *ctx, SRV_R_NET_SHARE_GET_I
if (snum >= 0) {
switch (info_level) {
case 1:
- init_srv_share_info_1(&r_n->info.share.info1, snum);
+ init_srv_share_info_1(p, &r_n->info.share.info1, snum);
break;
case 2:
- init_srv_share_info_2(&r_n->info.share.info2, snum);
+ init_srv_share_info_2(p, &r_n->info.share.info2, snum);
break;
case 502:
- init_srv_share_info_502(ctx, &r_n->info.share.info502, snum);
+ init_srv_share_info_502(p, &r_n->info.share.info502, snum);
break;
case 1005:
init_srv_share_info_1005(&r_n->info.share.info1005, snum);
@@ -574,7 +562,7 @@ static void init_srv_r_net_share_get_info(TALLOC_CTX *ctx, SRV_R_NET_SHARE_GET_I
status = NT_STATUS_BAD_NETWORK_NAME;
}
- r_n->info.ptr_share_ctr = (status == NT_STATUS_NOPROBLEMO) ? 1 : 0;
+ r_n->info.ptr_share_ctr = (status == NT_STATUS_OK) ? 1 : 0;
r_n->status = status;
}
@@ -694,7 +682,7 @@ static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *sto
static uint32 init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -736,7 +724,7 @@ static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
else
r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
- if (r_n->status != NT_STATUS_NOPROBLEMO)
+ if (r_n->status != NT_STATUS_OK)
resume_hnd = 0;
init_enum_hnd(&r_n->enum_hnd, resume_hnd);
@@ -850,7 +838,7 @@ static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto
static uint32 init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -891,7 +879,7 @@ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
else
r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
- if (r_n->status != NT_STATUS_NOPROBLEMO)
+ if (r_n->status != NT_STATUS_OK)
resume_hnd = 0;
init_enum_hnd(&r_n->enum_hnd, resume_hnd);
@@ -950,7 +938,7 @@ static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *fto
static uint32 init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -987,7 +975,7 @@ static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
else
r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
- if (r_n->status != NT_STATUS_NOPROBLEMO)
+ if (r_n->status != NT_STATUS_OK)
resume_hnd = 0;
init_enum_hnd(&r_n->enum_hnd, resume_hnd);
@@ -999,7 +987,7 @@ net server get info
uint32 _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u)
{
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
SRV_INFO_CTR *ctr = (SRV_INFO_CTR *)talloc(p->mem_ctx, sizeof(SRV_INFO_CTR));
if (!ctr)
@@ -1056,7 +1044,7 @@ uint32 _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R
/* NT gives "Windows NT error 0xc00000022" if we return
NT_STATUS_ACCESS_DENIED here so just pretend everything is OK. */
- uint32 status = NT_STATUS_NOPROBLEMO;
+ uint32 status = NT_STATUS_OK;
DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__));
@@ -1153,7 +1141,7 @@ uint32 _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R
DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
/* Create the list of shares for the response. */
- init_srv_r_net_share_enum(p->mem_ctx, r_u,
+ init_srv_r_net_share_enum(p, r_u,
q_u->ctr.info_level,
get_enum_hnd(&q_u->enum_hnd), True);
@@ -1171,7 +1159,7 @@ uint32 _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET
DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
/* Create the list of shares for the response. */
- init_srv_r_net_share_enum(p->mem_ctx, r_u,
+ init_srv_r_net_share_enum(p, r_u,
q_u->ctr.info_level,
get_enum_hnd(&q_u->enum_hnd), False);
@@ -1192,7 +1180,7 @@ uint32 _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S
/* Create the list of shares for the response. */
unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
- init_srv_r_net_share_get_info(p->mem_ctx, r_u, share_name, q_u->info_level);
+ init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level);
DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__));
@@ -1229,9 +1217,7 @@ static char *valid_share_pathname(char *dos_pathname)
if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
return False;
- /* Convert to UNIX charset. */
pstrcpy(unix_pathname, ptr);
- dos_to_unix(unix_pathname, True);
ret = chdir(unix_pathname);
@@ -1266,7 +1252,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
r_u->switch_value = 0;
if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
snum = find_service(share_name);
@@ -1276,17 +1262,17 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
/* No change to printer shares. */
if (lp_print_ok(snum))
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
get_current_user(&user,p);
if (user.uid != 0)
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
switch (q_u->info_level) {
case 1:
/* Not enough info in a level 1 to do anything. */
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
case 2:
unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name));
@@ -1301,7 +1287,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
map_generic_share_sd_bits(psd);
break;
case 1005:
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
case 1501:
fstrcpy(pathname, lp_pathname(snum));
fstrcpy(comment, lp_comment(snum));
@@ -1316,7 +1302,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
/* We can only modify disk shares. */
if (type != STYPE_DISKTREE)
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
/* Check if the pathname is valid. */
if (!(ptr = valid_share_pathname( pathname )))
@@ -1334,16 +1320,15 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
if (!lp_change_share_cmd() || !*lp_change_share_cmd())
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
lp_change_share_cmd(), CONFIGFILE, share_name, ptr, comment);
- dos_to_unix(command, True); /* Convert to unix-codepage */
DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
/* Tell everyone we updated smb.conf. */
@@ -1369,7 +1354,7 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -1397,18 +1382,18 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
if (user.uid != 0) {
DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n"));
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
DEBUG(10,("_srv_net_share_add: No add share command\n"));
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
switch (q_u->info_level) {
case 1:
/* Not enough info in a level 1 to do anything. */
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
case 2:
unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name));
unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name));
@@ -1425,14 +1410,14 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
break;
case 1005:
/* DFS only level. */
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
default:
DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level));
return NT_STATUS_INVALID_INFO_CLASS;
}
if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
snum = find_service(share_name);
@@ -1442,7 +1427,7 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
/* We can only add disk shares. */
if (type != STYPE_DISKTREE)
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
/* Check if the pathname is valid. */
if (!(ptr = valid_share_pathname( pathname )))
@@ -1455,12 +1440,11 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
lp_add_share_cmd(), CONFIGFILE, share_name, ptr, comment);
- dos_to_unix(command, True); /* Convert to unix-codepage */
DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
if (psd) {
@@ -1480,7 +1464,7 @@ uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -1501,7 +1485,7 @@ uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name));
if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global"))
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
snum = find_service(share_name);
@@ -1510,24 +1494,23 @@ uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
/* No change to printer shares. */
if (lp_print_ok(snum))
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
get_current_user(&user,p);
if (user.uid != 0)
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
lp_delete_share_cmd(), CONFIGFILE, lp_servicename(snum));
- dos_to_unix(command, True); /* Convert to unix-codepage */
DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
if ((ret = smbrun(command, NULL)) != 0) {
DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
- return ERROR_ACCESS_DENIED;
+ return ERRnoaccess;
}
/* Delete the SD in the database. */
@@ -1538,7 +1521,7 @@ uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
lp_killservice(snum);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -1559,7 +1542,7 @@ uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET
r_u->tod = tod;
r_u->ptr_srv_tod = 0x1;
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
@@ -1609,7 +1592,7 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
ZERO_STRUCT(st);
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
@@ -1640,7 +1623,7 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
if (!fsp) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename));
- r_u->status = ERROR_ACCESS_DENIED;
+ r_u->status = ERRnoaccess;
goto error_exit;
}
}
@@ -1649,7 +1632,7 @@ uint32 _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
if (sd_size == 0) {
DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename));
- r_u->status = ERROR_ACCESS_DENIED;
+ r_u->status = ERRnoaccess;
goto error_exit;
}
@@ -1698,10 +1681,11 @@ uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
struct current_user user;
fstring user_name;
connection_struct *conn = NULL;
+ BOOL became_user = False;
ZERO_STRUCT(st);
- r_u->status = NT_STATUS_NOPROBLEMO;
+ r_u->status = NT_STATUS_OK;
unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname));
@@ -1719,6 +1703,13 @@ uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
goto error_exit;
}
+ if (!become_user(conn, conn->vuid)) {
+ DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
+ r_u->status = ERRnoaccess;
+ goto error_exit;
+ }
+ became_user = True;
+
unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
unix_convert(filename, conn, NULL, &bad_path, &st);
@@ -1733,7 +1724,7 @@ uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
if (!fsp) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename));
- r_u->status = ERROR_ACCESS_DENIED;
+ r_u->status = ERRnoaccess;
goto error_exit;
}
}
@@ -1742,11 +1733,12 @@ uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
if (ret == False) {
DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename));
- r_u->status = ERROR_ACCESS_DENIED;
+ r_u->status = ERRnoaccess;
goto error_exit;
}
close_file(fsp, True);
+ unbecome_user();
close_cnum(conn, user.vuid);
return r_u->status;
@@ -1756,6 +1748,9 @@ uint32 _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_
close_file(fsp, True);
}
+ if (became_user)
+ unbecome_user();
+
if (conn)
close_cnum(conn, user.vuid);
@@ -1814,7 +1809,7 @@ uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D
const char *disk_name;
uint32 resume=get_enum_hnd(&q_u->enum_hnd);
- r_u->status=NT_STATUS_NOPROBLEMO;
+ r_u->status=NT_STATUS_OK;
r_u->total_entries = init_server_disk_enum(&resume);
@@ -1849,7 +1844,7 @@ uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV
int snum;
fstring share_name;
- r_u->status=NT_STATUS_NOPROBLEMO;
+ r_u->status=NT_STATUS_OK;
switch(q_u->type) {
@@ -1868,7 +1863,7 @@ uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV
default:
/*unsupported type*/
- r_u->status = ERROR_INVALID_LEVEL;
+ r_u->status = ERRunknownlevel;
break;
}
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index 8f15b7f117b..22e573402e9 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -251,8 +251,10 @@ uint32 local_lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
********************************************************************/
uint32 local_lookup_user_name(uint32 rid, char *user_name, uint32 *type)
{
- struct sam_disp_info *disp_info;
+ SAM_ACCOUNT *sampwd=NULL;
int i = 0;
+ BOOL ret;
+
(*type) = SID_NAME_USER;
DEBUG(5,("lookup_user_name: rid: %d", rid));
@@ -263,26 +265,28 @@ uint32 local_lookup_user_name(uint32 rid, char *user_name, uint32 *type)
i++;
}
- if (domain_user_rids[i].rid != 0)
- {
+ if (domain_user_rids[i].rid != 0) {
fstrcpy(user_name, domain_user_rids[i].name);
DEBUG(5,(" = %s\n", user_name));
return 0x0;
}
+ pdb_init_sam(&sampwd);
+
/* ok, it's a user. find the user account */
become_root();
- disp_info = getsamdisprid(rid);
+ ret = pdb_getsampwrid(sampwd, rid);
unbecome_root();
- if (disp_info != NULL)
- {
- fstrcpy(user_name, disp_info->smb_name);
+ if (ret == True) {
+ fstrcpy(user_name, pdb_get_username(sampwd) );
DEBUG(5,(" = %s\n", user_name));
+ pdb_free_sam(sampwd);
return 0x0;
}
DEBUG(5,(" none mapped\n"));
+ pdb_free_sam(sampwd);
return NT_STATUS_NONE_MAPPED;
}
@@ -329,19 +333,24 @@ uint32 local_lookup_alias_rid(char *alias_name, uint32 *rid)
********************************************************************/
uint32 local_lookup_user_rid(char *user_name, uint32 *rid)
{
- struct sam_passwd *sam_pass;
+ SAM_ACCOUNT *sampass=NULL;
+ BOOL ret;
+
(*rid) = 0;
+ pdb_init_sam(&sampass);
+
/* find the user account */
become_root();
- sam_pass = getsam21pwnam(user_name);
+ ret = pdb_getsampwnam(sampass, user_name);
unbecome_root();
- if (sam_pass != NULL)
- {
- (*rid) = sam_pass->user_rid;
+ if (ret == True) {
+ (*rid) = pdb_get_user_rid(sampass);
+ pdb_free_sam(sampass);
return 0x0;
}
+ pdb_free_sam(sampass);
return NT_STATUS_NONE_MAPPED;
}
diff --git a/source/rpc_server/srv_wkssvc_nt.c b/source/rpc_server/srv_wkssvc_nt.c
index 40771d2fb93..c20ebb57067 100644
--- a/source/rpc_server/srv_wkssvc_nt.c
+++ b/source/rpc_server/srv_wkssvc_nt.c
@@ -72,7 +72,7 @@ uint32 _wks_query_info(pipes_struct *p, WKS_Q_QUERY_INFO *q_u, WKS_R_QUERY_INFO
return NT_STATUS_NO_MEMORY;
create_wks_info_100(wks100);
- init_wks_r_query_info(r_u, q_u->switch_value, wks100, NT_STATUS_NOPROBLEMO);
+ init_wks_r_query_info(r_u, q_u->switch_value, wks100, NT_STATUS_OK);
DEBUG(5,("_wks_query_info: %d\n", __LINE__));
diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c
index 153d5366e00..5fe8509b215 100644
--- a/source/rpcclient/cmd_lsarpc.c
+++ b/source/rpcclient/cmd_lsarpc.c
@@ -59,7 +59,7 @@ static uint32 cmd_lsa_query_info_policy(struct cli_state *cli, int argc, char **
if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol)) != NT_STATUS_NOPROBLEMO) {
+ &pol)) != NT_STATUS_OK) {
goto done;
}
@@ -69,7 +69,7 @@ static uint32 cmd_lsa_query_info_policy(struct cli_state *cli, int argc, char **
if ((result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
domain_name, &dom_sid))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -121,7 +121,7 @@ static uint32 cmd_lsa_lookup_names(struct cli_state *cli, int argc, char **argv)
if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol)) != NT_STATUS_NOPROBLEMO) {
+ &pol)) != NT_STATUS_OK) {
goto done;
}
@@ -131,7 +131,7 @@ static uint32 cmd_lsa_lookup_names(struct cli_state *cli, int argc, char **argv)
if ((result = cli_lsa_lookup_names(cli, mem_ctx, &pol, argc - 1,
&argv[1], &sids, &types, &num_names) !=
- NT_STATUS_NOPROBLEMO)) {
+ NT_STATUS_OK)) {
goto done;
}
@@ -194,7 +194,7 @@ static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv)
if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol)) != NT_STATUS_NOPROBLEMO) {
+ &pol)) != NT_STATUS_OK) {
goto done;
}
@@ -217,7 +217,7 @@ static uint32 cmd_lsa_lookup_sids(struct cli_state *cli, int argc, char **argv)
if ((result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, argc - 1, sids,
&names, &types, &num_names) !=
- NT_STATUS_NOPROBLEMO)) {
+ NT_STATUS_OK)) {
goto done;
}
@@ -287,7 +287,7 @@ static uint32 cmd_lsa_enum_trust_dom(struct cli_state *cli, int argc, char **arg
if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol)) != NT_STATUS_NOPROBLEMO) {
+ &pol)) != NT_STATUS_OK) {
goto done;
}
@@ -298,7 +298,7 @@ static uint32 cmd_lsa_enum_trust_dom(struct cli_state *cli, int argc, char **arg
if ((result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
&num_domains, &domain_names,
&domain_sids)
- != NT_STATUS_NOPROBLEMO)) {
+ != NT_STATUS_OK)) {
goto done;
}
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index 93f6f1c3957..375f6765665 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -49,7 +49,7 @@ static uint32 cmd_netlogon_logon_ctrl2(struct cli_state *cli, int argc,
}
if ((result = cli_netlogon_logon_ctrl2(cli, mem_ctx, query_level))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -87,7 +87,7 @@ static uint32 cmd_netlogon_logon_ctrl(struct cli_state *cli, int argc,
#if 0
if ((result = cli_netlogon_logon_ctrl(cli, mem_ctx, query_level))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
#endif
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 931d44eb3b1..2ee84f80873 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -119,6 +119,22 @@ static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
printf("Unknown 6:\t0x%x\n", info2->unknown_6);
}
+void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
+{
+ fstring tmp;
+
+ printf("RID: 0x%x ", e1->rid_user);
+
+ unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
+ printf("Account: %s\t", tmp);
+
+ unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
+ printf("Name: %s\t", tmp);
+
+ unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
+ printf("Desc: %s\n", tmp);
+}
+
/**********************************************************************
* Query user information
*/
@@ -130,8 +146,7 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv)
BOOL got_connect_pol = False,
got_domain_pol = False,
got_user_pol = False;
- SAM_USERINFO_CTR user_ctr;
- SAM_USER_INFO_21 info_21;
+ SAM_USERINFO_CTR *user_ctr;
fstring server;
TALLOC_CTX *mem_ctx;
uint32 user_rid;
@@ -161,9 +176,9 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv)
slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (server);
- if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol)) !=
- NT_STATUS_NOPROBLEMO) {
+ NT_STATUS_OK) {
goto done;
}
@@ -172,7 +187,7 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv)
if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -181,24 +196,21 @@ static uint32 cmd_samr_query_user(struct cli_state *cli, int argc, char **argv)
if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
user_rid, &user_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
got_user_pol = True;
ZERO_STRUCT(user_ctr);
- ZERO_STRUCT(info_21);
- user_ctr.info.id21 = &info_21;
-
- if ((result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol, info_level,
- &user_ctr))
- != NT_STATUS_NOPROBLEMO) {
+ if ((result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
+ info_level, &user_ctr))
+ != NT_STATUS_OK) {
goto done;
}
- display_sam_user_info_21(&info_21);
+ display_sam_user_info_21(user_ctr->info.id21);
done:
if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
@@ -266,14 +278,16 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv)
GROUP_INFO_CTR group_ctr;
fstring server;
TALLOC_CTX *mem_ctx;
+ uint32 group_rid;
- if (argc != 1) {
- printf("Usage: %s\n", argv[0]);
+ if (argc != 2) {
+ printf("Usage: %s rid\n", argv[0]);
return 0;
}
- if (!(mem_ctx=talloc_init()))
- {
+ group_rid = atoi(argv[1]);
+
+ if (!(mem_ctx=talloc_init())) {
DEBUG(0,("cmd_samr_query_group: talloc_init returned NULL!\n"));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -289,9 +303,9 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv)
slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (server);
- if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol)) !=
- NT_STATUS_NOPROBLEMO) {
+ NT_STATUS_OK) {
goto done;
}
@@ -300,7 +314,7 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv)
if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -308,8 +322,8 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv)
if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
- 0x202, &group_pol))
- != NT_STATUS_NOPROBLEMO) {
+ group_rid, &group_pol))
+ != NT_STATUS_OK) {
goto done;
}
@@ -317,9 +331,9 @@ static uint32 cmd_samr_query_group(struct cli_state *cli, int argc, char **argv)
ZERO_STRUCT(group_ctr);
- if ((result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol, info_level,
- &group_ctr))
- != NT_STATUS_NOPROBLEMO) {
+ if ((result = cli_samr_query_groupinfo(cli, mem_ctx, &group_pol,
+ info_level, &group_ctr))
+ != NT_STATUS_OK) {
goto done;
}
@@ -378,9 +392,9 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **
slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (server);
- if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol)) !=
- NT_STATUS_NOPROBLEMO) {
+ NT_STATUS_OK) {
goto done;
}
@@ -389,7 +403,7 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **
if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -398,7 +412,7 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **
if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
user_rid, &user_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -406,7 +420,7 @@ static uint32 cmd_samr_query_usergroups(struct cli_state *cli, int argc, char **
if ((result = cli_samr_query_usergroups(cli, mem_ctx, &user_pol,
&num_groups, &user_gids))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -464,9 +478,9 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar
slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
strupper (server);
- if ((result = cli_samr_connect(cli, mem_ctx, server, MAXIMUM_ALLOWED_ACCESS,
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol)) !=
- NT_STATUS_NOPROBLEMO) {
+ NT_STATUS_OK) {
goto done;
}
@@ -475,7 +489,7 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar
if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -484,7 +498,7 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar
if ((result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
group_rid, &group_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -493,7 +507,7 @@ static uint32 cmd_samr_query_groupmem(struct cli_state *cli, int argc, char **ar
if ((result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
&num_members, &group_rids,
&group_attrs))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -522,7 +536,6 @@ static uint32 cmd_samr_enum_dom_groups(struct cli_state *cli, int argc,
uint32 result = NT_STATUS_UNSUCCESSFUL;
BOOL got_connect_pol = False, got_domain_pol = False;
TALLOC_CTX *mem_ctx;
- fstring server;
uint32 start_idx, size, num_dom_groups, i;
struct acct_info *dom_groups;
@@ -546,15 +559,11 @@ static uint32 cmd_samr_enum_dom_groups(struct cli_state *cli, int argc,
return NT_STATUS_UNSUCCESSFUL;
}
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper(server);
-
/* Get sam policy handle */
- if ((result = cli_samr_connect(cli, mem_ctx, server,
- MAXIMUM_ALLOWED_ACCESS,
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol)) !=
- NT_STATUS_NOPROBLEMO) {
+ NT_STATUS_OK) {
goto done;
}
@@ -565,7 +574,7 @@ static uint32 cmd_samr_enum_dom_groups(struct cli_state *cli, int argc,
if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -606,8 +615,6 @@ static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc,
uint32 result = NT_STATUS_UNSUCCESSFUL, alias_rid, num_members, i;
DOM_SID *alias_sids;
- fstring server;
-
if (argc != 2) {
printf("Usage: %s rid\n", argv[0]);
return 0;
@@ -632,13 +639,9 @@ static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc,
/* Open SAMR handle */
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper(server);
-
- if ((result = cli_samr_connect(cli, mem_ctx, server,
- MAXIMUM_ALLOWED_ACCESS,
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol)) !=
- NT_STATUS_NOPROBLEMO) {
+ NT_STATUS_OK) {
goto done;
}
@@ -649,7 +652,7 @@ static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc,
if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -660,7 +663,7 @@ static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc,
if ((result = cli_samr_open_alias(cli, mem_ctx, &domain_pol,
MAXIMUM_ALLOWED_ACCESS,
alias_rid, &alias_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -668,7 +671,7 @@ static uint32 cmd_samr_query_aliasmem(struct cli_state *cli, int argc,
if ((result = cli_samr_query_aliasmem(cli, mem_ctx, &alias_pol,
&num_members, &alias_sids))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -699,9 +702,10 @@ static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc,
uint32 result = NT_STATUS_UNSUCCESSFUL;
BOOL got_connect_pol = False, got_domain_pol = False;
TALLOC_CTX *mem_ctx;
- fstring server;
- uint32 start_idx, size, num_dom_groups, i;
- struct acct_info *dom_groups;
+ uint32 start_idx, max_entries, num_entries, i;
+ uint16 info_level = 1;
+ SAM_DISPINFO_CTR ctr;
+ SAM_DISPINFO_1 info1;
if (argc != 1) {
printf("Usage: %s\n", argv[0]);
@@ -723,15 +727,11 @@ static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc,
return NT_STATUS_UNSUCCESSFUL;
}
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper(server);
-
/* Get sam policy handle */
- if ((result = cli_samr_connect(cli, mem_ctx, server,
- MAXIMUM_ALLOWED_ACCESS,
- &connect_pol)) !=
- NT_STATUS_NOPROBLEMO) {
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol))
+ != NT_STATUS_OK) {
goto done;
}
@@ -740,9 +740,9 @@ static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc,
/* Get domain policy handle */
if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
+ MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -751,15 +751,21 @@ static uint32 cmd_samr_query_dispinfo(struct cli_state *cli, int argc,
/* Query display info */
start_idx = 0;
- size = 0xffff;
+ max_entries = 250;
- result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
- &start_idx, size,
- &dom_groups, &num_dom_groups);
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(info1);
- for (i = 0; i < num_dom_groups; i++)
- printf("group:[%s] rid:[0x%x]\n", dom_groups[i].acct_name,
- dom_groups[i].rid);
+ ctr.sam.info1 = &info1;
+
+ result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
+ &start_idx, info_level,
+ &num_entries, max_entries, &ctr);
+
+ for (i = 0; i < num_entries; i++) {
+ display_sam_info_1(&ctr.sam.info1->sam[i],
+ &ctr.sam.info1->str[i]);
+ }
done:
if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
@@ -780,7 +786,6 @@ static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc,
uint32 result = NT_STATUS_UNSUCCESSFUL;
BOOL got_connect_pol = False, got_domain_pol = False;
TALLOC_CTX *mem_ctx;
- fstring server;
uint16 switch_value = 2;
SAM_UNK_CTR ctr;
@@ -807,15 +812,11 @@ static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc,
return NT_STATUS_UNSUCCESSFUL;
}
- slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost);
- strupper(server);
-
/* Get sam policy handle */
- if ((result = cli_samr_connect(cli, mem_ctx, server,
- MAXIMUM_ALLOWED_ACCESS,
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
&connect_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -826,7 +827,7 @@ static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc,
if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
MAXIMUM_ALLOWED_ACCESS,
&domain_sid, &domain_pol))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -836,7 +837,7 @@ static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc,
if ((result = cli_samr_query_dom_info(cli, mem_ctx, &domain_pol,
switch_value, &ctr))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -862,6 +863,334 @@ static uint32 cmd_samr_query_dominfo(struct cli_state *cli, int argc,
return result;
}
+/* Create domain user */
+
+static uint32 cmd_samr_create_dom_user(struct cli_state *cli, int argc,
+ char **argv)
+{
+ POLICY_HND connect_pol, domain_pol, user_pol;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+ BOOL got_connect_pol = False, got_domain_pol = False,
+ got_user_pol = False;
+ TALLOC_CTX *mem_ctx;
+ char *acct_name;
+ uint16 acb_info;
+ uint32 unknown, user_rid;
+
+ if (argc != 2) {
+ printf("Usage: %s username\n", argv[0]);
+ return 0;
+ }
+
+ acct_name = argv[1];
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0, ("cmd_samr_query_dispinfo: talloc_init returned "
+ "NULL!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ fetch_domain_sid(cli);
+
+ /* Initialise RPC connection */
+
+ if (!cli_nt_session_open (cli, PIPE_SAMR)) {
+ fprintf (stderr, "Could not initialize samr pipe!\n");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Get sam policy handle */
+
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ got_connect_pol = True;
+
+ /* Get domain policy handle */
+
+ if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ got_domain_pol = True;
+
+ /* Create domain user */
+
+ acb_info = ACB_NORMAL;
+ unknown = 0xe005000b; /* No idea what this is - a permission mask? */
+
+ if ((result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
+ acct_name, acb_info, unknown,
+ &user_pol, &user_rid))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ got_user_pol = True;
+
+ done:
+ if (got_user_pol) cli_samr_close(cli, mem_ctx, &user_pol);
+ if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
+ if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
+
+ cli_nt_session_close(cli);
+ talloc_destroy(mem_ctx);
+
+ return result;
+}
+
+/* Lookup sam names */
+
+static uint32 cmd_samr_lookup_names(struct cli_state *cli, int argc,
+ char **argv)
+{
+ TALLOC_CTX *mem_ctx;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+ POLICY_HND connect_pol, domain_pol;
+ BOOL got_connect_pol = False, got_domain_pol = False;
+ uint32 flags = 0x000003e8;
+ uint32 num_rids, num_names, *name_types, *rids;
+ char **names;
+ int i;
+
+ if (argc < 2) {
+ printf("Usage: %s name1 [name2 [name3] [...]]\n", argv[0]);
+ return 0;
+ }
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0, ("cmd_samr_lookup_names: talloc_init failed\n"));
+ return result;
+ }
+
+ fetch_domain_sid(cli);
+
+ /* Initialise RPC connection */
+
+ if (!cli_nt_session_open (cli, PIPE_SAMR)) {
+ fprintf (stderr, "Could not initialize samr pipe!\n");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Get sam policy and domain handles */
+
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ got_connect_pol = True;
+
+ if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ got_domain_pol = True;
+
+ /* Look up names */
+
+ num_names = argc - 1;
+ names = (char **)talloc(mem_ctx, sizeof(char *) * num_names);
+
+ for (i = 0; i < argc - 1; i++)
+ names[i] = argv[i + 1];
+
+ if ((result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ flags, num_names, names,
+ &num_rids, &rids, &name_types))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ /* Display results */
+
+ for (i = 0; i < num_names; i++)
+ printf("name %s: 0x%x (%d)\n", names[i], rids[i],
+ name_types[i]);
+
+ done:
+ if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
+ if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
+
+ cli_nt_session_close(cli);
+ talloc_destroy(mem_ctx);
+
+ return result;
+}
+
+/* Lookup sam rids */
+
+static uint32 cmd_samr_lookup_rids(struct cli_state *cli, int argc,
+ char **argv)
+{
+ TALLOC_CTX *mem_ctx;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+ POLICY_HND connect_pol, domain_pol;
+ BOOL got_connect_pol = False, got_domain_pol = False;
+ uint32 flags = 0x000003e8;
+ uint32 num_rids, num_names, *rids, *name_types;
+ char **names;
+ int i;
+
+ if (argc < 2) {
+ printf("Usage: %s rid1 [rid2 [rid3] [...]]\n", argv[0]);
+ return 0;
+ }
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0, ("cmd_samr_lookup_rids: talloc_init failed\n"));
+ return result;
+ }
+
+ fetch_domain_sid(cli);
+
+ /* Initialise RPC connection */
+
+ if (!cli_nt_session_open (cli, PIPE_SAMR)) {
+ fprintf (stderr, "Could not initialize samr pipe!\n");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Get sam policy and domain handles */
+
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ got_connect_pol = True;
+
+ if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ got_domain_pol = True;
+
+ /* Look up rids */
+
+ num_rids = argc - 1;
+ rids = (uint32 *)talloc(mem_ctx, sizeof(uint32) * num_rids);
+
+ for (i = 0; i < argc - 1; i++)
+ rids[i] = atoi(argv[i + 1]);
+
+ if ((result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol,
+ flags, num_rids, rids,
+ &num_names, &names, &name_types))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ /* Display results */
+
+ for (i = 0; i < num_names; i++)
+ printf("rid %x: %s (%d)\n", rids[i], names[i], name_types[i]);
+
+ done:
+ if (got_domain_pol) cli_samr_close(cli, mem_ctx, &domain_pol);
+ if (got_connect_pol) cli_samr_close(cli, mem_ctx, &connect_pol);
+
+ cli_nt_session_close(cli);
+ talloc_destroy(mem_ctx);
+
+ return result;
+}
+
+/* Delete domain user */
+
+static uint32 cmd_samr_delete_dom_user(struct cli_state *cli, int argc,
+ char **argv)
+{
+ TALLOC_CTX *mem_ctx;
+ uint32 result = NT_STATUS_UNSUCCESSFUL;
+ POLICY_HND connect_pol, domain_pol, user_pol;
+
+ if (argc != 2) {
+ printf("Usage: %s username\n", argv[0]);
+ return 0;
+ }
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0, ("cmd_samr_delete_dom_user: talloc_init failed\n"));
+ return result;
+ }
+
+ fetch_domain_sid(cli);
+
+ /* Initialise RPC connection */
+
+ if (!cli_nt_session_open (cli, PIPE_SAMR)) {
+ DEBUG(0, ("cmd_samr_delete_dom_user: could not open samr pipe!\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Get sam policy and domain handles */
+
+ if ((result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ if ((result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ /* Get handle on user */
+
+ {
+ uint32 *user_rids, num_rids, *name_types;
+ uint32 flags = 0x000003e8;
+
+ if ((result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ flags, 1, &argv[1],
+ &num_rids, &user_rids,
+ &name_types))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ if ((result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ user_rids[0], &user_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+ }
+
+ /* Delete user */
+
+ if ((result = cli_samr_delete_dom_user(cli, mem_ctx, &user_pol))
+ != NT_STATUS_OK) {
+ goto done;
+ }
+
+ /* Display results */
+
+ done:
+ cli_nt_session_close(cli);
+ talloc_destroy(mem_ctx);
+
+ return result;
+}
+
/* List of commands exported by this module */
struct cmd_set samr_commands[] = {
@@ -876,6 +1205,10 @@ struct cmd_set samr_commands[] = {
{ "querydominfo", cmd_samr_query_dominfo, "Query domain info" },
{ "enumdomgroups", cmd_samr_enum_dom_groups, "Enumerate domain groups" },
+ { "createdomuser", cmd_samr_create_dom_user, "Create domain user" },
+ { "samlookupnames", cmd_samr_lookup_names, "Look up names", },
+ { "samlookuprids", cmd_samr_lookup_rids, "Look up names", },
+ { "deletedomuser", cmd_samr_delete_dom_user, "Delete domain user" },
{ NULL, NULL, NULL }
};
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index 6b5d45a2492..d8f7cf33ae2 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -64,7 +64,7 @@ BOOL get_short_archi(char *short_archi, char *long_archi)
if (archi_table[i].long_archi==NULL) {
DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
- return FALSE;
+ return False;
}
StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
@@ -84,7 +84,7 @@ static uint32 cmd_spoolss_not_implemented (struct cli_state *cli,
int argc, char **argv)
{
printf ("(*) This command is not currently implemented.\n");
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -152,7 +152,7 @@ static uint32 cmd_spoolss_open_printer_ex(struct cli_state *cli, int argc, char
if (argc != 2) {
printf("Usage: %s <printername>\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!cli)
@@ -181,10 +181,10 @@ static uint32 cmd_spoolss_open_printer_ex(struct cli_state *cli, int argc, char
result = cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "",
MAXIMUM_ALLOWED_ACCESS, servername, user, &hnd);
- if (result == NT_STATUS_NOPROBLEMO) {
+ if (result == NT_STATUS_OK) {
printf ("Printer %s opened successfully\n", printername);
result = cli_spoolss_close_printer (cli, mem_ctx, &hnd);
- if (result != NT_STATUS_NOPROBLEMO) {
+ if (result != NT_STATUS_OK) {
printf ("Error closing printer handle! (%s)\n", get_nt_error_msg(result));
}
}
@@ -349,7 +349,7 @@ static uint32 cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char **
if (argc > 2)
{
printf("Usage: %s [level]\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -375,7 +375,7 @@ static uint32 cmd_spoolss_enum_printers(struct cli_state *cli, int argc, char **
result = cli_spoolss_enum_printers(cli, mem_ctx, PRINTER_ENUM_LOCAL,
info_level, &returned, &ctr);
- if (result == NT_STATUS_NOPROBLEMO)
+ if (result == NT_STATUS_OK)
{
if (!returned)
printf ("No Printers printers returned.\n");
@@ -454,7 +454,7 @@ static uint32 cmd_spoolss_enum_ports(struct cli_state *cli, int argc, char **arg
if (argc > 2) {
printf("Usage: %s [level]\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -479,7 +479,7 @@ static uint32 cmd_spoolss_enum_ports(struct cli_state *cli, int argc, char **arg
result = cli_spoolss_enum_ports(cli, mem_ctx, info_level, &returned, &ctr);
- if (result == NT_STATUS_NOPROBLEMO) {
+ if (result == NT_STATUS_OK) {
int i;
for (i = 0; i < returned; i++) {
@@ -520,7 +520,7 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg
if (argc == 1 || argc > 3) {
printf("Usage: %s <printername> [level]\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -549,7 +549,7 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg
/* get a printer handle */
if ((result = cli_spoolss_open_printer_ex(
cli, mem_ctx, printername, "", MAXIMUM_ALLOWED_ACCESS, servername,
- user, &pol)) != NT_STATUS_NOPROBLEMO) {
+ user, &pol)) != NT_STATUS_OK) {
goto done;
}
@@ -557,7 +557,7 @@ static uint32 cmd_spoolss_getprinter(struct cli_state *cli, int argc, char **arg
/* Get printer info */
if ((result = cli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto done;
}
@@ -720,7 +720,7 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv
if ((argc == 1) || (argc > 3))
{
printf("Usage: %s <printername> [level]\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -746,7 +746,7 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv
/* Open a printer handle */
if ((result=cli_spoolss_open_printer_ex (cli, mem_ctx, printername, "",
- MAXIMUM_ALLOWED_ACCESS, servername, user, &pol)) != NT_STATUS_NO_PROBLEMO)
+ MAXIMUM_ALLOWED_ACCESS, servername, user, &pol)) != NT_STATUS_OK)
{
printf ("Error opening printer handle for %s!\n", printername);
return result;
@@ -762,10 +762,10 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv
switch (result)
{
- case NT_STATUS_NO_PROBLEMO:
+ case ERRsuccess:
break;
- case ERROR_UNKNOWN_PRINTER_DRIVER:
+ case ERRunknownprinterdriver:
continue;
default:
@@ -803,8 +803,8 @@ static uint32 cmd_spoolss_getdriver(struct cli_state *cli, int argc, char **argv
cli_nt_session_close (cli);
talloc_destroy(mem_ctx);
- if (result==ERROR_UNKNOWN_PRINTER_DRIVER)
- return NT_STATUS_NO_PROBLEMO;
+ if (result==ERRunknownprinterdriver)
+ return NT_STATUS_OK;
else
return result;
@@ -826,7 +826,7 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a
if (argc > 2)
{
printf("Usage: enumdrivers [level]\n");
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -860,7 +860,7 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a
continue;
- if (result != NT_STATUS_NO_PROBLEMO)
+ if (result != NT_STATUS_OK)
{
printf ("Error getting driver for environment [%s] - %s\n",
archi_table[i].long_archi, get_nt_error_msg(result));
@@ -897,8 +897,8 @@ static uint32 cmd_spoolss_enum_drivers(struct cli_state *cli, int argc, char **a
cli_nt_session_close (cli);
talloc_destroy(mem_ctx);
- if (result==ERROR_UNKNOWN_PRINTER_DRIVER)
- return NT_STATUS_NO_PROBLEMO;
+ if (result==ERRunknownprinterdriver)
+ return NT_STATUS_OK;
else
return result;
@@ -931,7 +931,7 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a
if (argc > 2)
{
printf("Usage: %s [environment]\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
/* Initialise RPC connection */
@@ -956,7 +956,7 @@ static uint32 cmd_spoolss_getdriverdir(struct cli_state *cli, int argc, char **a
/* Get the directory. Only use Info level 1 */
if ((result = cli_spoolss_getprinterdriverdir (cli, mem_ctx, 1, env, &ctr))
- != NT_STATUS_NO_PROBLEMO)
+ != NT_STATUS_OK)
{
return result;
}
@@ -1098,7 +1098,7 @@ static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, cha
printf ("\t<Config File Name>:<Help File Name>:<Language Monitor Name>:\\\n");
printf ("\t<Default Data Type>:<Comma Separated list of Files>\n");
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -1134,7 +1134,7 @@ static uint32 cmd_spoolss_addprinterdriver (struct cli_state *cli, int argc, cha
ctr.info3 = &info3;
if ((result = cli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr))
- != NT_STATUS_NO_PROBLEMO)
+ != NT_STATUS_OK)
{
return result;
}
@@ -1164,7 +1164,7 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char **
if (argc != 5)
{
printf ("Usage: %s <name> <shared name> <driver> <port>\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -1215,7 +1215,7 @@ static uint32 cmd_spoolss_addprinterex (struct cli_state *cli, int argc, char **
ctr.printers_2 = &info2;
if ((result = cli_spoolss_addprinterex (cli, mem_ctx, level, &ctr))
- != NT_STATUS_NO_PROBLEMO)
+ != NT_STATUS_OK)
{
cli_nt_session_close (cli);
return result;
@@ -1248,7 +1248,7 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg
if (argc != 3)
{
printf ("Usage: %s <printer> <driver>\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -1273,7 +1273,7 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg
/* get a printer handle */
if ((result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
MAXIMUM_ALLOWED_ACCESS, servername, user, &pol))
- != NT_STATUS_NOPROBLEMO)
+ != NT_STATUS_OK)
{
goto done;
}
@@ -1283,7 +1283,7 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg
/* Get printer info */
ZERO_STRUCT (info2);
ctr.printers_2 = &info2;
- if ((result = cli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr)) != NT_STATUS_NOPROBLEMO)
+ if ((result = cli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr)) != NT_STATUS_OK)
{
printf ("Unable to retrieve printer information!\n");
goto done;
@@ -1291,7 +1291,7 @@ static uint32 cmd_spoolss_setdriver (struct cli_state *cli, int argc, char **arg
/* set the printer driver */
init_unistr(&ctr.printers_2->drivername, argv[2]);
- if ((result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0)) != NT_STATUS_NO_PROBLEMO)
+ if ((result = cli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0)) != NT_STATUS_OK)
{
printf ("SetPrinter call failed!\n");
goto done;;
@@ -1321,7 +1321,7 @@ static uint32 cmd_spoolss_deletedriver (struct cli_state *cli, int argc, char **
if (argc != 2)
{
printf ("Usage: %s <driver>\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (!(mem_ctx=talloc_init()))
@@ -1345,7 +1345,7 @@ static uint32 cmd_spoolss_deletedriver (struct cli_state *cli, int argc, char **
{
/* make the call to remove the driver */
if ((result = cli_spoolss_deleteprinterdriver(cli, mem_ctx,
- archi_table[i].long_archi, argv[1])) != NT_STATUS_NO_PROBLEMO)
+ archi_table[i].long_archi, argv[1])) != NT_STATUS_OK)
{
printf ("Failed to remove driver %s for arch [%s] - error %s!\n",
argv[1], archi_table[i].long_archi, get_nt_error_msg(result));
@@ -1359,7 +1359,7 @@ static uint32 cmd_spoolss_deletedriver (struct cli_state *cli, int argc, char **
cli_nt_session_close (cli);
talloc_destroy(mem_ctx);
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_OK;
}
diff --git a/source/rpcclient/cmd_srvsvc.c b/source/rpcclient/cmd_srvsvc.c
index b804cc383db..0f1289f2750 100644
--- a/source/rpcclient/cmd_srvsvc.c
+++ b/source/rpcclient/cmd_srvsvc.c
@@ -212,7 +212,7 @@ static uint32 cmd_srvsvc_srv_query_info(struct cli_state *cli, int argc,
if ((result = cli_srvsvc_net_srv_get_info(cli, mem_ctx, info_level,
&ctr)
- != NT_STATUS_NOPROBLEMO)) {
+ != NT_STATUS_OK)) {
goto done;
}
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index 537d3249338..9785b2c309b 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -23,7 +23,7 @@
#include "includes.h"
extern int DEBUGLEVEL;
-extern fstring debugf;
+extern pstring debugf;
DOM_SID domain_sid;
@@ -212,13 +212,13 @@ void fetch_domain_sid(struct cli_state *cli)
if ((result = cli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
- &pol) != NT_STATUS_NOPROBLEMO)) {
+ &pol) != NT_STATUS_OK)) {
goto error;
}
if ((result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
domain_name, &domain_sid))
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
goto error;
}
@@ -233,7 +233,7 @@ void fetch_domain_sid(struct cli_state *cli)
error:
fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
- if (result != NT_STATUS_NOPROBLEMO) {
+ if (result != NT_STATUS_OK) {
fprintf(stderr, "error: %s\n", get_nt_error_msg(result));
}
@@ -279,7 +279,7 @@ static uint32 cmd_debuglevel(struct cli_state *cli, int argc, char **argv)
{
if (argc > 2) {
printf("Usage: %s [debuglevel]\n", argv[0]);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
if (argc == 2) {
@@ -288,13 +288,13 @@ static uint32 cmd_debuglevel(struct cli_state *cli, int argc, char **argv)
printf("debuglevel is %d\n", DEBUGLEVEL);
- return NT_STATUS_NOPROBLEMO;
+ return NT_STATUS_OK;
}
static uint32 cmd_quit(struct cli_state *cli, int argc, char **argv)
{
exit(0);
- return NT_STATUS_NOPROBLEMO; /* NOTREACHED */
+ return NT_STATUS_OK; /* NOTREACHED */
}
/* Build in rpcclient commands */
@@ -501,9 +501,9 @@ struct cli_state *setup_connection(struct cli_state *cli, char *system_name,
/* Print usage information */
-static void usage(char *pname)
+static void usage(void)
{
- printf("Usage: %s server [options]\n", pname);
+ printf("Usage: rpcclient server [options]\n");
printf("\t-A authfile file containing user credentials\n");
printf("\t-c \"command string\" execute semicolon separated cmds\n");
@@ -543,17 +543,6 @@ static void usage(char *pname)
DEBUGLEVEL = 1;
- /* Parse options */
- if (argc < 2) {
- usage(argv[0]);
- return 0;
- }
-
- pstrcpy(server, argv[1]);
-
- argv++;
- argc--;
-
while ((opt = getopt(argc, argv, "A:s:Nd:U:W:c:l:")) != EOF) {
switch (opt) {
case 'A':
@@ -602,11 +591,25 @@ static void usage(char *pname)
case 'h':
default:
- usage(argv[0]);
+ usage();
exit(1);
}
}
+ argv += optind;
+ argc -= optind;
+
+ /* Parse options */
+ if (argc == 0) {
+ usage();
+ return 0;
+ }
+
+ if (strncmp("//", argv[0], 2) == 0 || strncmp("\\\\", argv[0], 2) == 0)
+ argv[0] += 2;
+
+ pstrcpy(server, argv[0]);
+
/* the following functions are part of the Samba debugging
facilities. See lib/debug.c */
setup_logging (argv[0], interactive);
@@ -643,12 +646,12 @@ static void usage(char *pname)
else {
init_rpcclient_creds (&creds, username, domain, password);
}
- memset(password,'X',strlen(password));
+ memset(password,'X',sizeof(password));
/* open a connection to the specified server */
ZERO_STRUCTP (&cli);
if (!setup_connection (&cli, server, &creds)) {
- return 0;
+ return 1;
}
/* There are no pointers in ntuser_creds struct so zero it out */
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index 35d1e21f27f..6f633c0bc20 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -176,9 +176,6 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, int eclass, i
char *inbuf = blr->inbuf;
construct_reply_common(inbuf, outbuf);
- if(eclass == 0) /* NT Error. */
- SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
-
ERROR(eclass,ecode);
if (!send_smb(smbd_server_fd(),outbuf))
exit_server("generic_blocking_lock_error: send_smb failed.\n");
@@ -419,7 +416,7 @@ static BOOL process_lockingX(blocking_lock_record *blr)
* request would never have been queued. JRA.
*/
errno = 0;
- if(!do_lock(fsp,conn,count,lock_pid,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
+ if(!do_lock(fsp,conn,lock_pid,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
&eclass, &ecode))
break;
}
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 083308d335f..245c1d1ea9b 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -50,6 +50,7 @@
#include "includes.h"
extern int DEBUGLEVEL;
+extern struct passdb_ops pdb_ops;
#if ALLOW_CHANGE_PASSWORD
@@ -193,7 +194,7 @@ static int dochild(int master, char *slavedev, char *name,
}
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
stermios.c_lflag |= ICANON;
- stermios.c_oflag &= ~(ONLCR);
+ stermios.c_oflag &= ~(ONLCR);
if (tcsetattr(0, TCSANOW, &stermios) < 0)
{
DEBUG(3, ("could not set attributes of pty\n"));
@@ -225,14 +226,15 @@ static int expect(int master, char *issue, char *expected)
int attempts, timeout, nread, len;
BOOL match = False;
- for (attempts = 0; attempts < 2; attempts++)
- {
- if (!strequal(issue, "."))
- {
+ for (attempts = 0; attempts < 2; attempts++) {
+ if (!strequal(issue, ".")) {
if (lp_passwd_chat_debug())
DEBUG(100, ("expect: sending [%s]\n", issue));
- write(master, issue, strlen(issue));
+ if ((len = write(master, issue, strlen(issue))) != strlen(issue)) {
+ DEBUG(2,("expect: (short) write returned %d\n", len ));
+ return False;
+ }
}
if (strequal(expected, "."))
@@ -244,29 +246,35 @@ static int expect(int master, char *issue, char *expected)
while ((len = read_with_timeout(master, buffer + nread, 1,
sizeof(buffer) - nread - 1,
- timeout)) > 0)
- {
+ timeout)) > 0) {
nread += len;
buffer[nread] = 0;
- if ((match = (ms_fnmatch(expected, buffer) == 0)))
- timeout = 200;
+ {
+ /* Eat leading/trailing whitespace before match. */
+ pstring str;
+ pstrcpy( str, buffer);
+ trim_string( str, " ", " ");
+
+ if ((match = (unix_wild_match(expected, str) == 0)))
+ timeout = 200;
+ }
}
if (lp_passwd_chat_debug())
- DEBUG(100, ("expect: expected [%s] received [%s]\n",
- expected, buffer));
+ DEBUG(100, ("expect: expected [%s] received [%s] match %s\n",
+ expected, buffer, match ? "yes" : "no" ));
if (match)
break;
- if (len < 0)
- {
+ if (len < 0) {
DEBUG(2, ("expect: %s\n", strerror(errno)));
return False;
}
}
+ DEBUG(10,("expect: returning %s\n", match ? "True" : "False" ));
return match;
}
@@ -513,15 +521,24 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
pstrcpy(chatsequence, lp_passwd_chat());
if (!*chatsequence) {
- DEBUG(2, ("Null chat sequence - no password changing\n"));
+ DEBUG(2, ("chgpasswd: Null chat sequence - no password changing\n"));
return (False);
}
if (!*passwordprogram) {
- DEBUG(2, ("Null password program - no password changing\n"));
+ DEBUG(2, ("chgpasswd: Null password program - no password changing\n"));
return (False);
}
+ if (as_root) {
+ /* The password program *must* contain the user name to work. Fail if not. */
+ if (strstr(passwordprogram, "%u") == NULL) {
+ DEBUG(0,("chgpasswd: Running as root the 'passwd program' parameter *MUST* contain \
+the string %%u, and the given string %s does not.\n", passwordprogram ));
+ return False;
+ }
+ }
+
pstring_sub(passwordprogram, "%u", name);
/* note that we do NOT substitute the %o and %n in the password program
as this would open up a security hole where the user could use
@@ -548,62 +565,66 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
************************************************************/
BOOL check_lanman_password(char *user, uchar * pass1,
- uchar * pass2, struct smb_passwd **psmbpw)
+ uchar * pass2, SAM_ACCOUNT **hnd)
{
static uchar null_pw[16];
uchar unenc_new_pw[16];
uchar unenc_old_pw[16];
- struct smb_passwd *smbpw;
-
- *psmbpw = NULL;
-
+ SAM_ACCOUNT *sampass = NULL;
+ uint16 acct_ctrl;
+ uint8 *lanman_pw;
+ BOOL ret;
+
become_root();
- smbpw = getsmbpwnam(user);
+ ret = pdb_getsampwnam(sampass, user);
unbecome_root();
- if (smbpw == NULL)
- {
- DEBUG(0,
- ("check_lanman_password: getsmbpwnam returned NULL\n"));
+ if (ret == False) {
+ DEBUG(0,("check_lanman_password: getsampwnam returned NULL\n"));
+ pdb_free_sam(sampass);
return False;
}
+
+ acct_ctrl = pdb_get_acct_ctrl (sampass);
+ lanman_pw = pdb_get_lanman_passwd (sampass);
- if (smbpw->acct_ctrl & ACB_DISABLED)
- {
- DEBUG(0,
- ("check_lanman_password: account %s disabled.\n",
- user));
+ if (acct_ctrl & ACB_DISABLED) {
+ DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
+ pdb_free_sam(sampass);
return False;
}
- if ((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
- {
+ if ((lanman_pw == NULL) && (acct_ctrl & ACB_PWNOTREQ)) {
uchar no_pw[14];
memset(no_pw, '\0', 14);
E_P16(no_pw, null_pw);
- smbpw->smb_passwd = null_pw;
+ if (!pdb_set_lanman_passwd(sampass, null_pw)) {
+ pdb_free_sam(sampass);
+ return False;
+ }
}
- else if (smbpw->smb_passwd == NULL)
- {
+ else if (lanman_pw == NULL) {
DEBUG(0, ("check_lanman_password: no lanman password !\n"));
+ pdb_free_sam(sampass);
return False;
}
/* Get the new lanman hash. */
- D_P16(smbpw->smb_passwd, pass2, unenc_new_pw);
+ D_P16(lanman_pw, pass2, unenc_new_pw);
/* Use this to get the old lanman hash. */
D_P16(unenc_new_pw, pass1, unenc_old_pw);
/* Check that the two old passwords match. */
- if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
- {
- DEBUG(0,
- ("check_lanman_password: old password doesn't match.\n"));
+ if (memcmp(lanman_pw, unenc_old_pw, 16)) {
+ DEBUG(0,("check_lanman_password: old password doesn't match.\n"));
+ pdb_free_sam(sampass);
return False;
}
- *psmbpw = smbpw;
+ /* this saves the pointer for the caller */
+ *hnd = sampass;
+
return True;
}
@@ -613,50 +634,51 @@ BOOL check_lanman_password(char *user, uchar * pass1,
no longer be valid.
************************************************************/
-BOOL change_lanman_password(struct smb_passwd *smbpw, uchar * pass1,
+BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar * pass1,
uchar * pass2)
{
static uchar null_pw[16];
uchar unenc_new_pw[16];
BOOL ret;
+ uint16 acct_ctrl;
+ uint8 *pwd;
- if (smbpw == NULL)
- {
- DEBUG(0,
- ("change_lanman_password: no smb password entry.\n"));
+ if (sampass == NULL) {
+ DEBUG(0,("change_lanman_password: no smb password entry.\n"));
return False;
}
+
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
+ pwd = pdb_get_lanman_passwd(sampass);
- if (smbpw->acct_ctrl & ACB_DISABLED)
- {
- DEBUG(0,
- ("change_lanman_password: account %s disabled.\n",
- smbpw->smb_name));
+ if (acct_ctrl & ACB_DISABLED) {
+ DEBUG(0,("change_lanman_password: account %s disabled.\n",
+ pdb_get_username(sampass)));
return False;
}
- if ((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
- {
+ if ((pwd == NULL) && (acct_ctrl & ACB_PWNOTREQ)) {
uchar no_pw[14];
memset(no_pw, '\0', 14);
E_P16(no_pw, null_pw);
- smbpw->smb_passwd = null_pw;
+ if (!pdb_set_lanman_passwd(sampass, null_pw))
+ return False;
}
- else if (smbpw->smb_passwd == NULL)
- {
- DEBUG(0, ("change_lanman_password: no lanman password !\n"));
+ else if (pwd == NULL) {
+ DEBUG(0,("change_lanman_password: no lanman password !\n"));
return False;
}
/* Get the new lanman hash. */
- D_P16(smbpw->smb_passwd, pass2, unenc_new_pw);
+ D_P16(pwd, pass2, unenc_new_pw);
- smbpw->smb_passwd = unenc_new_pw;
- smbpw->smb_nt_passwd = NULL; /* We lose the NT hash. Sorry. */
+ if (!pdb_set_lanman_passwd(sampass, unenc_new_pw))
+ return False;
+ pdb_set_nt_passwd (sampass, NULL); /* We lose the NT hash. Sorry. */
- /* Now write it into the file. */
+ /* Now flush the sam_passwd struct to persistent storage */
become_root();
- ret = mod_smbpwd_entry(smbpw, False);
+ ret = pdb_update_sam_account (sampass, False);
unbecome_root();
return ret;
@@ -670,10 +692,9 @@ BOOL pass_oem_change(char *user,
uchar * ntdata, uchar * nthash)
{
fstring new_passwd;
- struct smb_passwd *sampw;
+ SAM_ACCOUNT *sampass = NULL;
BOOL ret = check_oem_password(user, lmdata, lmhash, ntdata, nthash,
- &sampw,
- new_passwd, sizeof(new_passwd));
+ &sampass, new_passwd, sizeof(new_passwd));
/*
* At this point we have the new case-sensitive plaintext
@@ -685,17 +706,15 @@ BOOL pass_oem_change(char *user,
*/
if (ret && lp_unix_password_sync())
- {
ret = chgpasswd(user, "", new_passwd, True);
- }
if (ret)
- {
- ret = change_oem_password(sampw, new_passwd, False);
- }
+ ret = change_oem_password(sampass, new_passwd, False);
memset(new_passwd, 0, sizeof(new_passwd));
+ pdb_free_sam(sampass);
+
return ret;
}
@@ -709,36 +728,41 @@ BOOL pass_oem_change(char *user,
BOOL check_oem_password(char *user,
uchar * lmdata, uchar * lmhash,
uchar * ntdata, uchar * nthash,
- struct smb_passwd **psmbpw, char *new_passwd,
+ SAM_ACCOUNT **hnd, char *new_passwd,
int new_passwd_size)
{
static uchar null_pw[16];
static uchar null_ntpw[16];
- struct smb_passwd *smbpw = NULL;
+ SAM_ACCOUNT *sampass = NULL;
+ uint8 *lanman_pw, *nt_pw;
+ uint16 acct_ctrl;
int new_pw_len;
uchar new_ntp16[16];
uchar unenc_old_ntpw[16];
uchar new_p16[16];
uchar unenc_old_pw[16];
char no_pw[2];
+ BOOL ret;
BOOL nt_pass_set = (ntdata != NULL && nthash != NULL);
+ pdb_init_sam(&sampass);
+
become_root();
- *psmbpw = smbpw = getsmbpwnam(user);
+ ret = pdb_getsampwnam(sampass, user);
unbecome_root();
- if (smbpw == NULL)
- {
+ if (ret == False) {
DEBUG(0, ("check_oem_password: getsmbpwnam returned NULL\n"));
return False;
}
- if (smbpw->acct_ctrl & ACB_DISABLED)
- {
- DEBUG(0,
- ("check_lanman_password: account %s disabled.\n",
- user));
+ *hnd = sampass;
+
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
+
+ if (acct_ctrl & ACB_DISABLED) {
+ DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
return False;
}
@@ -747,31 +771,27 @@ BOOL check_oem_password(char *user,
no_pw[1] = 0;
nt_lm_owf_gen(no_pw, null_ntpw, null_pw);
+ /* save pointers to passwords so we don't have to keep looking them up */
+ lanman_pw = pdb_get_lanman_passwd(sampass);
+ nt_pw = pdb_get_nt_passwd (sampass);
+
/* check for null passwords */
- if (smbpw->smb_passwd == NULL)
- {
- if (smbpw->acct_ctrl & ACB_PWNOTREQ)
- {
- smbpw->smb_passwd = null_pw;
- }
- else
- {
- DEBUG(0,
- ("check_oem_password: no lanman password !\n"));
+ if (lanman_pw == NULL) {
+ if (acct_ctrl & ACB_PWNOTREQ) {
+ if (!pdb_set_lanman_passwd(sampass, null_pw)) {
+ return False;
+ }
+ } else {
+ DEBUG(0,("check_oem_password: no lanman password !\n"));
return False;
}
}
- if (smbpw->smb_nt_passwd == NULL && nt_pass_set)
- {
- if (smbpw->acct_ctrl & ACB_PWNOTREQ)
- {
- smbpw->smb_nt_passwd = null_pw;
- }
- else
- {
- DEBUG(0,
- ("check_oem_password: no ntlm password !\n"));
+ if (pdb_get_nt_passwd(sampass) == NULL && nt_pass_set) {
+ if (acct_ctrl & ACB_PWNOTREQ)
+ pdb_set_nt_passwd(sampass, null_pw);
+ else {
+ DEBUG(0,("check_oem_password: no ntlm password !\n"));
return False;
}
}
@@ -779,7 +799,7 @@ BOOL check_oem_password(char *user,
/*
* Call the hash function to get the new password.
*/
- SamOEMhash((uchar *) lmdata, (uchar *) smbpw->smb_passwd, 516);
+ SamOEMhash((uchar *) lmdata, (uchar *)lanman_pw, 516);
/*
* The length of the new password is in the last 4 bytes of
@@ -787,31 +807,23 @@ BOOL check_oem_password(char *user,
*/
new_pw_len = IVAL(lmdata, 512);
- if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1)
- {
- DEBUG(0,
- ("check_oem_password: incorrect password length (%d).\n",
- new_pw_len));
+ if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1) {
+ DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
return False;
}
- if (nt_pass_set)
- {
+ if (nt_pass_set) {
/*
* nt passwords are in unicode
*/
int uni_pw_len = new_pw_len;
char *pw;
new_pw_len /= 2;
- pw =
- dos_unistrn2((uint16 *)(&lmdata[512 - uni_pw_len]),
- new_pw_len);
+ pw = dos_unistrn2((uint16 *)(&lmdata[512 - uni_pw_len]), new_pw_len);
memcpy(new_passwd, pw, new_pw_len + 1);
- }
- else
- {
+ } else {
memcpy(new_passwd, &lmdata[512 - new_pw_len], new_pw_len);
- new_passwd[new_pw_len] = '\0';
+ new_passwd[new_pw_len] = 0;
}
/*
@@ -829,10 +841,9 @@ BOOL check_oem_password(char *user,
*/
D_P16(new_p16, lmhash, unenc_old_pw);
- if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
+ if (memcmp(lanman_pw, unenc_old_pw, 16))
{
- DEBUG(0,
- ("check_oem_password: old lm password doesn't match.\n"));
+ DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
return False;
}
@@ -850,17 +861,15 @@ BOOL check_oem_password(char *user,
D_P16(new_ntp16, lmhash, unenc_old_pw);
D_P16(new_ntp16, nthash, unenc_old_ntpw);
- if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
+ if (memcmp(lanman_pw, unenc_old_pw, 16))
{
- DEBUG(0,
- ("check_oem_password: old lm password doesn't match.\n"));
+ DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
return False;
}
- if (memcmp(smbpw->smb_nt_passwd, unenc_old_ntpw, 16))
+ if (memcmp(nt_pw, unenc_old_ntpw, 16))
{
- DEBUG(0,
- ("check_oem_password: old nt password doesn't match.\n"));
+ DEBUG(0,("check_oem_password: old nt password doesn't match.\n"));
return False;
}
#ifdef DEBUG_PASSWORD
@@ -876,21 +885,23 @@ BOOL check_oem_password(char *user,
override = True, override XXXXXXXXXX'd password
************************************************************/
-BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd,
+BOOL change_oem_password(SAM_ACCOUNT *hnd, char *new_passwd,
BOOL override)
{
- int ret;
+ BOOL ret;
uchar new_nt_p16[16];
uchar new_p16[16];
nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
- smbpw->smb_passwd = new_p16;
- smbpw->smb_nt_passwd = new_nt_p16;
+ if (!pdb_set_lanman_passwd (hnd, new_p16))
+ return False;
+ if (!pdb_set_nt_passwd(hnd, new_nt_p16))
+ return False;
/* Now write it into the file. */
become_root();
- ret = mod_smbpwd_entry(smbpw, override);
+ ret = pdb_update_sam_account (hnd, override);
unbecome_root();
memset(new_passwd, '\0', strlen(new_passwd));
@@ -903,45 +914,47 @@ BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd,
***********************************************************/
BOOL check_plaintext_password(char *user, char *old_passwd,
- int old_passwd_size, struct smb_passwd **psmbpw)
+ int old_passwd_size, SAM_ACCOUNT **hnd)
{
- struct smb_passwd *smbpw = NULL;
+ SAM_ACCOUNT *sampass = NULL;
uchar old_pw[16], old_ntpw[16];
+ BOOL ret;
+
+ pdb_init_sam(&sampass);
become_root();
- *psmbpw = smbpw = getsmbpwnam(user);
+ ret = pdb_getsampwnam(sampass, user);
unbecome_root();
- if (smbpw == NULL)
+ *hnd = sampass;
+
+ if (ret == False)
{
- DEBUG(0,
- ("check_plaintext_password: getsmbpwnam returned NULL\n"));
+ DEBUG(0,("check_plaintext_password: getsmbpwnam returned NULL\n"));
return False;
}
- if (smbpw->acct_ctrl & ACB_DISABLED)
+ if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED)
{
- DEBUG(0,
- ("check_plaintext_password: account %s disabled.\n",
- user));
+ DEBUG(0,("check_plaintext_password: account %s disabled.\n", user));
return (False);
}
nt_lm_owf_gen(old_passwd, old_ntpw, old_pw);
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("check_plaintext_password: smbpw->smb_nt_passwd \n"));
- dump_data(100, smbpw->smb_nt_passwd, 16);
+ DEBUG(100, ("check_plaintext_password: nt_passwd \n"));
+ dump_data(100, pdb_get_nt_passwd(sampass), 16);
DEBUG(100, ("check_plaintext_password: old_ntpw \n"));
dump_data(100, old_ntpw, 16);
- DEBUG(100, ("check_plaintext_password: smbpw->smb_passwd \n"));
- dump_data(100, smbpw->smb_passwd, 16);
+ DEBUG(100, ("check_plaintext_password: lanman_passwd \n"));
+ dump_data(100, pdb_get_lanman_passwd(sampass), 16);
DEBUG(100, ("check_plaintext_password: old_pw\n"));
dump_data(100, old_pw, 16);
#endif
- if (memcmp(smbpw->smb_nt_passwd, old_ntpw, 16)
- && memcmp(smbpw->smb_passwd, old_pw, 16))
+ if (memcmp(pdb_get_nt_passwd(sampass), old_ntpw, 16)
+ && memcmp(pdb_get_lanman_passwd(sampass), old_pw, 16))
return (False);
else
return (True);
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 217c81228f7..7c0672efe0d 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -78,7 +78,7 @@ static void check_magic(files_struct *fsp,connection_struct *conn)
return;
}
- transfer_file(tmp_fd,outfd,st.st_size, NULL,0,0);
+ transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
close(tmp_fd);
close(outfd);
}
@@ -153,6 +153,9 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
lock_share_entry_fsp(fsp);
share_entry_count = del_share_mode(fsp, &share_entry);
+ DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
+ share_entry_count, fsp->fsp_name ));
+
/*
* We delete on close if it's the last open, and the
* delete on close flag was set in the entry we just deleted.
diff --git a/source/smbd/connection.c b/source/smbd/connection.c
index 796a54e77dd..9e074a8e809 100644
--- a/source/smbd/connection.c
+++ b/source/smbd/connection.c
@@ -59,7 +59,8 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
kbuf.dsize = sizeof(key);
if (tdb_delete(tdb, kbuf) != 0) {
- DEBUG(0,("yield_connection: tdb_delete failed with error %s.\n", tdb_errorstr(tdb) ));
+ DEBUG(0,("yield_connection: tdb_delete for name %s failed with error %s.\n",
+ name, tdb_errorstr(tdb) ));
return (False);
}
@@ -114,12 +115,10 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
{
struct connections_key key;
struct connections_data crec;
- TDB_DATA kbuf, dbuf, lockkey;
- BOOL rec_locked = False;
- BOOL ret = True;
+ TDB_DATA kbuf, dbuf;
if (!tdb) {
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST,
+ tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
O_RDWR | O_CREAT, 0644);
}
if (!tdb)
@@ -137,34 +136,21 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
cs.name = lp_servicename(SNUM(conn));
cs.Clear = Clear;
- lockkey.dptr = cs.name;
- lockkey.dsize = strlen(cs.name)+1;
-
/*
- * Go through and count the connections with hash chain representing the service name
- * locked. This is slow but removes race conditions. JRA.
+ * This has a race condition, but locking the chain before hand is worse
+ * as it leads to deadlock.
*/
- if (tdb_chainlock(tdb, lockkey)) {
- DEBUG(0,("claim_connection: tdb_chainlock failed %s\n",
- tdb_errorstr(tdb) ));
- return False;
- }
-
- rec_locked = True;
-
if (tdb_traverse(tdb, count_fn, &cs) == -1) {
DEBUG(0,("claim_connection: traverse of connections.tdb failed with error %s.\n",
tdb_errorstr(tdb) ));
- ret = False;
- goto out;
+ return False;
}
if (cs.curr_connections >= max_connections) {
DEBUG(1,("claim_connection: Max connections (%d) exceeded for %s\n",
max_connections, name ));
- ret = False;
- goto out;
+ return False;
}
}
@@ -201,13 +187,8 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) {
DEBUG(0,("claim_connection: tdb_store failed with error %s.\n",
tdb_errorstr(tdb) ));
- ret = False;
+ return False;
}
- out:
-
- if (rec_locked)
- tdb_chainunlock(tdb, lockkey);
-
- return ret;
+ return True;
}
diff --git a/source/smbd/error.c b/source/smbd/error.c
index 472a8d8fd15..164f4e42a56 100644
--- a/source/smbd/error.c
+++ b/source/smbd/error.c
@@ -22,125 +22,95 @@
#include "includes.h"
extern int DEBUGLEVEL;
+extern uint32 global_client_caps;
/* these can be set by some functions to override the error codes */
int unix_ERR_class=SMB_SUCCESS;
int unix_ERR_code=0;
-
-/****************************************************************************
- create an error packet from a cached error.
-****************************************************************************/
-int cached_error_packet(char *inbuf,char *outbuf,files_struct *fsp,int line)
-{
- write_bmpx_struct *wbmpx = fsp->wbmpx_ptr;
-
- int32 eclass = wbmpx->wr_errclass;
- int32 err = wbmpx->wr_error;
-
- /* We can now delete the auxiliary struct */
- free((char *)wbmpx);
- fsp->wbmpx_ptr = NULL;
- return error_packet(inbuf,outbuf,eclass,err,line);
-}
-
-
-struct
-{
- int unixerror;
- int smbclass;
- int smbcode;
-} unix_smb_errmap[] =
-{
- {EPERM,ERRDOS,ERRnoaccess},
- {EACCES,ERRDOS,ERRnoaccess},
- {ENOENT,ERRDOS,ERRbadfile},
- {ENOTDIR,ERRDOS,ERRbadpath},
- {EIO,ERRHRD,ERRgeneral},
- {EBADF,ERRSRV,ERRsrverror},
- {EINVAL,ERRSRV,ERRsrverror},
- {EEXIST,ERRDOS,ERRfilexists},
- {ENFILE,ERRDOS,ERRnofids},
- {EMFILE,ERRDOS,ERRnofids},
- {ENOSPC,ERRHRD,ERRdiskfull},
+struct {
+ int unixerror;
+ int smbclass;
+ int smbcode;
+} unix_smb_errmap[] = {
+ {EPERM,ERRDOS,ERRnoaccess},
+ {EACCES,ERRDOS,ERRnoaccess},
+ {ENOENT,ERRDOS,ERRbadfile},
+ {ENOTDIR,ERRDOS,ERRbadpath},
+ {EIO,ERRHRD,ERRgeneral},
+ {EBADF,ERRDOS,ERRbadfid},
+ {EINVAL,ERRSRV,ERRsrverror},
+ {EEXIST,ERRDOS,ERRfilexists},
+ {ENFILE,ERRDOS,ERRnofids},
+ {EMFILE,ERRDOS,ERRnofids},
+ {ENOSPC,ERRHRD,ERRdiskfull},
#ifdef EDQUOT
- {EDQUOT,ERRHRD,ERRdiskfull},
+ {EDQUOT,ERRHRD,ERRdiskfull},
#endif
#ifdef ENOTEMPTY
- {ENOTEMPTY,ERRDOS,ERRnoaccess},
+ {ENOTEMPTY,ERRDOS,ERRnoaccess},
#endif
#ifdef EXDEV
- {EXDEV,ERRDOS,ERRdiffdevice},
+ {EXDEV,ERRDOS,ERRdiffdevice},
#endif
- {EROFS,ERRHRD,ERRnowrite},
- {0,0,0}
+ {EROFS,ERRHRD,ERRnowrite},
+ {0,0,0}
};
/****************************************************************************
- create an error packet from errno
+ Create an error packet from errno.
****************************************************************************/
-int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
-{
- int eclass=def_class;
- int ecode=def_code;
- int i=0;
-
- if (unix_ERR_class != SMB_SUCCESS)
- {
- eclass = unix_ERR_class;
- ecode = unix_ERR_code;
- unix_ERR_class = SMB_SUCCESS;
- unix_ERR_code = 0;
- }
- else
- {
- while (unix_smb_errmap[i].smbclass != 0)
- {
- if (unix_smb_errmap[i].unixerror == errno)
- {
- eclass = unix_smb_errmap[i].smbclass;
- ecode = unix_smb_errmap[i].smbcode;
- break;
- }
- i++;
- }
- }
- return(error_packet(inbuf,outbuf,eclass,ecode,line));
+int unix_error_packet(char *outbuf,int def_class,uint32 def_code,int line, const char *file)
+{
+ int eclass=def_class;
+ int ecode=def_code;
+ int i=0;
+
+ if (unix_ERR_class != SMB_SUCCESS) {
+ eclass = unix_ERR_class;
+ ecode = unix_ERR_code;
+ unix_ERR_class = SMB_SUCCESS;
+ unix_ERR_code = 0;
+ } else {
+ while (unix_smb_errmap[i].smbclass != 0) {
+ if (unix_smb_errmap[i].unixerror == errno) {
+ eclass = unix_smb_errmap[i].smbclass;
+ ecode = unix_smb_errmap[i].smbcode;
+ break;
+ }
+ i++;
+ }
+ }
+
+ return(error_packet(outbuf,0,eclass,ecode,line,file));
}
-
/****************************************************************************
- create an error packet. Normally called using the ERROR() macro
+ Create an error packet. Normally called using the ERROR() macro.
****************************************************************************/
-int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
+
+int error_packet(char *outbuf,uint32 nt_err, int error_class,uint32 error_code,int line, const char *file)
{
- int outsize = set_message(outbuf,0,0,True);
- int cmd = CVAL(inbuf,smb_com);
- int flgs2 = SVAL(outbuf,smb_flg2);
+ int outsize = set_message(outbuf,0,0,True);
+ int cmd = CVAL(outbuf,smb_com);
- if (errno != 0)
- DEBUG(3,("error string = %s\n",strerror(errno)));
+ if (errno != 0)
+ DEBUG(3,("error string = %s\n",strerror(errno)));
- if ((flgs2 & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES)
- {
- SIVAL(outbuf,smb_rcls,error_code);
+ if ((global_client_caps & CAP_STATUS32) && (nt_err != 0)) {
+ SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
+ SIVAL(outbuf,smb_rcls,nt_err);
- DEBUG( 3, ( "32 bit error packet at line %d cmd=%d (%s) eclass=%08x [%s]\n",
- line, cmd, smb_fn_name(cmd), error_code, smb_errstr(outbuf) ) );
- }
- else
- {
- CVAL(outbuf,smb_rcls) = error_class;
- SSVAL(outbuf,smb_err,error_code);
- DEBUG( 3, ( "error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
- line,
- (int)CVAL(inbuf,smb_com),
- smb_fn_name(CVAL(inbuf,smb_com)),
- error_class,
- error_code ) );
-
- }
+ DEBUG( 3, ( "32 bit error packet at %s(%d) cmd=%d (%s) eclass=%08x [%s]\n",
+ file, line, cmd, smb_fn_name(cmd), nt_err, smb_errstr(outbuf) ) );
+
+ } else {
+ CVAL(outbuf,smb_rcls) = error_class;
+ SSVAL(outbuf,smb_err,error_code);
+ DEBUG( 3, ( "error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n",
+ file, line, cmd, smb_fn_name(cmd), error_class, error_code ) );
+ }
- return(outsize);
+ return(outsize);
}
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index 76b043c2dac..3ec6d1f1cff 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -100,10 +100,9 @@ void send_trans_reply(char *outbuf,
set_message(outbuf,10,1+align+this_ldata+this_lparam,True);
- if (buffer_too_large)
- {
+ if (buffer_too_large) {
/* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */
- if (!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32 ))) {
+ if (!(global_client_caps & CAP_STATUS32 )) {
/* Win9x version. */
SSVAL(outbuf, smb_err, ERRmoredata);
SCVAL(outbuf, smb_rcls, ERRDOS);
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 59d765e8391..3d8844d5be1 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -857,120 +857,111 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char *QueueName = p;
- int uLevel;
- int count=0;
- int snum;
- char* str3;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
- char* tmpdata=NULL;
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ char *QueueName = p;
+ int uLevel;
+ int count=0;
+ int snum;
+ char* str3;
+ struct pack_desc desc;
+ print_queue_struct *queue=NULL;
+ print_status_struct status;
+ char* tmpdata=NULL;
- memset((char *)&status,'\0',sizeof(status));
- memset((char *)&desc,'\0',sizeof(desc));
+ memset((char *)&status,'\0',sizeof(status));
+ memset((char *)&desc,'\0',sizeof(desc));
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
- str3 = p + 4;
+ p = skip_string(p,1);
+ uLevel = SVAL(p,0);
+ str3 = p + 4;
- /* remove any trailing username */
- if ((p = strchr(QueueName,'%'))) *p = 0;
+ /* remove any trailing username */
+ if ((p = strchr(QueueName,'%')))
+ *p = 0;
- DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName));
+ DEBUG(3,("api_DosPrintQGetInfo: uLevel=%d name=%s\n",uLevel,QueueName));
- /* check it's a supported varient */
- if (!prefix_ok(str1,"zWrLh")) return False;
- if (!check_printq_info(&desc,uLevel,str2,str3)) {
- /*
- * Patch from Scott Moomaw <scott@bridgewater.edu>
- * to return the 'invalid info level' error if an
- * unknown level was requested.
- */
- *rdata_len = 0;
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,ERROR_INVALID_LEVEL);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,0);
- return(True);
- }
+ /* check it's a supported varient */
+ if (!prefix_ok(str1,"zWrLh"))
+ return False;
+ if (!check_printq_info(&desc,uLevel,str2,str3)) {
+ /*
+ * Patch from Scott Moomaw <scott@bridgewater.edu>
+ * to return the 'invalid info level' error if an
+ * unknown level was requested.
+ */
+ *rdata_len = 0;
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,ERRunknownlevel);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,0);
+ return(True);
+ }
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
+ snum = lp_servicenumber(QueueName);
+ if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0) {
+ lp_add_printer(QueueName,pnum);
+ snum = lp_servicenumber(QueueName);
+ }
+ }
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- if (uLevel==52) {
- count = get_printerdrivernumber(snum);
- DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
- } else {
- count = print_queue_status(snum, &queue,&status);
- }
+ if (snum < 0 || !VALID_SNUM(snum))
+ return(False);
- if (mdrcnt > 0) {
- *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- } else {
- /*
- * Don't return data but need to get correct length
- * init_package will return wrong size if buflen=0
- */
- desc.buflen = getlen(desc.format);
- desc.base = tmpdata = (char *) malloc (desc.buflen);
- }
+ if (uLevel==52) {
+ count = get_printerdrivernumber(snum);
+ DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
+ } else {
+ count = print_queue_status(snum, &queue,&status);
+ }
- if (init_package(&desc,1,count)) {
- desc.subcount = count;
- fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
- } else if(uLevel == 0) {
-#if 0
- /*
- * This is a *disgusting* hack.
- * This is *so* bad that even I'm embarrassed (and I
- * have no shame). Here's the deal :
- * Until we get the correct SPOOLSS code into smbd
- * then when we're running with NT SMB support then
- * NT makes this call with a level of zero, and then
- * immediately follows it with an open request to
- * the \\SRVSVC pipe. If we allow that open to
- * succeed then NT barfs when it cannot open the
- * \\SPOOLSS pipe immediately after and continually
- * whines saying "Printer name is invalid" forever
- * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
- * to fail, then NT downgrades to using the downlevel code
- * and everything works as well as before. I hate
- * myself for adding this code.... JRA.
- */
-
- fail_next_srvsvc_open();
-#endif
- }
+ if (mdrcnt > 0) {
+ *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ } else {
+ /*
+ * Don't return data but need to get correct length
+ * init_package will return wrong size if buflen=0
+ */
+ desc.buflen = getlen(desc.format);
+ desc.base = tmpdata = (char *) malloc (desc.buflen);
+ }
- *rdata_len = desc.usedlen;
+ if (init_package(&desc,1,count)) {
+ desc.subcount = count;
+ fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
+ }
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
+ /*
+ * We must set the return code to ERRbuftoosmall
+ * in order to support lanman style printing with Win NT/2k
+ * clients --jerry
+ */
+ if (!mdrcnt && lp_disable_spoolss())
+ desc.errcode = ERRbuftoosmall;
+
+ *rdata_len = desc.usedlen;
- DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,desc.neededlen);
- if (queue) free(queue);
- if (tmpdata) free (tmpdata);
+ DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
- return(True);
+ if (queue)
+ free(queue);
+ if (tmpdata)
+ free (tmpdata);
+
+ return(True);
}
/****************************************************************************
@@ -1009,7 +1000,7 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
*rdata_len = 0;
*rparam_len = 6;
*rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,ERROR_INVALID_LEVEL);
+ SSVALS(*rparam,0,ERRunknownlevel);
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,0);
return(True);
@@ -1143,10 +1134,16 @@ static int get_server_info(uint32 servertype,
if (!*ptr) continue;
if (count == alloced) {
+ struct srv_info_struct *ts;
+
alloced += 10;
- (*servers) = (struct srv_info_struct *)
- Realloc(*servers,sizeof(**servers)*alloced);
- if (!(*servers)) return(0);
+ ts = (struct srv_info_struct *)Realloc(*servers,sizeof(**servers)*alloced);
+ if (!ts) {
+ DEBUG(0,("get_server_info: failed to enlarge servers info struct!\n"));
+ return(0);
+ }
+ else
+ *servers = ts;
memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
}
s = &(*servers)[count];
@@ -1775,7 +1772,7 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
{
fstring saved_pass2;
- struct smb_passwd *smbpw = NULL;
+ SAM_ACCOUNT *sampass = NULL;
/*
* Save the new password as change_oem_password overwrites it
@@ -1784,8 +1781,8 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
fstrcpy(saved_pass2, pass2);
- if (check_plaintext_password(user,pass1,strlen(pass1),&smbpw) &&
- change_oem_password(smbpw,pass2,False))
+ if (check_plaintext_password(user,pass1,strlen(pass1),&sampass) &&
+ change_oem_password(sampass,pass2,False))
{
SSVAL(*rparam,0,NERR_Success);
@@ -1826,10 +1823,10 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
if(SVAL(*rparam,0) != NERR_Success)
{
- struct smb_passwd *sampw = NULL;
+ SAM_ACCOUNT *sampass = NULL;
- if(check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &sampw) &&
- change_lanman_password(sampw,(unsigned char *)pass1,(unsigned char *)pass2))
+ if(check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &sampass) &&
+ change_lanman_password(sampass,(unsigned char *)pass1,(unsigned char *)pass2))
{
SSVAL(*rparam,0,NERR_Success);
}
diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c
index 1cc602dc051..d6d470c2dab 100644
--- a/source/smbd/mangle.c
+++ b/source/smbd/mangle.c
@@ -317,7 +317,7 @@ BOOL is_mangled( char *s )
* are the correct case. See case_mangle and
* case_default above.
*
- * Output: True if the name is a valid DOS name, else FALSE.
+ * Output: True if the name is a valid DOS name, else False.
*
* ************************************************************************** **
*/
@@ -987,7 +987,7 @@ BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum)
{
char *map;
DEBUG(5,("name_map_mangle( %s, need83 = %s, cache83 = %s, %d )\n", OutName,
- need83 ? "TRUE" : "FALSE", cache83 ? "TRUE" : "FALSE", snum));
+ need83 ? "True" : "False", cache83 ? "True" : "False", snum));
#ifdef MANGLE_LONG_FILENAMES
if( !need83 && is_illegal_name(OutName) )
diff --git a/source/smbd/notify.c b/source/smbd/notify.c
index 3c21ce1e1b5..d0966289fe7 100644
--- a/source/smbd/notify.c
+++ b/source/smbd/notify.c
@@ -23,6 +23,7 @@
#include "includes.h"
extern int DEBUGLEVEL;
+extern uint32 global_client_caps;
static struct cnotify_fns *cnotify;
@@ -62,8 +63,11 @@ static void change_notify_reply_packet(char *inbuf, uint32 error_code)
* can even determine how MS failed to test stuff and why.... :-). JRA.
*/
- SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
- ERROR(0,error_code);
+ if (global_client_caps & CAP_STATUS32) {
+ ERROR(0,error_code);
+ } else {
+ ERROR(ERRDOS,STATUS_NOTIFY_ENUM_DIR);
+ }
/*
* Seems NT needs a transact command with an error code
diff --git a/source/smbd/notify_kernel.c b/source/smbd/notify_kernel.c
index d7408c06b57..f1e40793c85 100644
--- a/source/smbd/notify_kernel.c
+++ b/source/smbd/notify_kernel.c
@@ -125,7 +125,7 @@ static void *kernel_register_notify(connection_struct *conn, char *path, uint32
int fd;
unsigned long kernel_flags;
- fd = dos_open(path, O_RDONLY, 0);
+ fd = sys_open(dos_to_unix(path,False),O_RDONLY, 0);
if (fd == -1) {
DEBUG(3,("Failed to open directory %s for change notify\n", path));
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index 7dfe4b7e1e8..c9e70401bae 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -28,6 +28,7 @@ extern int global_oplock_break;
extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
+extern uint32 global_client_caps;
static char *known_nt_pipes[] = {
"\\LANMAN",
@@ -63,8 +64,8 @@ struct generic_mapping file_generic_mapping = {
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_error, char *params,
- int paramsize, char *pdata, int datasize)
+static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_error, int eclass, uint32 ecode,
+ char *params, int paramsize, char *pdata, int datasize)
{
extern int max_send;
int data_to_send = datasize;
@@ -84,10 +85,7 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err
set_message(outbuf,18,0,True);
if(nt_error != 0) {
- /* NT Error. */
- SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
-
- ERROR(0,nt_error);
+ ERROR_BOTH(nt_error,eclass,ecode);
}
/*
@@ -256,29 +254,29 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err
static void get_filename( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
{
- /*
- * We need various heuristics here to detect a unicode string... JRA.
- */
+ /*
+ * We need various heuristics here to detect a unicode string... JRA.
+ */
- DEBUG(10,("get_filename: data_offset = %d, data_len = %d, fname_len = %d\n",
- data_offset, data_len, fname_len ));
+ DEBUG(10,("get_filename: data_offset = %d, data_len = %d, fname_len = %d\n",
+ data_offset, data_len, fname_len ));
- if(data_len - fname_len > 1) {
- /*
- * NT 5.0 Beta 2 has kindly sent us a UNICODE string
- * without bothering to set the unicode bit. How kind.
- *
- * Firstly - ensure that the data offset is aligned
- * on a 2 byte boundary - add one if not.
- */
- fname_len = fname_len/2;
- if(data_offset & 1)
- data_offset++;
- pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
- } else {
- StrnCpy(fname,inbuf+data_offset,fname_len);
- fname[fname_len] = '\0';
- }
+ if(data_len - fname_len > 1) {
+ /*
+ * NT 5.0 Beta 2 has kindly sent us a UNICODE string
+ * without bothering to set the unicode bit. How kind.
+ *
+ * Firstly - ensure that the data offset is aligned
+ * on a 2 byte boundary - add one if not.
+ */
+ fname_len = fname_len/2;
+ if(data_offset & 1)
+ data_offset++;
+ pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
+ } else {
+ StrnCpy(fname,inbuf+data_offset,fname_len);
+ fname[fname_len] = '\0';
+ }
}
/****************************************************************************
@@ -288,32 +286,38 @@ static void get_filename( char *fname, char *inbuf, int data_offset, int data_le
static void get_filename_transact( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
{
- /*
- * We need various heuristics here to detect a unicode string... JRA.
- */
+ DEBUG(10,("get_filename_transact: data_offset = %d, data_len = %d, fname_len = %d\n",
+ data_offset, data_len, fname_len ));
- DEBUG(10,("get_filename_transact: data_offset = %d, data_len = %d, fname_len = %d\n",
- data_offset, data_len, fname_len ));
+ /*
+ * Win2K sends a unicode filename plus one extra alingment byte.
+ * WinNT4.x send an ascii string with multiple garbage bytes on
+ * the end here.
+ */
- /*
- * Win2K sends a unicode filename plus one extra alingment byte.
- * WinNT4.x send an ascii string with multiple garbage bytes on
- * the end here.
- */
+ /*
+ * We need various heuristics here to detect a unicode string... JRA.
+ */
- if((data_len == 1) || (inbuf[data_offset] == '\0')) {
- /*
- * Ensure that the data offset is aligned
- * on a 2 byte boundary - add one if not.
- */
- fname_len = fname_len/2;
- if(data_offset & 1)
- data_offset++;
- pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
- } else {
- StrnCpy(fname,inbuf+data_offset,fname_len);
- fname[fname_len] = '\0';
- }
+ if( ((fname_len % 2) == 0) &&
+ (
+ (data_len == 1) ||
+ (inbuf[data_offset] == '\0') ||
+ ((fname_len > 1) && (inbuf[data_offset+1] == '\\') && (inbuf[data_offset+2] == '\0'))
+ )) {
+
+ /*
+ * Ensure that the data offset is aligned
+ * on a 2 byte boundary - add one if not.
+ */
+ fname_len = fname_len/2;
+ if(data_offset & 1)
+ data_offset++;
+ pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
+ } else {
+ StrnCpy(fname,inbuf+data_offset,fname_len);
+ fname[fname_len] = '\0';
+ }
}
/****************************************************************************
@@ -526,69 +530,6 @@ to open_mode %x\n", (unsigned long)desired_access, (unsigned long)share_access,
return smb_open_mode;
}
-#if 0
-/*
- * This is a *disgusting* hack.
- * This is *so* bad that even I'm embarrassed (and I
- * have no shame). Here's the deal :
- * Until we get the correct SPOOLSS code into smbd
- * then when we're running with NT SMB support then
- * NT makes this call with a level of zero, and then
- * immediately follows it with an open request to
- * the \\SRVSVC pipe. If we allow that open to
- * succeed then NT barfs when it cannot open the
- * \\SPOOLSS pipe immediately after and continually
- * whines saying "Printer name is invalid" forever
- * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
- * to fail, then NT downgrades to using the downlevel code
- * and everything works as well as before. I hate
- * myself for adding this code.... JRA.
- *
- * The HACK_FAIL_TIME define allows only a 2
- * second window for this to occur, just in
- * case...
- */
-
-static BOOL fail_next_srvsvc = False;
-static time_t fail_time;
-#define HACK_FAIL_TIME 2 /* In seconds. */
-
-void fail_next_srvsvc_open(void)
-{
- /* Check client is WinNT proper; Win2K doesn't like Jeremy's hack - matty */
- if (get_remote_arch() != RA_WINNT)
- return;
-
- fail_next_srvsvc = True;
- fail_time = time(NULL);
- DEBUG(10,("fail_next_srvsvc_open: setting up timeout close of \\srvsvc pipe for print fix.\n"));
-}
-
-/*
- * HACK alert.... see above - JRA.
- */
-
-BOOL should_fail_next_srvsvc_open(const char *pipename)
-{
-
- DEBUG(10,("should_fail_next_srvsvc_open: fail = %d, pipe = %s\n",
- (int)fail_next_srvsvc, pipename));
-
- if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
- fail_next_srvsvc = False;
- fail_time = (time_t)0;
- DEBUG(10,("should_fail_next_srvsvc_open: End of timeout close of \\srvsvc pipe for print fix.\n"));
- }
-
- if(fail_next_srvsvc && strequal(pipename, "srvsvc")) {
- fail_next_srvsvc = False;
- DEBUG(10,("should_fail_next_srvsvc_open: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
- return True;
- }
- return False;
-}
-#endif
-
/****************************************************************************
Reply to an NT create and X call on a pipe.
****************************************************************************/
@@ -603,6 +544,10 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
/* See if it is one we want to handle. */
+
+ if (lp_disable_spoolss() && strequal(fname, "\\spoolss"))
+ return(ERROR(ERRSRV,ERRaccess));
+
for( i = 0; known_nt_pipes[i]; i++ )
if( strequal(fname,known_nt_pipes[i]))
break;
@@ -613,11 +558,6 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
/* Strip \\ off the name. */
fname++;
-#if 0
- if(should_fail_next_srvsvc_open(fname))
- return (ERROR(ERRSRV,ERRaccess));
-#endif
-
DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
p = open_rpc_pipe_p(fname, conn, vuid);
@@ -744,7 +684,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
size_t dir_name_len;
if(!dir_fsp) {
- END_PROFILE(SMBntcreateX);
+ END_PROFILE(SMBntcreateX);
return(ERROR(ERRDOS,ERRbadfid));
}
@@ -757,11 +697,10 @@ int reply_ntcreate_and_X(connection_struct *conn,
smb_buflen(inbuf),fname_len);
if( strchr(fname, ':')) {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
END_PROFILE(SMBntcreateX);
- return(ERROR(0, NT_STATUS_OBJECT_PATH_NOT_FOUND));
+ return(ERROR_BOTH(NT_STATUS_OBJECT_PATH_NOT_FOUND,ERRDOS,ERRbadpath));
}
- END_PROFILE(SMBntcreateX);
+ END_PROFILE(SMBntcreateX);
return(ERROR(ERRDOS,ERRbadfid));
}
@@ -898,9 +837,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
if (create_options & FILE_NON_DIRECTORY_FILE) {
restore_case_semantics(file_attributes);
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
END_PROFILE(SMBntcreateX);
- return(ERROR(0, NT_STATUS_FILE_IS_A_DIRECTORY));
+ return(ERROR_BOTH(NT_STATUS_FILE_IS_A_DIRECTORY,ERRDOS,ERRbadaccess));
}
oplock_request = 0;
@@ -1092,7 +1030,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn,
DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(inbuf, outbuf, bufsize, 0, params, 69, *ppdata, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, params, 69, *ppdata, 0);
return -1;
}
@@ -1101,7 +1039,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn,
Internal fn to set security descriptors.
****************************************************************************/
-static BOOL set_sd(files_struct *fsp, char *data, uint32 sd_len, uint security_info_sent, int *pdef_class,uint32 *pdef_code)
+static BOOL set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 security_info_sent, int *pdef_class,uint32 *pdef_code)
{
prs_struct pd;
SEC_DESC *psd = NULL;
@@ -1281,8 +1219,7 @@ static int call_nt_transact_create(connection_struct *conn,
total_parameter_count - 53 - fname_len, fname_len);
if( strchr(fname, ':')) {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_OBJECT_PATH_NOT_FOUND));
+ return(ERROR_BOTH(NT_STATUS_OBJECT_PATH_NOT_FOUND,ERRDOS,ERRbadpath));
}
return(ERROR(ERRDOS,ERRbadfid));
@@ -1388,8 +1325,7 @@ static int call_nt_transact_create(connection_struct *conn,
if (create_options & FILE_NON_DIRECTORY_FILE) {
restore_case_semantics(file_attributes);
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_FILE_IS_A_DIRECTORY));
+ return(ERROR_BOTH(NT_STATUS_FILE_IS_A_DIRECTORY,ERRDOS, ERRbadaccess));
}
oplock_request = 0;
@@ -1521,7 +1457,7 @@ static int call_nt_transact_create(connection_struct *conn,
DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
/* Send the required number of replies */
- send_nt_replies(inbuf, outbuf, bufsize, 0, params, 69, *ppdata, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, params, 69, *ppdata, 0);
return -1;
}
@@ -1621,7 +1557,7 @@ static int call_nt_transact_rename(connection_struct *conn,
/*
* Rename was successful.
*/
- send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, NULL, 0, NULL, 0);
DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
fsp->fsp_name, new_name));
@@ -1685,7 +1621,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
if(max_data_count < sd_size) {
- send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL,
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_BUFFER_TOO_SMALL, ERRDOS, 122,
params, 4, *ppdata, 0);
return -1;
}
@@ -1741,7 +1677,7 @@ security descriptor.\n"));
talloc_destroy(mem_ctx);
- send_nt_replies(inbuf, outbuf, bufsize, 0, params, 4, data, (int)sd_size);
+ send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, params, 4, data, (int)sd_size);
return -1;
}
@@ -1780,7 +1716,7 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
if (!set_sd( fsp, data, total_data_count, security_info_sent, &error_class, &error_code))
return (ERROR(error_class, error_code));
- send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
+ send_nt_replies(inbuf, outbuf, bufsize, 0, 0, 0, NULL, 0, NULL, 0);
return -1;
}
@@ -1798,7 +1734,7 @@ static int call_nt_transact_ioctl(connection_struct *conn,
DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n"));
logged_message = True; /* Only print this once... */
}
- return(ERROR(ERRSRV,ERRnosupport));
+ return(ERROR_BOTH(NT_STATUS_NOT_IMPLEMENTED,ERRSRV,ERRnosupport));
}
/****************************************************************************
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 92b164ce951..6919249a226 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -3,6 +3,7 @@
Version 1.9.
file opening and share modes
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001
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
@@ -452,108 +453,151 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T
SMB_INO_T inode, int share_mode, int *p_flags, int *p_oplock_request,
BOOL *p_all_current_opens_are_level_II)
{
- int i;
- int num_share_modes;
- int oplock_contention_count = 0;
- share_mode_entry *old_shares = 0;
- BOOL fcbopen = False;
- BOOL broke_oplock;
+ int i;
+ int num_share_modes;
+ int oplock_contention_count = 0;
+ share_mode_entry *old_shares = 0;
+ BOOL fcbopen = False;
+ BOOL broke_oplock;
- if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
- fcbopen = True;
+ if(GET_OPEN_MODE(share_mode) == DOS_OPEN_FCB)
+ fcbopen = True;
- num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
+ num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
- if(num_share_modes == 0)
- return 0;
+ if(num_share_modes == 0)
+ return 0;
- /*
- * Check if the share modes will give us access.
- */
+ /*
+ * Check if the share modes will give us access.
+ */
- do {
+ do {
+ share_mode_entry broken_entry;
- broke_oplock = False;
- *p_all_current_opens_are_level_II = True;
+ broke_oplock = False;
+ *p_all_current_opens_are_level_II = True;
- for(i = 0; i < num_share_modes; i++) {
- share_mode_entry *share_entry = &old_shares[i];
+ for(i = 0; i < num_share_modes; i++) {
+ share_mode_entry *share_entry = &old_shares[i];
- /*
- * By observation of NetBench, oplocks are broken *before* share
- * modes are checked. This allows a file to be closed by the client
- * if the share mode would deny access and the client has an oplock.
- * Check if someone has an oplock on this file. If so we must break
- * it before continuing.
- */
+ /*
+ * By observation of NetBench, oplocks are broken *before* share
+ * modes are checked. This allows a file to be closed by the client
+ * if the share mode would deny access and the client has an oplock.
+ * Check if someone has an oplock on this file. If so we must break
+ * it before continuing.
+ */
- if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
- (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
+ if((*p_oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
+ (!*p_oplock_request && (share_entry->op_type != NO_OPLOCK))) {
- BOOL opb_ret;
+ BOOL opb_ret;
- DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
+ DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
- /* Oplock break - unlock to request it. */
- unlock_share_entry(conn, dev, inode);
+ /* Oplock break - unlock to request it. */
+ unlock_share_entry(conn, dev, inode);
- opb_ret = request_oplock_break(share_entry, dev, inode);
+ opb_ret = request_oplock_break(share_entry, dev, inode);
- /* Now relock. */
- lock_share_entry(conn, dev, inode);
+ /* Now relock. */
+ lock_share_entry(conn, dev, inode);
- if(opb_ret == False) {
- free((char *)old_shares);
- DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
+ if(opb_ret == False) {
+ DEBUG(0,("open_mode_check: FAILED when breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- return -1;
- }
+ free((char *)old_shares);
+ errno = EACCES;
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadshare;
+ return -1;
+ }
+
+ broke_oplock = True;
+ broken_entry = *share_entry;
+ break;
+
+ } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
+ *p_all_current_opens_are_level_II = False;
+ }
- broke_oplock = True;
- *p_all_current_opens_are_level_II = False;
- break;
+ /* someone else has a share lock on it, check to see
+ if we can too */
- } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- *p_all_current_opens_are_level_II = False;
- }
+ if(check_share_mode(share_entry, share_mode, fname, fcbopen, p_flags) == False) {
+ free((char *)old_shares);
+ errno = EACCES;
+ return -1;
+ }
- /* someone else has a share lock on it, check to see
- if we can too */
+ } /* end for */
- if(check_share_mode(share_entry, share_mode, fname, fcbopen, p_flags) == False) {
- free((char *)old_shares);
- errno = EACCES;
- return -1;
- }
+ if(broke_oplock) {
+ free((char *)old_shares);
+ num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
+ oplock_contention_count++;
- } /* end for */
+ /* Paranoia check that this is no longer an exlusive entry. */
+ for(i = 0; i < num_share_modes; i++) {
+ share_mode_entry *share_entry = &old_shares[i];
- if(broke_oplock) {
- free((char *)old_shares);
- num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
- oplock_contention_count++;
- }
- } while(broke_oplock);
+ if (share_modes_identical(&broken_entry, share_entry) &&
+ EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
- if(old_shares != 0)
- free((char *)old_shares);
+ /*
+ * This should not happen. The target left this oplock
+ * as exlusive.... The process *must* be dead....
+ */
- /*
- * Refuse to grant an oplock in case the contention limit is
- * reached when going through the lock list multiple times.
- */
+ DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s, \
+dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
- if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
- *p_oplock_request = 0;
- DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
- oplock_contention_count ));
- }
+ if (process_exists(broken_entry.pid)) {
+ pstring errmsg;
+ slprintf(errmsg, sizeof(errmsg)-1,
+ "open_mode_check: Existant process %d left active oplock.\n",
+ broken_entry.pid );
+ smb_panic(errmsg);
+ }
+
+ if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
+ errno = EACCES;
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadshare;
+ return -1;
+ }
+
+ /*
+ * We must reload the share modes after deleting the
+ * other process's entry.
+ */
+
+ free((char *)old_shares);
+ num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
+ break;
+ }
+ } /* end for paranoia... */
+ } /* end if broke_oplock */
+
+ } while(broke_oplock);
+
+ if(old_shares != 0)
+ free((char *)old_shares);
- return num_share_modes;
+ /*
+ * Refuse to grant an oplock in case the contention limit is
+ * reached when going through the lock list multiple times.
+ */
+
+ if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn))) {
+ *p_oplock_request = 0;
+ DEBUG(4,("open_mode_check: oplock contention = %d. Not granting oplock.\n",
+ oplock_contention_count ));
+ }
+
+ return num_share_modes;
}
/****************************************************************************
@@ -569,6 +613,7 @@ static void kernel_flock(files_struct *fsp, int deny_mode)
else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
if (kernel_mode) flock(fsp->fd, kernel_mode);
#endif
+ ;;
}
@@ -1041,7 +1086,7 @@ files_struct *open_directory(connection_struct *conn, char *fname,
}
if(vfs_mkdir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
- DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
+ DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
fname, strerror(errno) ));
file_free(fsp);
return NULL;
@@ -1213,11 +1258,10 @@ dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (doub
unlock_share_entry(conn, dev, inode);
if(request_oplock_break(share_entry, dev, inode) == False)
{
- free((char *)old_shares);
-
DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
+ free((char *)old_shares);
return False;
}
lock_share_entry(conn, dev, inode);
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index cc2581375ea..7033eddc163 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -48,6 +48,20 @@ int32 get_number_of_exclusive_open_oplocks(void)
return exclusive_oplocks_open;
}
+/****************************************************************************
+ Return True if an oplock message is pending.
+****************************************************************************/
+
+BOOL oplock_message_waiting(fd_set *fds)
+{
+ if (koplocks && koplocks->msg_waiting(fds))
+ return True;
+
+ if (FD_ISSET(oplock_sock, fds))
+ return True;
+
+ return False;
+}
/****************************************************************************
Read an oplock break message from either the oplock UDP fd or the
@@ -630,7 +644,8 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
time_t start_time;
BOOL shutdown_server = False;
BOOL oplock_timeout = False;
- connection_struct *saved_conn;
+ connection_struct *saved_user_conn;
+ connection_struct *saved_fsp_conn;
int saved_vuid;
pstring saved_dir;
int timeout = (OPLOCK_BREAK_TIMEOUT * 1000);
@@ -734,9 +749,10 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
* Save the information we need to re-become the
* user, then unbecome the user whilst we're doing this.
*/
- saved_conn = fsp->conn;
+ saved_user_conn = current_user.conn;
saved_vuid = current_user.vuid;
- vfs_GetWd(saved_conn,saved_dir);
+ saved_fsp_conn = fsp->conn;
+ vfs_GetWd(saved_fsp_conn,saved_dir);
unbecome_user();
/* Save the chain fnum. */
file_chain_save();
@@ -810,7 +826,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
* Go back to being the user who requested the oplock
* break.
*/
- if(!become_user(saved_conn, saved_vuid))
+ if((saved_user_conn != NULL) && (saved_vuid != UID_FIELD_INVALID) && !become_user(saved_user_conn, saved_vuid))
{
DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
DEBUGADD( 0, ( "Shutting down server\n" ) );
@@ -818,7 +834,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
exit_server("unable to re-become user");
}
/* Including the directory. */
- vfs_ChDir(saved_conn,saved_dir);
+ vfs_ChDir(saved_fsp_conn,saved_dir);
/* Restore the chain fnum. */
file_chain_restore();
@@ -903,6 +919,19 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
+#if 1 /* JRA PARANOIA TEST.... */
+ {
+ files_struct *fsp = file_find_dit(dev, inode, &share_entry->time);
+ if (!fsp) {
+ DEBUG(0,("request_oplock_break: PANIC : breaking our own oplock requested for \
+dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x and no fsp found !\n",
+ (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
+ (int)share_entry->time.tv_usec ));
+ smb_panic("request_oplock_break: no fsp found for our own oplock\n");
+ }
+ }
+#endif /* END JRA PARANOIA TEST... */
+
/* Call oplock break direct. */
return oplock_break(dev, inode, &share_entry->time, True);
}
@@ -1128,6 +1157,9 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
num_share_modes = get_share_modes(fsp->conn, fsp->dev, fsp->inode, &share_list);
+ DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n",
+ num_share_modes ));
+
for(i = 0; i < num_share_modes; i++) {
share_mode_entry *share_entry = &share_list[i];
@@ -1140,6 +1172,9 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
* also no harm to ignore existing NO_OPLOCK states. JRA.
*/
+ DEBUG(10,("release_level_2_oplocks_on_change: share_entry[%i]->op_type == %d\n",
+ i, share_entry->op_type ));
+
if (share_entry->op_type == NO_OPLOCK)
continue;
@@ -1166,6 +1201,8 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
abort();
}
+ DEBUG(10,("release_level_2_oplocks_on_change: breaking our own oplock.\n"));
+
oplock_break_level2(new_fsp, True, token);
} else {
@@ -1175,17 +1212,19 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
* message.
*/
+ DEBUG(10,("release_level_2_oplocks_on_change: breaking remote oplock.\n"));
request_oplock_break(share_entry, fsp->dev, fsp->inode);
}
}
- free((char *)share_list);
+ if (share_list)
+ free((char *)share_list);
unlock_share_entry_fsp(fsp);
/* Paranoia check... */
if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
DEBUG(0,("release_level_2_oplocks_on_change: PANIC. File %s still has a level II oplock.\n", fsp->fsp_name));
- abort();
+ smb_panic("release_level_2_oplocks_on_change");
}
}
diff --git a/source/smbd/password.c b/source/smbd/password.c
index 5ae1c89ace7..c6be5f68eda 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -31,6 +31,12 @@ static pstring session_users="";
extern pstring global_myname;
extern fstring global_myworkgroup;
+/*
+ * track the machine trust account password timeout when
+ * in domain mode security
+ */
+BOOL global_machine_password_needs_changing = False;
+
/* Data to do lanman1/2 password challenge. */
static unsigned char saved_challenge[8];
static BOOL challenge_sent=False;
@@ -40,31 +46,10 @@ Get the next challenge value - no repeats.
********************************************************************/
void generate_next_challenge(char *challenge)
{
-#if 0
- /*
- * Leave this ifdef'd out while we test
- * the new crypto random number generator.
- * JRA.
- */
- unsigned char buf[16];
- static int counter = 0;
- struct timeval tval;
- int v1,v2;
-
- /* get a sort-of random number */
- GetTimeOfDay(&tval);
- v1 = (counter++) + sys_getpid() + tval.tv_sec;
- v2 = (counter++) * sys_getpid() + tval.tv_usec;
- SIVAL(challenge,0,v1);
- SIVAL(challenge,4,v2);
-
- /* mash it up with md4 */
- mdfour(buf, (unsigned char *)challenge, 8);
-#else
- unsigned char buf[8];
+ unsigned char buf[8];
+
+ generate_random_buffer(buf,8,False);
- generate_random_buffer(buf,8,False);
-#endif
memcpy(saved_challenge, buf, 8);
memcpy(challenge,buf,8);
challenge_sent = True;
@@ -365,15 +350,17 @@ update the encrypted smbpasswd file from the plaintext username and password
*****************************************************************************/
static BOOL update_smbpassword_file(char *user, char *password)
{
- struct smb_passwd *smbpw;
- BOOL ret;
-
+ SAM_ACCOUNT *sampass = NULL;
+ BOOL ret;
+
+ pdb_init_sam(&sampass);
+
become_root();
- smbpw = getsmbpwnam(user);
+ ret = pdb_getsampwnam(sampass, user);
unbecome_root();
- if(smbpw == NULL) {
- DEBUG(0,("getsmbpwnam returned NULL\n"));
+ if(!ret) {
+ DEBUG(0,("update_smbpassword_file: pdb_getsampwnam failed to locate %s\n", user));
return False;
}
@@ -381,15 +368,18 @@ static BOOL update_smbpassword_file(char *user, char *password)
* Remove the account disabled flag - we are updating the
* users password from a login.
*/
- smbpw->acct_ctrl &= ~ACB_DISABLED;
+ pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED);
/* Here, the flag is one, because we want to ignore the
XXXXXXX'd out password */
- ret = change_oem_password( smbpw, password, True);
+ ret = change_oem_password( sampass, password, True);
if (ret == False) {
DEBUG(3,("change_oem_password returned False\n"));
}
-
+
+ if (sampass)
+ pdb_free_sam(sampass);
+
return ret;
}
@@ -443,70 +433,68 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha
Do a specific test for an smb password being correct, given a smb_password and
the lanman and NT responses.
****************************************************************************/
-BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
+BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8],
uchar lm_pass[24], uchar nt_pass[24])
{
uchar challenge[8];
+ char* user_name;
+ uint8 *nt_pw, *lm_pw;
- if (!lm_pass || !smb_pass) return(False);
+ if (!lm_pass || !sampass)
+ return(False);
- DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",
- smb_pass->smb_name));
+ user_name = pdb_get_username(sampass);
+
+ DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",user_name));
- if(smb_pass->acct_ctrl & ACB_DISABLED) {
- DEBUG(1,("account for user %s was disabled.\n",
- smb_pass->smb_name));
+ if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
+ DEBUG(1,("smb_password_ok: account for user %s was disabled.\n", user_name));
return(False);
}
- if (chal == NULL)
- {
- DEBUG(5,("use last SMBnegprot challenge\n"));
- if (!last_challenge(challenge))
- {
- DEBUG(1,("no challenge done - password failed\n"));
+ if (chal == NULL) {
+ DEBUG(5,("smb_password_ok: use last SMBnegprot challenge\n"));
+ if (!last_challenge(challenge)) {
+ DEBUG(1,("smb_password_ok: no challenge done - password failed\n"));
return False;
}
- }
- else
- {
- DEBUG(5,("challenge received\n"));
+ } else {
+ DEBUG(5,("smb_password_ok: challenge received\n"));
memcpy(challenge, chal, 8);
}
- if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) {
+ nt_pw = pdb_get_nt_passwd(sampass);
+
+ if ((Protocol >= PROTOCOL_NT1) && (nt_pw != NULL)) {
/* We have the NT MD4 hash challenge available - see if we can
use it (ie. does it exist in the smbpasswd file).
*/
DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
- if (smb_password_check((char *)nt_pass,
- (uchar *)smb_pass->smb_nt_passwd,
- challenge)) {
- DEBUG(4,("NT MD4 password check succeeded\n"));
+ if (smb_password_check((char *)nt_pass, (uchar *)nt_pw, challenge)) {
+ DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n"));
return(True);
}
- DEBUG(4,("NT MD4 password check failed\n"));
+ DEBUG(4,("smb_password_ok: NT MD4 password check failed\n"));
}
- /* Try against the lanman password. smb_pass->smb_passwd == NULL means
- no password, allow access. */
+ /* Try against the lanman password. pdb_get_lanman_passwd(sampass) == NULL
+ means no password, allow access. */
- if((smb_pass->smb_passwd == NULL) &&
- (smb_pass->acct_ctrl & ACB_PWNOTREQ)) {
- DEBUG(4,("smb_password_ok: no password required for user %s\n",
- smb_pass->smb_name));
+ lm_pw = pdb_get_lanman_passwd(sampass);
+
+ if((lm_pw == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ))
+ {
+ DEBUG(4,("smb_password_ok: no password required for user %s\n",user_name));
return True;
}
- if(lp_lanman_auth() && (smb_pass->smb_passwd != NULL)) {
+ if(lp_lanman_auth() && (lm_pw != NULL)) {
DEBUG(4,("smb_password_ok: Checking LM password\n"));
-
- if (smb_password_check((char *)lm_pass,
- (uchar *)smb_pass->smb_passwd, challenge)) {
+ if(smb_password_check((char *)lm_pass,(uchar *)lm_pw, challenge)) {
DEBUG(4,("smb_password_ok: LM password check succeeded\n"));
return(True);
}
- DEBUG(4,("LM password check failed\n"));
+ DEBUG(4,("smb_password_ok: LM password check failed\n"));
}
return False;
@@ -519,18 +507,19 @@ SMB hash
return True if the password is correct, False otherwise
****************************************************************************/
-BOOL pass_check_smb(char *user, char *domain,
- uchar *chal, uchar *lm_pwd, uchar *nt_pwd,
- struct passwd *pwd)
+BOOL pass_check_smb(char *user, char *domain, uchar *chal,
+ uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd)
{
- struct passwd *pass;
- struct smb_passwd *smb_pass;
+ SAM_ACCOUNT *sampass = NULL;
if (!lm_pwd || !nt_pwd)
{
return(False);
}
+#if 0 /* JERRY */
+ /* FIXME! this code looks to be unnecessary now that the passdb
+ validates that the username exists and has a valid uid */
if (pwd != NULL && user == NULL)
{
pass = (struct passwd *) pwd;
@@ -538,6 +527,8 @@ BOOL pass_check_smb(char *user, char *domain,
}
else
{
+ /* I don't get this call here. I think it should be moved.
+ Need to check on it. --jerry */
pass = smb_getpwnam(user,True);
}
@@ -546,44 +537,44 @@ BOOL pass_check_smb(char *user, char *domain,
DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",user));
return(False);
}
+#endif
- smb_pass = getsmbpwnam(user);
-
- if (smb_pass == NULL)
+ /* get the account information */
+ pdb_init_sam(&sampass);
+ if (!pdb_getsampwnam(sampass, user))
{
- DEBUG(1,("Couldn't find user '%s' in smb_passwd file.\n", user));
+ DEBUG(1,("Couldn't find user '%s' in passdb.\n", user));
return(False);
}
/* Quit if the account was disabled. */
- if(smb_pass->acct_ctrl & ACB_DISABLED) {
+ if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
DEBUG(1,("Account for user '%s' was disabled.\n", user));
return(False);
}
- /* Ensure the uid's match */
- if (smb_pass->smb_userid != pass->pw_uid)
- {
- DEBUG(0,("Error : UNIX and SMB uids in password files do not match for user '%s'!\n", user));
- return(False);
- }
- if (smb_pass->acct_ctrl & ACB_PWNOTREQ) {
- if (lp_null_passwords()) {
- DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", smb_pass->smb_name));
+ if (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)
+ {
+ if (lp_null_passwords())
+ {
+ DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", user));
return(True);
- } else {
- DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", smb_pass->smb_name));
+ }
+ else
+ {
+ DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", user));
return(False);
}
}
- if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd))
+ if (smb_password_ok(sampass, chal, lm_pwd, nt_pwd))
{
return(True);
}
DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user));
+
return False;
}
@@ -621,7 +612,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
*/
if (ret)
- return (smb_pam_accountcheck(user) == NT_STATUS_NOPROBLEMO);
+ return (smb_pam_accountcheck(user) == NT_STATUS_OK);
return ret;
}
@@ -1087,10 +1078,10 @@ struct cli_state *server_cryptkey(void)
if (!cli_initialise(cli))
return NULL;
- pserver = strdup(lp_passwordserver());
+ pserver = strdup(lp_passwordserver());
p = pserver;
- while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
+ while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
standard_sub_basic(desthost);
strupper(desthost);
@@ -1564,6 +1555,10 @@ BOOL domain_client_validate( char *user, char *domain,
return False;
}
+ /* Test if machine password is expired and need to be changed */
+ if (time(NULL) > last_change_time + lp_machine_password_timeout())
+ global_machine_password_needs_changing = True;
+
/*
* At this point, smb_apasswd points to the lanman response to
* the challenge in local_challenge, and smb_ntpasswd points to
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 4832184df71..5c22b89a8d8 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -419,7 +419,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if(security_info_sent == 0) {
DEBUG(0,("unpack_nt_owners: no security info sent !\n"));
- return False;
+ return True;
}
/*
@@ -438,8 +438,10 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if (security_info_sent & OWNER_SECURITY_INFORMATION) {
sid_copy(&owner_sid, psd->owner_sid);
- if (!sid_to_uid( &owner_sid, puser, &sid_type))
+ if (!sid_to_uid( &owner_sid, puser, &sid_type)) {
DEBUG(3,("unpack_nt_owners: unable to validate owner sid.\n"));
+ return False;
+ }
}
/*
@@ -449,8 +451,10 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if (security_info_sent & GROUP_SECURITY_INFORMATION) {
sid_copy(&grp_sid, psd->grp_sid);
- if (!sid_to_gid( &grp_sid, pgrp, &sid_type))
+ if (!sid_to_gid( &grp_sid, pgrp, &sid_type)) {
DEBUG(3,("unpack_nt_owners: unable to validate group sid.\n"));
+ return False;
+ }
}
DEBUG(5,("unpack_nt_owners: owner_sids validated.\n"));
@@ -711,6 +715,17 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
SEC_ACE *psa = &dacl->ace[i];
/*
+ * Ignore non-mappable SIDs (NT Authority, BUILTIN etc).
+ */
+
+ if (non_mappable_sid(&psa->sid)) {
+ fstring str;
+ DEBUG(10,("create_canon_ace_lists: ignoring non-mappable SID %s\n",
+ sid_to_string(str, &psa->sid) ));
+ continue;
+ }
+
+ /*
* Create a cannon_ace entry representing this NT DACL ACE.
*/
@@ -1457,7 +1472,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
uid_to_sid( &sid, *puid);
unix_ug.uid = *puid;
owner_type = UID_ACE;
- sys_acl_free_qualifier((void *)puid);
+ sys_acl_free_qualifier((void *)puid,tagtype);
break;
}
case SMB_ACL_GROUP_OBJ:
@@ -1476,7 +1491,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
gid_to_sid( &sid, *pgid);
unix_ug.gid = *pgid;
owner_type = GID_ACE;
- sys_acl_free_qualifier((void *)pgid);
+ sys_acl_free_qualifier((void *)pgid,tagtype);
break;
}
case SMB_ACL_MASK:
@@ -1705,14 +1720,14 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
if(default_ace || fsp->is_directory || fsp->fd == -1) {
if (sys_acl_set_file(dos_to_unix(fsp->fsp_name,False), the_acl_type, the_acl) == -1) {
- DEBUG(0,("set_canon_ace_list: sys_acl_set_file type %s failed for file %s (%s).\n",
+ DEBUG(2,("set_canon_ace_list: sys_acl_set_file type %s failed for file %s (%s).\n",
the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
fsp->fsp_name, strerror(errno) ));
goto done;
}
} else {
if (sys_acl_set_fd(fsp->fd, the_acl) == -1) {
- DEBUG(0,("set_canon_ace_list: sys_acl_set_file failed for file %s (%s).\n",
+ DEBUG(2,("set_canon_ace_list: sys_acl_set_file failed for file %s (%s).\n",
fsp->fsp_name, strerror(errno) ));
goto done;
}
@@ -2213,11 +2228,11 @@ static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode)
}
/*
- * If this is a simple 3 element ACL then it's a standard
+ * If this is a simple 3 element ACL or no elements then it's a standard
* UNIX permission set. Just use chmod...
*/
- if (num_entries == 3)
+ if ((num_entries == 3) || (num_entries == 0))
return -1;
return 0;
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 168cfd440e5..5c329a7c8ac 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -207,6 +207,11 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
signals */
if (selrtn == -1 && errno == EINTR) {
async_processing(&fds, buffer, buffer_len);
+ /*
+ * After async processing we must go and do the select again, as
+ * the state of the flag in fds for the server file descriptor is
+ * indeterminate - we may have done I/O on it in the oplock processing. JRA.
+ */
goto again;
}
@@ -223,9 +228,21 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
return False;
}
- if (!FD_ISSET(smbd_server_fd(),&fds) || selrtn > 1) {
+ /*
+ * Ensure we process oplock break messages by preference.
+ * This is IMPORTANT ! Otherwise we can starve other processes
+ * sending us an oplock break message. JRA.
+ */
+
+ if (oplock_message_waiting(&fds)) {
+ DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
async_processing(&fds, buffer, buffer_len);
- if (!FD_ISSET(smbd_server_fd(),&fds)) goto again;
+ /*
+ * After async processing we must go and do the select again, as
+ * the state of the flag in fds for the server file descriptor is
+ * indeterminate - we may have done I/O on it in the oplock processing. JRA.
+ */
+ goto again;
}
return receive_smb(smbd_server_fd(), buffer, 0);
@@ -349,12 +366,12 @@ struct smb_message_struct
/* 0x18 */ { NULL, NULL, 0 },
/* 0x19 */ { NULL, NULL, 0 },
/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
-/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
-/* 0x1c */ { "SMBreadBs",NULL,AS_USER},
+/* 0x1b */ { "SMBreadBmpx",NULL,0},
+/* 0x1c */ { "SMBreadBs",NULL,0},
/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
-/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
-/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
-/* 0x20 */ { "SMBwritec",NULL,AS_USER},
+/* 0x1e */ { "SMBwriteBmpx",NULL,0},
+/* 0x1f */ { "SMBwriteBs",NULL,0},
+/* 0x20 */ { "SMBwritec",NULL,0},
/* 0x21 */ { NULL, NULL, 0 },
/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
@@ -790,6 +807,12 @@ static BOOL smbd_process_limit(void)
total_smbds = 1; /* In case we need to create the entry. */
+ if (!conn_tdb_ctx()) {
+ DEBUG(0,("smbd_process_limit: max smbd processes parameter set with status parameter not \
+set. Ignoring max smbd restriction.\n"));
+ return False;
+ }
+
if (tdb_change_int_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
return True;
@@ -1103,7 +1126,10 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
/* also send a keepalive to the password server if its still
connected */
if (cli && cli->initialised)
- send_keepalive(cli->fd);
+ if (!send_keepalive(cli->fd)) {
+ DEBUG( 2, ( "password server keepalive failed.\n"));
+ cli_shutdown(cli);
+ }
last_keepalive_sent_time = t;
}
@@ -1166,9 +1192,10 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup ));
/*
* Now we are root, check if the log files need pruning.
+ * Force a log file check.
*/
- if(need_to_check_log_size())
- check_log_size();
+ force_check_log_size();
+ check_log_size();
/*
* Modify the select timeout depending upon
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index caf3997ba80..46693a6fe1e 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -45,12 +45,72 @@ BOOL disk_quotas_vxfs(const pstring name, char *path, SMB_BIG_UINT *bsize, SMB_B
#include <sys/types.h>
#include <asm/types.h>
-#include <sys/quota.h>
+
+/*
+ * This shouldn't be neccessary - it should be /usr/include/sys/quota.h
+ * Unfortunately, RH7.1 ships with a different quota system using struct mem_dqblk
+ * rather than the struct dqblk defined in /usr/include/sys/quota.h.
+ * This means we must include linux/quota.h to have a hope of working on
+ * RH7.1 systems. And it also means this breaks if the kernel is upgraded
+ * to a Linus 2.4.x (where x > the minor number shipped with RH7.1) until
+ * Linus synchronises with the AC patches. Sometimes I *hate* Linux :-). JRA.
+ */
+
+#include <linux/quota.h>
#include <mntent.h>
#include <linux/unistd.h>
-_syscall4(int, quotactl, int, cmd, const char *, special, int, id, caddr_t, addr);
+
+#define LINUX_QUOTAS_2
+
+typedef struct _LINUX_SMB_DISK_QUOTA {
+ SMB_BIG_UINT bsize;
+ SMB_BIG_UINT hardlimit; /* In bsize units. */
+ SMB_BIG_UINT softlimit; /* In bsize units. */
+ SMB_BIG_UINT curblocks; /* In bsize units. */
+ SMB_BIG_UINT ihardlimit; /* inode hard limit. */
+ SMB_BIG_UINT isoftlimit; /* inode soft limit. */
+ SMB_BIG_UINT curinodes; /* Current used inodes. */
+} LINUX_SMB_DISK_QUOTA;
+
+/****************************************************************************
+ Abstract out the old and new Linux quota get calls.
+****************************************************************************/
+
+static int get_smb_linux_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
+{
+ int ret;
+#ifdef LINUX_QUOTAS_1
+ struct dqblk D;
+ ZERO_STRUCT(D);
+ dp->bsize = (SMB_BIG_UINT)1024;
+#else /* LINUX_QUOTAS_2 */
+ struct mem_dqblk D;
+ ZERO_STRUCT(D);
+#ifndef QUOTABLOCK_SIZE
+#define QUOTABLOCK_SIZE 1024
+#endif
+ dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
+#endif
+
+ if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
+ return -1;
+
+ dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
+ dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
+ dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
+ dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
+ dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
+
+#ifdef LINUX_QUOTAS_1
+ dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
+#else /* LINUX_QUOTAS_2 */
+ dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace)/ dp->bsize;
+#endif
+
+ return 0;
+}
/****************************************************************************
try to get the disk space from disk quotas (LINUX version)
@@ -58,81 +118,78 @@ try to get the disk space from disk quotas (LINUX version)
BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
- int r;
- struct dqblk D;
- SMB_STRUCT_STAT S;
- FILE *fp;
- struct mntent *mnt;
- SMB_DEV_T devno;
- int found;
- uid_t euser_id;
+ int r;
+ SMB_STRUCT_STAT S;
+ FILE *fp;
+ LINUX_SMB_DISK_QUOTA D;
+ struct mntent *mnt;
+ SMB_DEV_T devno;
+ int found;
+ uid_t euser_id;
- euser_id = geteuid();
+ euser_id = geteuid();
- /* find the block device file */
+ /* find the block device file */
- if ( sys_stat(path, &S) == -1 ) {
- return(False) ;
- }
+ if ( sys_stat(path, &S) == -1 )
+ return(False) ;
- devno = S.st_dev ;
+ devno = S.st_dev ;
- fp = setmntent(MOUNTED,"r");
- found = False ;
+ fp = setmntent(MOUNTED,"r");
+ found = False ;
- while ((mnt = getmntent(fp))) {
- if ( sys_stat(mnt->mnt_dir,&S) == -1 )
- continue ;
- if (S.st_dev == devno) {
- found = True ;
- break ;
- }
- }
- endmntent(fp) ;
+ while ((mnt = getmntent(fp))) {
+ if ( sys_stat(mnt->mnt_dir,&S) == -1 )
+ continue ;
+
+ if (S.st_dev == devno) {
+ found = True ;
+ break;
+ }
+ }
+
+ endmntent(fp) ;
- if (!found) {
- return(False);
- }
+ if (!found)
+ return(False);
- save_re_uid();
- set_effective_uid(0);
- r=quotactl(QCMD(Q_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D);
- restore_re_uid();
+ save_re_uid();
+ set_effective_uid(0);
+ r=get_smb_linux_quota(mnt->mnt_fsname, euser_id, &D);
+ restore_re_uid();
- /* Use softlimit to determine disk space, except when it has been exceeded */
- *bsize = 1024;
- if (r)
- {
- if (errno == EDQUOT)
- {
- *dfree =0;
- *dsize =D.dqb_curblocks;
- return (True);
- }
- else return(False);
- }
- /* Use softlimit to determine disk space, except when it has been exceeded */
- if (
- (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) ||
- (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) ||
- (D.dqb_isoftlimit && D.dqb_curinodes>=D.dqb_isoftlimit) ||
- (D.dqb_ihardlimit && D.dqb_curinodes>=D.dqb_ihardlimit)
- )
- {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- }
- else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0)
- {
- return(False);
- }
- else {
- if (D.dqb_bsoftlimit == 0)
- D.dqb_bsoftlimit = D.dqb_bhardlimit;
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
- *dsize = D.dqb_bsoftlimit;
- }
- return (True);
+ /* Use softlimit to determine disk space, except when it has been exceeded */
+ *bsize = D.bsize;
+ if (r == -1) {
+ if (errno == EDQUOT) {
+ *dfree =0;
+ *dsize =D.curblocks;
+ return (True);
+ } else {
+ return(False);
+ }
+ }
+
+ /* Use softlimit to determine disk space, except when it has been exceeded */
+ if (
+ (D.softlimit && D.curblocks >= D.softlimit) ||
+ (D.hardlimit && D.curblocks >= D.hardlimit) ||
+ (D.isoftlimit && D.curinodes >= D.isoftlimit) ||
+ (D.ihardlimit && D.curinodes>=D.ihardlimit)
+ ) {
+ *dfree = 0;
+ *dsize = D.curblocks;
+ } else if (D.softlimit==0 && D.hardlimit==0) {
+ return(False);
+ } else {
+ if (D.softlimit == 0)
+ D.softlimit = D.hardlimit;
+ *dfree = D.softlimit - D.curblocks;
+ *dsize = D.softlimit;
+ }
+
+ return (True);
}
#elif defined(CRAY)
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 4eaffcede63..ffcbe6d8986 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -312,13 +312,22 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
*password = 0;
passlen = strlen(password);
}
-
- p = strchr(path+2,'\\');
- if (!p) {
- END_PROFILE(SMBtconX);
- return(ERROR(ERRDOS,ERRnosuchshare));
+
+ /*
+ * the service name can be either: \\server\share
+ * or share directly like on the DELL PowerVault 705
+ */
+ if (*path=='\\') {
+ p = strchr(path+2,'\\');
+ if (!p) {
+ END_PROFILE(SMBtconX);
+ return(ERROR(ERRDOS,ERRnosuchshare));
+ }
+ fstrcpy(service,p+1);
}
- fstrcpy(service,p+1);
+ else
+ fstrcpy(service,path);
+
p = strchr(service,'%');
if (p) {
*p++ = 0;
@@ -456,61 +465,59 @@ int reply_ioctl(connection_struct *conn,
}
/****************************************************************************
- always return an error: it's just a matter of which one...
+ Always return an error: it's just a matter of which one...
+ FIXME: memory leak - no call to pdb_free_sam() --jerry
****************************************************************************/
+
static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user,
char *smb_passwd, int smb_passlen,
char *smb_nt_passwd, int smb_nt_passlen)
{
- struct smb_passwd *smb_trust_acct = NULL; /* check if trust account exists */
- if (lp_security() == SEC_USER) {
- smb_trust_acct = getsmbpwnam(user);
- } else {
- DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_LOGON_FAILURE));
- }
+ SAM_ACCOUNT *sam_trust_acct = NULL; /* check if trust account exists */
+ uint16 acct_ctrl;
- if (smb_trust_acct == NULL) {
- /* lkclXXXX: workstation entry doesn't exist */
- DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_NO_SUCH_USER));
- } else {
- if ((smb_passlen != 24) || (smb_nt_passlen != 24)) {
- DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_LOGON_FAILURE));
- }
+ if (lp_security() == SEC_USER) {
+ pdb_init_sam(&sam_trust_acct);
+ pdb_getsampwnam(sam_trust_acct, user);
+ } else {
+ DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
+ }
- if (!smb_password_ok(smb_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd)) {
- DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_LOGON_FAILURE));
- }
+ if (sam_trust_acct == NULL) {
+ /* lkclXXXX: workstation entry doesn't exist */
+ DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
+ return(ERROR_BOTH(NT_STATUS_NO_SUCH_USER,ERRDOS,1317));
+ } else {
+ if ((smb_passlen != 24) || (smb_nt_passlen != 24)) {
+ DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
+ }
- if (smb_trust_acct->acct_ctrl & ACB_DOMTRUST) {
- DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT));
- }
+ if (!smb_password_ok(sam_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd)) {
+ DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw));
+ }
- if (smb_trust_acct->acct_ctrl & ACB_SVRTRUST) {
- DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT));
- }
+ acct_ctrl = pdb_get_acct_ctrl(sam_trust_acct);
+ if (acct_ctrl & ACB_DOMTRUST) {
+ DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT,ERRDOS,1807));
+ }
- if (smb_trust_acct->acct_ctrl & ACB_WSTRUST) {
- DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT));
- }
- }
+ if (acct_ctrl & ACB_SVRTRUST) {
+ DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT,ERRDOS,1809));
+ }
- /* don't know what to do: indicate logon failure */
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, NT_STATUS_LOGON_FAILURE));
+ if (acct_ctrl & ACB_WSTRUST) {
+ DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
+ return(ERROR_BOTH(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT,ERRDOS,1808));
+ }
+ }
+
+ /* don't know what to do: indicate logon failure */
+ return(ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRDOS,1326));
}
/****************************************************************************
@@ -684,24 +691,7 @@ static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user
}
/****************************************************************************
- Return a bad password error configured for the correct client type.
-****************************************************************************/
-
-static int bad_password_error(char *inbuf,char *outbuf)
-{
- enum remote_arch_types ra_type = get_remote_arch();
-
- if(((ra_type == RA_WINNT) || (ra_type == RA_WIN2K)) &&
- (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32 ))) {
- SSVAL(outbuf,smb_flg2,FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0,NT_STATUS_LOGON_FAILURE));
- }
-
- return(ERROR(ERRSRV,ERRbadpw));
-}
-
-/****************************************************************************
-reply to a session setup command
+ Reply to a session setup command.
****************************************************************************/
int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
@@ -870,7 +860,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
alpha_strcpy(user, user, ". _-$", sizeof(user));
alpha_strcpy(domain, domain, ". _-", sizeof(domain));
if (strstr(user, "..") || strstr(domain,"..")) {
- return bad_password_error(inbuf, outbuf);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
}
DEBUG(3,("sesssetupX:name=[%s]\n",user));
@@ -1004,7 +994,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
{
DEBUG(1,("Rejecting user '%s': authentication failed\n", user));
END_PROFILE(SMBsesssetupX);
- return bad_password_error(inbuf,outbuf);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
}
if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
@@ -1013,7 +1003,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
{
DEBUG(1,("Rejecting user '%s': bad password\n", user));
END_PROFILE(SMBsesssetupX);
- return bad_password_error(inbuf,outbuf);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
}
}
@@ -1066,7 +1056,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if (!pw) {
DEBUG(1,("Username %s is invalid on this system\n",user));
END_PROFILE(SMBsesssetupX);
- return bad_password_error(inbuf,outbuf);
+ return ERROR_BOTH(NT_STATUS_LOGON_FAILURE,ERRSRV,ERRbadpw);
}
gid = pw->pw_gid;
uid = pw->pw_uid;
@@ -1180,8 +1170,6 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- /* if((SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) && dfs_redirect(fname,conn)) return(dfs_path_error(inbuf,outbuf));
- */
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
if (! (*fname))
@@ -1362,9 +1350,9 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
path = smb_buf(inbuf) + 1;
status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
-
+ RESOLVE_DFSPATH(path, conn, inbuf, outbuf);
/* dirtype &= ~aDIR; */
-
+
if (status_len == 0)
{
SMB_STRUCT_STAT sbuf;
@@ -1481,11 +1469,11 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
SearchEmpty:
- if (numentries == 0 || !ok)
+ if ( (numentries == 0) || !ok)
{
- CVAL(outbuf,smb_rcls) = ERRDOS;
- SSVAL(outbuf,smb_err,ERRnofiles);
- dptr_close(&dptr_num);
+ CVAL(outbuf,smb_rcls) = ERRDOS;
+ SSVAL(outbuf,smb_err,ERRnofiles);
+ dptr_close(&dptr_num);
}
/* If we were called as SMBffirst with smb_search_id == NULL
@@ -1513,7 +1501,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
uint16 flg2 = SVAL(outbuf,smb_flg2);
SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
}
-
+
outsize += DIR_STRUCT_SIZE*numentries;
smb_setlen(outbuf,outsize - 4);
@@ -1869,72 +1857,84 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
****************************************************************************/
int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- pstring fname;
- int outsize = 0;
- int createmode;
- mode_t unixmode = 0600;
- BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
- int tmpfd;
- SMB_STRUCT_STAT sbuf;
+ pstring fname;
+ int outsize = 0;
+ int createmode;
+ mode_t unixmode;
+ BOOL bad_path = False;
+ files_struct *fsp;
+ int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ int tmpfd;
+ SMB_STRUCT_STAT sbuf;
+ char *p, *s;
- START_PROFILE(SMBctemp);
+ START_PROFILE(SMBctemp);
- createmode = SVAL(inbuf,smb_vwv0);
- pstrcpy(fname,smb_buf(inbuf)+1);
- pstrcat(fname,"/TMXXXXXX");
+ createmode = SVAL(inbuf,smb_vwv0);
+ pstrcpy(fname,smb_buf(inbuf)+1);
+ pstrcat(fname,"\\TMXXXXXX");
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- unix_convert(fname,conn,0,&bad_path,&sbuf);
-
- tmpfd = smb_mkstemp(fname);
- if (tmpfd == -1) {
- END_PROFILE(SMBctemp);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
- vfs_stat(conn,fname,&sbuf);
+ unixmode = unix_mode(conn,createmode,fname);
- /* Open file in dos compatibility share mode. */
- /* We should fail if file does not exist. */
- fsp = open_file_shared(conn,fname,&sbuf,
+ tmpfd = smb_mkstemp(fname);
+ if (tmpfd == -1) {
+ END_PROFILE(SMBctemp);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ vfs_stat(conn,fname,&sbuf);
+
+ /* Open file in dos compatibility share mode. */
+ /* We should fail if file does not exist. */
+ fsp = open_file_shared(conn,fname,&sbuf,
SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
FILE_EXISTS_OPEN|FILE_FAIL_IF_NOT_EXIST,
unixmode, oplock_request, NULL, NULL);
- /* close fd from smb_mkstemp() */
- close(tmpfd);
+ /* close fd from smb_mkstemp() */
+ close(tmpfd);
- if (!fsp)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- END_PROFILE(SMBctemp);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ if (!fsp) {
+ if((errno == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ END_PROFILE(SMBctemp);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- outsize = set_message(outbuf,1,2 + strlen(fname),True);
- SSVAL(outbuf,smb_vwv0,fsp->fnum);
- CVAL(smb_buf(outbuf),0) = 4;
- pstrcpy(smb_buf(outbuf) + 1,fname);
+ /* the returned filename is relative to the directory */
+ s = strrchr(fname, '/');
+ if (!s)
+ s = fname;
+ else
+ s++;
- if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- }
+ outsize = set_message(outbuf,1,4+ strlen(fname),True);
+ SSVAL(outbuf,smb_vwv0,fsp->fnum);
+
+ p = smb_buf(outbuf);
+ SSVALS(p, 0, -1); /* what is this? not in spec */
+ SSVAL(p, 2, strlen(s));
+ p += 4;
+ pstrcpy(p,s);
+
+ if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ }
- if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- DEBUG( 2, ( "created temp file %s\n", fname ) );
- DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
- fname, fsp->fd, createmode, (int)unixmode ) );
+ DEBUG( 2, ( "created temp file %s\n", fname ) );
+ DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
+ fname, fsp->fd, createmode, (int)unixmode ) );
- END_PROFILE(SMBctemp);
- return(outsize);
+ END_PROFILE(SMBctemp);
+ return(outsize);
}
@@ -2101,154 +2101,145 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return(outsize);
}
+/****************************************************************************
+ Fail for readbraw.
+****************************************************************************/
+
+void fail_readraw(void)
+{
+ pstring errstr;
+ slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)\n",
+ strerror(errno) );
+ exit_server(errstr);
+}
/****************************************************************************
- reply to a readbraw (core+ protocol)
+ Reply to a readbraw (core+ protocol).
****************************************************************************/
int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
{
- size_t maxcount,mincount;
- size_t nread = 0;
- SMB_OFF_T startpos;
- char *header = outbuf;
- ssize_t ret=0;
- files_struct *fsp;
- START_PROFILE(SMBreadbraw);
+ size_t maxcount,mincount;
+ size_t nread = 0;
+ SMB_OFF_T startpos;
+ char *header = outbuf;
+ ssize_t ret=0;
+ files_struct *fsp;
+ START_PROFILE(SMBreadbraw);
- /*
- * Special check if an oplock break has been issued
- * and the readraw request croses on the wire, we must
- * return a zero length response here.
- */
+ /*
+ * Special check if an oplock break has been issued
+ * and the readraw request croses on the wire, we must
+ * return a zero length response here.
+ */
- if(global_oplock_break)
- {
- _smb_setlen(header,0);
- transfer_file(0,smbd_server_fd(),(SMB_OFF_T)0,header,4,0);
- DEBUG(5,("readbraw - oplock break finished\n"));
- END_PROFILE(SMBreadbraw);
- return -1;
- }
+ if(global_oplock_break) {
+ _smb_setlen(header,0);
+ if (write_data(smbd_server_fd(),header,4) != 4)
+ fail_readraw();
+ DEBUG(5,("readbraw - oplock break finished\n"));
+ END_PROFILE(SMBreadbraw);
+ return -1;
+ }
- fsp = file_fsp(inbuf,smb_vwv0);
-
- if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
- /*
- * fsp could be NULL here so use the value from the packet. JRA.
- */
- DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
- _smb_setlen(header,0);
- transfer_file(0,smbd_server_fd(),(SMB_OFF_T)0,header,4,0);
- END_PROFILE(SMBreadbraw);
- return(-1);
- }
+ fsp = file_fsp(inbuf,smb_vwv0);
- CHECK_FSP(fsp,conn);
+ if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
+ /*
+ * fsp could be NULL here so use the value from the packet. JRA.
+ */
+ DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
+ _smb_setlen(header,0);
+ if (write_data(smbd_server_fd(),header,4) != 4)
+ fail_readraw();
+ END_PROFILE(SMBreadbraw);
+ return(-1);
+ }
- flush_write_cache(fsp, READRAW_FLUSH);
+ CHECK_FSP(fsp,conn);
- startpos = IVAL(inbuf,smb_vwv1);
- if(CVAL(inbuf,smb_wct) == 10) {
- /*
- * This is a large offset (64 bit) read.
- */
+ flush_write_cache(fsp, READRAW_FLUSH);
+
+ startpos = IVAL(inbuf,smb_vwv1);
+ if(CVAL(inbuf,smb_wct) == 10) {
+ /*
+ * This is a large offset (64 bit) read.
+ */
#ifdef LARGE_SMB_OFF_T
- startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
#else /* !LARGE_SMB_OFF_T */
- /*
- * Ensure we haven't been sent a >32 bit offset.
- */
+ /*
+ * Ensure we haven't been sent a >32 bit offset.
+ */
- if(IVAL(inbuf,smb_vwv8) != 0) {
- DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
+ if(IVAL(inbuf,smb_vwv8) != 0) {
+ DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
- _smb_setlen(header,0);
- transfer_file(0,smbd_server_fd(),(SMB_OFF_T)0,header,4,0);
- END_PROFILE(SMBreadbraw);
- return(-1);
- }
+ _smb_setlen(header,0);
+ if (write_data(smbd_server_fd(),header,4) != 4)
+ fail_readraw();
+ END_PROFILE(SMBreadbraw);
+ return(-1);
+ }
#endif /* LARGE_SMB_OFF_T */
- if(startpos < 0) {
- DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n",
- (double)startpos ));
- _smb_setlen(header,0);
- transfer_file(0,smbd_server_fd(),(SMB_OFF_T)0,header,4,0);
- END_PROFILE(SMBreadbraw);
- return(-1);
- }
- }
- maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
- mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
+ if(startpos < 0) {
+ DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
+ _smb_setlen(header,0);
+ if (write_data(smbd_server_fd(),header,4) != 4)
+ fail_readraw();
+ END_PROFILE(SMBreadbraw);
+ return(-1);
+ }
+ }
+ maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
+ mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
- /* ensure we don't overrun the packet size */
- maxcount = MIN(65535,maxcount);
- maxcount = MAX(mincount,maxcount);
+ /* ensure we don't overrun the packet size */
+ maxcount = MIN(65535,maxcount);
+ maxcount = MAX(mincount,maxcount);
- if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False))
- {
- SMB_OFF_T size = fsp->size;
- SMB_OFF_T sizeneeded = startpos + maxcount;
-
- if (size < sizeneeded)
- {
- SMB_STRUCT_STAT st;
- if (vfs_fstat(fsp,fsp->fd,&st) == 0)
- size = st.st_size;
- if (!fsp->can_write)
- fsp->size = size;
- }
+ if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ SMB_OFF_T size = fsp->size;
+ SMB_OFF_T sizeneeded = startpos + maxcount;
+
+ if (size < sizeneeded) {
+ SMB_STRUCT_STAT st;
+ if (vfs_fstat(fsp,fsp->fd,&st) == 0)
+ size = st.st_size;
+ if (!fsp->can_write)
+ fsp->size = size;
+ }
- nread = MIN(maxcount,(size - startpos));
- }
+ if (startpos >= size)
+ nread = 0;
+ else
+ nread = MIN(maxcount,(size - startpos));
+ }
- if (nread < mincount)
- nread = 0;
+ if (nread < mincount)
+ nread = 0;
- DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
- fsp->fnum, (double)startpos,
- (int)maxcount, (int)mincount, (int)nread ) );
+ DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
+ (int)maxcount, (int)mincount, (int)nread ) );
-#if UNSAFE_READRAW
- {
- BOOL seek_fail = False;
- int predict=0;
- _smb_setlen(header,nread);
-
- if ((nread-predict) > 0) {
- if(conn->vfs_ops.seek(fsp,fsp->fd,startpos + predict) == -1) {
- DEBUG(0,("reply_readbraw: ERROR: seek_file failed.\n"));
- ret = 0;
- seek_fail = True;
- }
- }
-
- if(!seek_fail)
- ret = (ssize_t)vfs_transfer_file(-1, fsp, fsp->fd, Client, NULL,
- (SMB_OFF_T)(nread-predict),header,4+predict,
- startpos+predict);
- }
-
- if (ret != nread+4)
- DEBUG(0,("ERROR: file read failure on %s at %d for %d bytes (%d)\n",
- fsp->fsp_name,startpos,nread,ret));
-
-#else /* UNSAFE_READRAW */
- ret = read_file(fsp,header+4,startpos,nread);
- if (ret < mincount) ret = 0;
+ if (nread > 0) {
+ ret = read_file(fsp,header+4,startpos,nread);
+ if (ret < mincount)
+ ret = 0;
+ }
- _smb_setlen(header,ret);
- transfer_file(0,smbd_server_fd(),0,header,4+ret,0);
-#endif /* UNSAFE_READRAW */
+ _smb_setlen(header,ret);
+ if (write_data(smbd_server_fd(),header,4+ret) != 4+ret)
+ fail_readraw();
- DEBUG(5,("readbraw finished\n"));
- END_PROFILE(SMBreadbraw);
- return -1;
+ DEBUG(5,("readbraw finished\n"));
+ END_PROFILE(SMBreadbraw);
+ return -1;
}
@@ -2269,7 +2260,6 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
CHECK_FSP(fsp,conn);
CHECK_READ(fsp);
- CHECK_ERROR(fsp);
release_level_2_oplocks_on_change(fsp);
@@ -2338,7 +2328,6 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
CHECK_FSP(fsp,conn);
CHECK_READ(fsp);
- CHECK_ERROR(fsp);
numtoread = SVAL(inbuf,smb_vwv1);
startpos = IVAL(inbuf,smb_vwv2);
@@ -2395,7 +2384,6 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
CHECK_FSP(fsp,conn);
CHECK_READ(fsp);
- CHECK_ERROR(fsp);
set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
@@ -2452,115 +2440,126 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
- ssize_t nwritten=0;
- ssize_t total_written=0;
- size_t numtowrite=0;
- size_t tcount;
- SMB_OFF_T startpos;
- char *data=NULL;
- BOOL write_through;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- int outsize = 0;
- START_PROFILE(SMBwritebraw);
+ ssize_t nwritten=0;
+ ssize_t total_written=0;
+ size_t numtowrite=0;
+ size_t tcount;
+ SMB_OFF_T startpos;
+ char *data=NULL;
+ BOOL write_through;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ int outsize = 0;
+ START_PROFILE(SMBwritebraw);
- CHECK_FSP(fsp,conn);
- CHECK_WRITE(fsp);
- CHECK_ERROR(fsp);
+ CHECK_FSP(fsp,conn);
+ CHECK_WRITE(fsp);
- tcount = IVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv3);
- write_through = BITSETW(inbuf+smb_vwv7,0);
-
- /* We have to deal with slightly different formats depending
- on whether we are using the core+ or lanman1.0 protocol */
- if(Protocol <= PROTOCOL_COREPLUS) {
- numtowrite = SVAL(smb_buf(inbuf),-2);
- data = smb_buf(inbuf);
- } else {
- numtowrite = SVAL(inbuf,smb_vwv10);
- data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
- }
+ tcount = IVAL(inbuf,smb_vwv1);
+ startpos = IVAL(inbuf,smb_vwv3);
+ write_through = BITSETW(inbuf+smb_vwv7,0);
- /* force the error type */
- CVAL(inbuf,smb_com) = SMBwritec;
- CVAL(outbuf,smb_com) = SMBwritec;
+ /* We have to deal with slightly different formats depending
+ on whether we are using the core+ or lanman1.0 protocol */
- if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
- END_PROFILE(SMBwritebraw);
- return(ERROR(ERRDOS,ERRlock));
- }
+ if(Protocol <= PROTOCOL_COREPLUS) {
+ numtowrite = SVAL(smb_buf(inbuf),-2);
+ data = smb_buf(inbuf);
+ } else {
+ numtowrite = SVAL(inbuf,smb_vwv10);
+ data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
+ }
- if (numtowrite>0)
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ /* force the error type */
+ CVAL(inbuf,smb_com) = SMBwritec;
+ CVAL(outbuf,smb_com) = SMBwritec;
+
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ END_PROFILE(SMBwritebraw);
+ return(ERROR(ERRDOS,ERRlock));
+ }
+
+ if (numtowrite>0)
+ nwritten = write_file(fsp,data,startpos,numtowrite);
- DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
- fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
+ DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
+ fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
- if (nwritten < numtowrite) {
- END_PROFILE(SMBwritebraw);
- return(UNIXERROR(ERRHRD,ERRdiskfull));
- }
+ if (nwritten < numtowrite) {
+ END_PROFILE(SMBwritebraw);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
- total_written = nwritten;
+ total_written = nwritten;
- /* Return a message to the redirector to tell it
- to send more bytes */
- CVAL(outbuf,smb_com) = SMBwritebraw;
- SSVALS(outbuf,smb_vwv0,-1);
- outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_writebraw: send_smb failed.\n");
+ /* Return a message to the redirector to tell it to send more bytes */
+ CVAL(outbuf,smb_com) = SMBwritebraw;
+ SSVALS(outbuf,smb_vwv0,-1);
+ outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
+ if (!send_smb(smbd_server_fd(),outbuf))
+ exit_server("reply_writebraw: send_smb failed.\n");
- /* Now read the raw data into the buffer and write it */
- if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
- exit_server("secondary writebraw failed");
- }
+ /* Now read the raw data into the buffer and write it */
+ if (read_smb_length(smbd_server_fd(),inbuf,SMB_SECONDARY_WAIT) == -1) {
+ exit_server("secondary writebraw failed");
+ }
- /* Even though this is not an smb message, smb_len
- returns the generic length of an smb message */
- numtowrite = smb_len(inbuf);
+ /* Even though this is not an smb message, smb_len returns the generic length of an smb message */
+ numtowrite = smb_len(inbuf);
- if (tcount > nwritten+numtowrite) {
- DEBUG(3,("Client overestimated the write %d %d %d\n",
- (int)tcount,(int)nwritten,(int)numtowrite));
- }
+ /* Set up outbuf to return the correct return */
+ outsize = set_message(outbuf,1,0,True);
+ CVAL(outbuf,smb_com) = SMBwritec;
+ SSVAL(outbuf,smb_vwv0,total_written);
- nwritten = vfs_transfer_file(smbd_server_fd(), NULL, -1, fsp,
- (SMB_OFF_T)numtowrite,NULL,0,
- startpos+nwritten);
- total_written += nwritten;
-
- /* Set up outbuf to return the correct return */
- outsize = set_message(outbuf,1,0,True);
- CVAL(outbuf,smb_com) = SMBwritec;
- SSVAL(outbuf,smb_vwv0,total_written);
+ if (numtowrite != 0) {
- if (nwritten < (ssize_t)numtowrite) {
- CVAL(outbuf,smb_rcls) = ERRHRD;
- SSVAL(outbuf,smb_err,ERRdiskfull);
- }
+ if (numtowrite > BUFFER_SIZE) {
+ DEBUG(0,("reply_writebraw: Oversize secondary write raw requested (%u). Terminating\n",
+ (unsigned int)numtowrite ));
+ exit_server("secondary writebraw failed");
+ }
- if ((lp_syncalways(SNUM(conn)) || write_through) &&
- lp_strict_sync(SNUM(conn)))
- sync_file(conn,fsp);
+ if (tcount > nwritten+numtowrite) {
+ DEBUG(3,("Client overestimated the write %d %d %d\n",
+ (int)tcount,(int)nwritten,(int)numtowrite));
+ }
- DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
- fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
+ if (read_data( smbd_server_fd(), inbuf+4, numtowrite) != numtowrite ) {
+ DEBUG(0,("reply_writebraw: Oversize secondary write raw read failed (%s). Terminating\n",
+ strerror(errno) ));
+ exit_server("secondary writebraw failed");
+ }
- /* we won't return a status if write through is not selected - this
- follows what WfWg does */
- END_PROFILE(SMBwritebraw);
- if (!write_through && total_written==tcount) {
- /*
- * Fix for "rabbit pellet" mode, trigger an early TCP ack by
- * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
- */
- if (!send_keepalive(smbd_server_fd()))
- exit_server("reply_writebraw: send of keepalive failed");
- return(-1);
- }
+ nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
- return(outsize);
+ if (nwritten < (ssize_t)numtowrite) {
+ CVAL(outbuf,smb_rcls) = ERRHRD;
+ SSVAL(outbuf,smb_err,ERRdiskfull);
+ }
+
+ if (nwritten > 0)
+ total_written += nwritten;
+ }
+
+ if ((lp_syncalways(SNUM(conn)) || write_through) && lp_strict_sync(SNUM(conn)))
+ sync_file(conn,fsp);
+
+ DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
+ fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
+
+ /* we won't return a status if write through is not selected - this follows what WfWg does */
+ END_PROFILE(SMBwritebraw);
+ if (!write_through && total_written==tcount) {
+ /*
+ * Fix for "rabbit pellet" mode, trigger an early TCP ack by
+ * sending a SMBkeepalive. Thanks to DaveCB at Sun for this. JRA.
+ */
+ if (!send_keepalive(smbd_server_fd()))
+ exit_server("reply_writebraw: send of keepalive failed");
+ return(-1);
+ }
+
+ return(outsize);
}
/****************************************************************************
@@ -2581,7 +2580,6 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
- CHECK_ERROR(fsp);
numtowrite = SVAL(inbuf,smb_vwv1);
startpos = IVAL(inbuf,smb_vwv2);
@@ -2625,8 +2623,31 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
}
/****************************************************************************
- reply to a write
+ Return correct error for space allocation fail.
+****************************************************************************/
+
+int allocate_space_error(char *inbuf,char *outbuf, int errno_val)
+{
+ errno = errno_val;
+ if (!(global_client_caps & CAP_STATUS32))
+ return (UNIXERROR(ERRHRD,ERRdiskfull));
+
+ /* Use more specific WNT/W2K error codes. */
+#ifdef EDQUOT
+ if (errno_val == ENOSPC || errno_val == EDQUOT) {
+#else
+ if (errno_val == ENOSPC) {
+#endif
+ return(ERROR(0,NT_STATUS_DISK_FULL));
+ }
+
+ return (UNIXERROR(ERRHRD,ERRdiskfull));
+}
+
+/****************************************************************************
+ Reply to a write.
****************************************************************************/
+
int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
{
size_t numtowrite;
@@ -2645,7 +2666,6 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
- CHECK_ERROR(fsp);
numtowrite = SVAL(inbuf,smb_vwv1);
startpos = IVAL(inbuf,smb_vwv2);
@@ -2660,7 +2680,13 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
zero then the file size should be extended or
truncated to the size given in smb_vwv[2-3] */
if(numtowrite == 0) {
- nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos);
+ /* This is actually an allocate call, not set EOF. JRA */
+ nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos);
+ if (nwritten < 0) {
+ int ret = allocate_space_error(inbuf, outbuf, errno);
+ END_PROFILE(SMBwrite);
+ return ret;
+ }
} else
nwritten = write_file(fsp,data,startpos,numtowrite);
@@ -2713,7 +2739,6 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
- CHECK_ERROR(fsp);
/* Deal with possible LARGE_WRITEX */
if (large_writeX)
@@ -2804,7 +2829,6 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
START_PROFILE(SMBlseek);
CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
flush_write_cache(fsp, SEEK_FLUSH);
@@ -2873,32 +2897,28 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
/****************************************************************************
- reply to a flush
+ Reply to a flush.
****************************************************************************/
int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
- int outsize = set_message(outbuf,0,0,True);
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- START_PROFILE(SMBflush);
+ int outsize = set_message(outbuf,0,0,True);
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBflush);
- if (fsp) {
- CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
- }
+ CHECK_FSP(fsp,conn);
- if (!fsp) {
- file_sync_all(conn);
- } else {
+ if (!fsp) {
+ file_sync_all(conn);
+ } else {
sync_file(conn,fsp);
- }
+ }
- DEBUG(3,("flush\n"));
- END_PROFILE(SMBflush);
- return(outsize);
+ DEBUG(3,("flush\n"));
+ END_PROFILE(SMBflush);
+ return(outsize);
}
-
/****************************************************************************
reply to a exit
****************************************************************************/
@@ -2924,7 +2944,6 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
{
int outsize = 0;
time_t mtime;
- int32 eclass = 0, err = 0;
files_struct *fsp = NULL;
START_PROFILE(SMBclose);
@@ -2947,11 +2966,6 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
return(ERROR(ERRDOS,ERRbadfid));
}
- if(HAS_CACHED_ERROR(fsp)) {
- eclass = fsp->wbmpx_ptr->wr_errclass;
- err = fsp->wbmpx_ptr->wr_error;
- }
-
if(fsp->is_directory || fsp->stat_open) {
/*
* Special case - close NT SMB directory or stat file
@@ -2997,12 +3011,6 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
}
}
- /* We have a cached error */
- if(eclass || err) {
- END_PROFILE(SMBclose);
- return(ERROR(eclass,err));
- }
-
END_PROFILE(SMBclose);
return(outsize);
}
@@ -3027,7 +3035,6 @@ int reply_writeclose(connection_struct *conn,
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
- CHECK_ERROR(fsp);
numtowrite = SVAL(inbuf,smb_vwv1);
startpos = IVAL(inbuf,smb_vwv2);
@@ -3082,7 +3089,6 @@ int reply_lock(connection_struct *conn,
START_PROFILE(SMBlock);
CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
release_level_2_oplocks_on_change(fsp);
@@ -3126,7 +3132,6 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, in
START_PROFILE(SMBunlock);
CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
count = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv1);
offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
@@ -3259,7 +3264,6 @@ int reply_printclose(connection_struct *conn,
START_PROFILE(SMBsplclose);
CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
if (!CAN_PRINT(conn)) {
END_PROFILE(SMBsplclose);
@@ -3370,7 +3374,6 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
- CHECK_ERROR(fsp);
numtowrite = SVAL(smb_buf(inbuf),1);
data = smb_buf(inbuf) + 3;
@@ -3416,86 +3419,81 @@ int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring d
}
/****************************************************************************
- reply to a mkdir
+ Reply to a mkdir
****************************************************************************/
+
int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- pstring directory;
- int outsize;
- START_PROFILE(SMBmkdir);
+ pstring directory;
+ int outsize;
+ START_PROFILE(SMBmkdir);
- pstrcpy(directory,smb_buf(inbuf) + 1);
+ pstrcpy(directory,smb_buf(inbuf) + 1);
- outsize=mkdir_internal(conn, inbuf, outbuf, directory);
- if(outsize == 0)
- outsize = set_message(outbuf,0,0,True);
+ outsize=mkdir_internal(conn, inbuf, outbuf, directory);
+ if(outsize == 0)
+ outsize = set_message(outbuf,0,0,True);
- DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
+ DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
- END_PROFILE(SMBmkdir);
- return(outsize);
+ END_PROFILE(SMBmkdir);
+ return(outsize);
}
/****************************************************************************
-Static function used by reply_rmdir to delete an entire directory
-tree recursively.
+ Static function used by reply_rmdir to delete an entire directory
+ tree recursively. Return False on ok, True on fail.
****************************************************************************/
static BOOL recursive_rmdir(connection_struct *conn, char *directory)
{
- char *dname = NULL;
- BOOL ret = False;
- void *dirptr = OpenDir(NULL, directory, False);
+ char *dname = NULL;
+ BOOL ret = False;
+ void *dirptr = OpenDir(conn, directory, False);
- if(dirptr == NULL)
- return True;
+ if(dirptr == NULL)
+ return True;
- while((dname = ReadDirName(dirptr)))
- {
- pstring fullname;
- SMB_STRUCT_STAT st;
+ while((dname = ReadDirName(dirptr))) {
+ pstring fullname;
+ SMB_STRUCT_STAT st;
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ continue;
- /* Construct the full name. */
- if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
- {
- errno = ENOMEM;
- ret = True;
- break;
- }
- pstrcpy(fullname, directory);
- pstrcat(fullname, "/");
- pstrcat(fullname, dname);
+ /* Construct the full name. */
+ if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
+ errno = ENOMEM;
+ ret = True;
+ break;
+ }
- if(conn->vfs_ops.lstat(conn,dos_to_unix(fullname,False), &st) != 0)
- {
- ret = True;
- break;
- }
+ pstrcpy(fullname, directory);
+ pstrcat(fullname, "/");
+ pstrcat(fullname, dname);
- if(st.st_mode & S_IFDIR)
- {
- if(recursive_rmdir(conn, fullname)!=0)
- {
- ret = True;
- break;
- }
- if(vfs_rmdir(conn,fullname) != 0)
- {
- ret = True;
- break;
- }
- }
- else if(vfs_unlink(conn,fullname) != 0)
- {
- ret = True;
- break;
- }
- }
- CloseDir(dirptr);
- return ret;
+ if(conn->vfs_ops.lstat(conn,dos_to_unix(fullname,False), &st) != 0) {
+ ret = True;
+ break;
+ }
+
+ if(st.st_mode & S_IFDIR) {
+ if(recursive_rmdir(conn, fullname)!=0) {
+ ret = True;
+ break;
+ }
+ if(vfs_rmdir(conn,fullname) != 0) {
+ ret = True;
+ break;
+ }
+ } else if(vfs_unlink(conn,fullname) != 0) {
+ ret = True;
+ break;
+ }
+ }
+
+ CloseDir(dirptr);
+ return ret;
}
/****************************************************************************
@@ -3504,86 +3502,75 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
BOOL rmdir_internals(connection_struct *conn, char *directory)
{
- BOOL ok;
-
- ok = (vfs_rmdir(conn,directory) == 0);
- if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn)))
- {
- /*
- * Check to see if the only thing in this directory are
- * vetoed files/directories. If so then delete them and
- * retry. If we fail to delete any of them (and we *don't*
- * do a recursive delete) then fail the rmdir.
- */
- BOOL all_veto_files = True;
- char *dname;
- void *dirptr = OpenDir(conn, directory, False);
-
- if(dirptr != NULL)
- {
- int dirpos = TellDir(dirptr);
- while ((dname = ReadDirName(dirptr)))
- {
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
- if(!IS_VETO_PATH(conn, dname))
- {
- all_veto_files = False;
- break;
- }
- }
- if(all_veto_files)
- {
- SeekDir(dirptr,dirpos);
- while ((dname = ReadDirName(dirptr)))
- {
- pstring fullname;
- SMB_STRUCT_STAT st;
-
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
+ BOOL ok;
+
+ ok = (vfs_rmdir(conn,directory) == 0);
+ if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
+ /*
+ * Check to see if the only thing in this directory are
+ * vetoed files/directories. If so then delete them and
+ * retry. If we fail to delete any of them (and we *don't*
+ * do a recursive delete) then fail the rmdir.
+ */
+ BOOL all_veto_files = True;
+ char *dname;
+ void *dirptr = OpenDir(conn, directory, False);
- /* Construct the full name. */
- if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
- {
- errno = ENOMEM;
- break;
- }
- pstrcpy(fullname, directory);
- pstrcat(fullname, "/");
- pstrcat(fullname, dname);
+ if(dirptr != NULL) {
+ int dirpos = TellDir(dirptr);
+ while ((dname = ReadDirName(dirptr))) {
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ continue;
+ if(!IS_VETO_PATH(conn, dname)) {
+ all_veto_files = False;
+ break;
+ }
+ }
+ if(all_veto_files) {
+ SeekDir(dirptr,dirpos);
+ while ((dname = ReadDirName(dirptr))) {
+ pstring fullname;
+ SMB_STRUCT_STAT st;
+
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ continue;
+
+ /* Construct the full name. */
+ if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
+ errno = ENOMEM;
+ break;
+ }
+ pstrcpy(fullname, directory);
+ pstrcat(fullname, "/");
+ pstrcat(fullname, dname);
- if(conn->vfs_ops.lstat(conn,dos_to_unix(fullname, False), &st) != 0)
- break;
- if(st.st_mode & S_IFDIR)
- {
- if(lp_recursive_veto_delete(SNUM(conn)))
- {
- if(recursive_rmdir(conn, fullname) != 0)
- break;
- }
- if(vfs_rmdir(conn,fullname) != 0)
- break;
- }
- else if(vfs_unlink(conn,fullname) != 0)
- break;
- }
- CloseDir(dirptr);
- /* Retry the rmdir */
- ok = (vfs_rmdir(conn,directory) == 0);
- }
- else
- CloseDir(dirptr);
- }
- else
- errno = ENOTEMPTY;
- }
+ if(conn->vfs_ops.lstat(conn,dos_to_unix(fullname, False), &st) != 0)
+ break;
+ if(st.st_mode & S_IFDIR) {
+ if(lp_recursive_veto_delete(SNUM(conn))) {
+ if(recursive_rmdir(conn, fullname) != 0)
+ break;
+ }
+ if(vfs_rmdir(conn,fullname) != 0)
+ break;
+ } else if(vfs_unlink(conn,fullname) != 0)
+ break;
+ }
+ CloseDir(dirptr);
+ /* Retry the rmdir */
+ ok = (vfs_rmdir(conn,directory) == 0);
+ } else {
+ CloseDir(dirptr);
+ }
+ } else {
+ errno = ENOTEMPTY;
+ }
+ }
- if (!ok)
- DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n",
- directory,strerror(errno)));
+ if (!ok)
+ DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n", directory,strerror(errno)));
- return ok;
+ return ok;
}
/****************************************************************************
@@ -3964,78 +3951,78 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, in
}
/*******************************************************************
- copy a file as part of a reply_copy
- ******************************************************************/
+ Copy a file as part of a reply_copy.
+******************************************************************/
static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
int count,BOOL target_is_directory, int *err_ret)
{
- int Access,action;
- SMB_STRUCT_STAT src_sbuf, sbuf2;
- SMB_OFF_T ret=-1;
- files_struct *fsp1,*fsp2;
- pstring dest;
+ int Access,action;
+ SMB_STRUCT_STAT src_sbuf, sbuf2;
+ SMB_OFF_T ret=-1;
+ files_struct *fsp1,*fsp2;
+ pstring dest;
- *err_ret = 0;
+ *err_ret = 0;
- pstrcpy(dest,dest1);
- if (target_is_directory) {
- char *p = strrchr(src,'/');
- if (p)
- p++;
- else
- p = src;
- pstrcat(dest,"/");
- pstrcat(dest,p);
- }
+ pstrcpy(dest,dest1);
+ if (target_is_directory) {
+ char *p = strrchr(src,'/');
+ if (p)
+ p++;
+ else
+ p = src;
+ pstrcat(dest,"/");
+ pstrcat(dest,p);
+ }
- if (!vfs_file_exist(conn,src,&src_sbuf))
- return(False);
+ if (!vfs_file_exist(conn,src,&src_sbuf))
+ return(False);
- fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
+ fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
- if (!fsp1) {
- return(False);
- }
+ if (!fsp1)
+ return(False);
- if (!target_is_directory && count)
- ofun = FILE_EXISTS_OPEN;
+ if (!target_is_directory && count)
+ ofun = FILE_EXISTS_OPEN;
- vfs_stat(conn,dest,&sbuf2);
- fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
- ofun,src_sbuf.st_mode,0,&Access,&action);
+ if (vfs_stat(conn,dest,&sbuf2) == -1)
+ ZERO_STRUCTP(&sbuf2);
- if (!fsp2) {
- close_file(fsp1,False);
- return(False);
- }
+ fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
+ ofun,src_sbuf.st_mode,0,&Access,&action);
- if ((ofun&3) == 1) {
- if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) {
- DEBUG(0,("copy_file: error - sys_lseek returned error %s\n",
- strerror(errno) ));
- /*
- * Stop the copy from occurring.
- */
- ret = -1;
- src_sbuf.st_size = 0;
- }
- }
+ if (!fsp2) {
+ close_file(fsp1,False);
+ return(False);
+ }
+
+ if ((ofun&3) == 1) {
+ if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) {
+ DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
+ /*
+ * Stop the copy from occurring.
+ */
+ ret = -1;
+ src_sbuf.st_size = 0;
+ }
+ }
- if (src_sbuf.st_size)
- ret = vfs_transfer_file(-1, fsp1, -1, fsp2, src_sbuf.st_size, NULL, 0, 0);
+ if (src_sbuf.st_size)
+ ret = vfs_transfer_file(fsp1, fsp2, src_sbuf.st_size);
- close_file(fsp1,False);
- /*
- * As we are opening fsp1 read-only we only expect
- * an error on close on fsp2 if we are out of space.
- * Thus we don't look at the error return from the
- * close of fsp1.
- */
- *err_ret = close_file(fsp2,False);
+ close_file(fsp1,False);
+ /*
+ * As we are opening fsp1 read-only we only expect
+ * an error on close on fsp2 if we are out of space.
+ * Thus we don't look at the error return from the
+ * close of fsp1.
+ */
+ *err_ret = close_file(fsp2,False);
- return(ret == (SMB_OFF_T)src_sbuf.st_size);
+ return(ret == (SMB_OFF_T)src_sbuf.st_size);
}
@@ -4296,6 +4283,40 @@ SMB_BIG_UINT get_lock_count( char *data, int data_offset, BOOL large_file_format
return count;
}
+#if !defined(HAVE_LONGLONG)
+/****************************************************************************
+ Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
+****************************************************************************/
+
+static uint32 map_lock_offset(uint32 high, uint32 low)
+{
+ unsigned int i;
+ uint32 mask = 0;
+ uint32 highcopy = high;
+
+ /*
+ * Try and find out how many significant bits there are in high.
+ */
+
+ for(i = 0; highcopy; i++)
+ highcopy >>= 1;
+
+ /*
+ * We use 31 bits not 32 here as POSIX
+ * lock offsets may not be negative.
+ */
+
+ mask = (~0) << (31 - i);
+
+ if(low & mask)
+ return 0; /* Fail. */
+
+ high <<= (31 - i);
+
+ return (high|low);
+}
+#endif /* !defined(HAVE_LONGLONG) */
+
/****************************************************************************
Get a lock offset, dealing with large offset requests.
****************************************************************************/
@@ -4368,7 +4389,6 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
START_PROFILE(SMBlockingX);
CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
data = smb_buf(inbuf);
@@ -4529,277 +4549,6 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
return chain_reply(inbuf,outbuf,length,bufsize);
}
-
-/****************************************************************************
- reply to a SMBreadbmpx (read block multiplex) request
-****************************************************************************/
-int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
-{
- ssize_t nread = -1;
- ssize_t total_read;
- char *data;
- SMB_OFF_T startpos;
- int outsize;
- size_t maxcount;
- int max_per_packet;
- size_t tcount;
- int pad;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- START_PROFILE(SMBreadBmpx);
-
- /* this function doesn't seem to work - disable by default */
- if (!lp_readbmpx()) {
- END_PROFILE(SMBreadBmpx);
- return(ERROR(ERRSRV,ERRuseSTD));
- }
-
- outsize = set_message(outbuf,8,0,True);
-
- CHECK_FSP(fsp,conn);
- CHECK_READ(fsp);
- CHECK_ERROR(fsp);
-
- startpos = IVAL(inbuf,smb_vwv1);
- maxcount = SVAL(inbuf,smb_vwv3);
-
- data = smb_buf(outbuf);
- pad = ((long)data)%4;
- if (pad) pad = 4 - pad;
- data += pad;
-
- max_per_packet = bufsize-(outsize+pad);
- tcount = maxcount;
- total_read = 0;
-
- if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
- END_PROFILE(SMBreadBmpx);
- return(ERROR(ERRDOS,ERRlock));
- }
-
- do
- {
- size_t N = MIN(max_per_packet,tcount-total_read);
-
- nread = read_file(fsp,data,startpos,N);
-
- if (nread <= 0) nread = 0;
-
- if (nread < (ssize_t)N)
- tcount = total_read + nread;
-
- set_message(outbuf,8,nread,False);
- SIVAL(outbuf,smb_vwv0,startpos);
- SSVAL(outbuf,smb_vwv2,tcount);
- SSVAL(outbuf,smb_vwv6,nread);
- SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
-
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_readbmpx: send_smb failed.\n");
-
- total_read += nread;
- startpos += nread;
- }
- while (total_read < (ssize_t)tcount);
-
- END_PROFILE(SMBreadBmpx);
- return(-1);
-}
-
-/****************************************************************************
- reply to a SMBwritebmpx (write block multiplex primary) request
-****************************************************************************/
-
-int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
-{
- size_t numtowrite;
- ssize_t nwritten = -1;
- int outsize = 0;
- SMB_OFF_T startpos;
- size_t tcount;
- BOOL write_through;
- int smb_doff;
- char *data;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- START_PROFILE(SMBwriteBmpx);
-
- CHECK_FSP(fsp,conn);
- CHECK_WRITE(fsp);
- CHECK_ERROR(fsp);
-
- tcount = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv3);
- write_through = BITSETW(inbuf+smb_vwv7,0);
- numtowrite = SVAL(inbuf,smb_vwv10);
- smb_doff = SVAL(inbuf,smb_vwv11);
-
- data = smb_base(inbuf) + smb_doff;
-
- /* If this fails we need to send an SMBwriteC response,
- not an SMBwritebmpx - set this up now so we don't forget */
- CVAL(outbuf,smb_com) = SMBwritec;
-
- if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
- END_PROFILE(SMBwriteBmpx);
- return(ERROR(ERRDOS,ERRlock));
- }
-
- nwritten = write_file(fsp,data,startpos,numtowrite);
-
- if(lp_syncalways(SNUM(conn)) || write_through)
- sync_file(conn,fsp);
-
- if(nwritten < (ssize_t)numtowrite) {
- END_PROFILE(SMBwriteBmpx);
- return(UNIXERROR(ERRHRD,ERRdiskfull));
- }
-
- /* If the maximum to be written to this file
- is greater than what we just wrote then set
- up a secondary struct to be attached to this
- fd, we will use this to cache error messages etc. */
- if((ssize_t)tcount > nwritten)
- {
- write_bmpx_struct *wbms;
- if(fsp->wbmpx_ptr != NULL)
- wbms = fsp->wbmpx_ptr; /* Use an existing struct */
- else
- wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
- if(!wbms)
- {
- DEBUG(0,("Out of memory in reply_readmpx\n"));
- END_PROFILE(SMBwriteBmpx);
- return(ERROR(ERRSRV,ERRnoresource));
- }
- wbms->wr_mode = write_through;
- wbms->wr_discard = False; /* No errors yet */
- wbms->wr_total_written = nwritten;
- wbms->wr_errclass = 0;
- wbms->wr_error = 0;
- fsp->wbmpx_ptr = wbms;
- }
-
- /* We are returning successfully, set the message type back to
- SMBwritebmpx */
- CVAL(outbuf,smb_com) = SMBwriteBmpx;
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
-
- DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten ) );
-
- if (write_through && tcount==nwritten) {
- /* we need to send both a primary and a secondary response */
- smb_setlen(outbuf,outsize - 4);
- if (!send_smb(smbd_server_fd(),outbuf))
- exit_server("reply_writebmpx: send_smb failed.\n");
-
- /* now the secondary */
- outsize = set_message(outbuf,1,0,True);
- CVAL(outbuf,smb_com) = SMBwritec;
- SSVAL(outbuf,smb_vwv0,nwritten);
- }
-
- END_PROFILE(SMBwriteBmpx);
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a SMBwritebs (write block multiplex secondary) request
-****************************************************************************/
-int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
-{
- size_t numtowrite;
- ssize_t nwritten = -1;
- int outsize = 0;
- SMB_OFF_T startpos;
- size_t tcount;
- BOOL write_through;
- int smb_doff;
- char *data;
- write_bmpx_struct *wbms;
- BOOL send_response = False;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- START_PROFILE(SMBwriteBs);
-
- CHECK_FSP(fsp,conn);
- CHECK_WRITE(fsp);
-
- tcount = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- numtowrite = SVAL(inbuf,smb_vwv6);
- smb_doff = SVAL(inbuf,smb_vwv7);
-
- data = smb_base(inbuf) + smb_doff;
-
- /* We need to send an SMBwriteC response, not an SMBwritebs */
- CVAL(outbuf,smb_com) = SMBwritec;
-
- /* This fd should have an auxiliary struct attached,
- check that it does */
- wbms = fsp->wbmpx_ptr;
- if(!wbms) {
- END_PROFILE(SMBwriteBs);
- return(-1);
- }
-
- /* If write through is set we can return errors, else we must
- cache them */
- write_through = wbms->wr_mode;
-
- /* Check for an earlier error */
- if(wbms->wr_discard) {
- END_PROFILE(SMBwriteBs);
- return -1; /* Just discard the packet */
- }
-
- nwritten = write_file(fsp,data,startpos,numtowrite);
-
- if(lp_syncalways(SNUM(conn)) || write_through)
- sync_file(conn,fsp);
-
- if (nwritten < (ssize_t)numtowrite)
- {
- if(write_through)
- {
- /* We are returning an error - we can delete the aux struct */
- if (wbms) free((char *)wbms);
- fsp->wbmpx_ptr = NULL;
- END_PROFILE(SMBwriteBs);
- return(ERROR(ERRHRD,ERRdiskfull));
- }
- END_PROFILE(SMBwriteBs);
- return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
- }
-
- /* Increment the total written, if this matches tcount
- we can discard the auxiliary struct (hurrah !) and return a writeC */
- wbms->wr_total_written += nwritten;
- if(wbms->wr_total_written >= tcount)
- {
- if (write_through)
- {
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
- send_response = True;
- }
-
- free((char *)wbms);
- fsp->wbmpx_ptr = NULL;
- }
-
- if(send_response) {
- END_PROFILE(SMBwriteBs);
- return(outsize);
- }
-
- END_PROFILE(SMBwriteBs);
- return(-1);
-}
-
-
/****************************************************************************
reply to a SMBsetattrE
****************************************************************************/
@@ -4814,7 +4563,6 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
outsize = set_message(outbuf,0,0,True);
CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
/* Convert the DOS times into unix times. Ignore create
time as UNIX can't set this.
@@ -4873,7 +4621,6 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
outsize = set_message(outbuf,11,0,True);
CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
/* Do an fstat on this file */
if(vfs_fstat(fsp,fsp->fd, &sbuf)) {
diff --git a/source/smbd/sec_ctx.c b/source/smbd/sec_ctx.c
index 9ca63a0f957..03f307164d9 100644
--- a/source/smbd/sec_ctx.c
+++ b/source/smbd/sec_ctx.c
@@ -223,6 +223,10 @@ BOOL initialise_groups(char *user, uid_t uid, gid_t gid)
struct sec_ctx *prev_ctx_p;
BOOL result = True;
+ if (non_root_mode()) {
+ return True;
+ }
+
become_root();
/* Call initgroups() to get user groups */
@@ -356,7 +360,7 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
current_user.gid = gid;
current_user.ngroups = ngroups;
current_user.groups = groups;
- current_user.nt_user_token = token;
+ current_user.nt_user_token = ctx_p->token;
}
/****************************************************************************
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 49cc9c8fa5c..a8bccc548d9 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -158,7 +158,11 @@ max can be %d\n",
s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
if(s == -1)
return False;
- /* ready to listen */
+
+ /* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
+
if (listen(s, 5) == -1) {
DEBUG(0,("listen: %s\n",strerror(errno)));
close(s);
@@ -178,6 +182,9 @@ max can be %d\n",
return(False);
/* ready to listen */
+ set_socket_options(s,"SO_KEEPALIVE");
+ set_socket_options(s,user_socket_options);
+
if (listen(s, 5) == -1) {
DEBUG(0,("open_sockets: listen: %s\n",
strerror(errno)));
@@ -272,6 +279,9 @@ max can be %d\n",
done correctly in the process. */
reset_globals_after_fork();
+ /* tdb needs special fork handling */
+ tdb_reopen_all();
+
return True;
}
/* The parent doesn't need this socket */
@@ -574,7 +584,7 @@ static void usage(char *pname)
case 'l':
specified_logfile = True;
- pstrcpy(debugf,optarg);
+ slprintf(debugf, sizeof(debugf)-1, "%s/log.smbd", optarg);
break;
case 'a':
@@ -698,10 +708,10 @@ static void usage(char *pname)
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
- DEBUG(0,("ERROR: failed to setup profiling\n"));
+ DEBUG(0,("ERROR: failed to setup profiling shared memory\n"));
return -1;
}
-#endif
+#endif /* WITH_PROFILE */
#ifdef WITH_SSL
{
@@ -771,7 +781,7 @@ static void usage(char *pname)
exit(1);
}
- if(!initialize_password_db()) {
+ if(!initialize_password_db(False)) {
exit(1);
}
diff --git a/source/smbd/service.c b/source/smbd/service.c
index f2af4403b2a..ffbdefbecb7 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -516,6 +516,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
*ecode = ERRaccess;
DEBUG(0,( "make_connection: connection to %s denied due to security descriptor.\n",
service ));
+ yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
conn_free(conn);
return NULL;
} else {
@@ -527,6 +528,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
if (!vfs_init(conn)) {
DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn))));
+ yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
conn_free(conn);
return NULL;
}
@@ -540,6 +542,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_rootpreexec_close(SNUM(conn))) {
DEBUG(1,("preexec gave %d - failing connection\n", ret));
+ yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
conn_free(conn);
*ecode = ERRsrverror;
return NULL;
@@ -592,6 +595,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_preexec_close(SNUM(conn))) {
DEBUG(1,("preexec gave %d - failing connection\n", ret));
+ yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
conn_free(conn);
*ecode = ERRsrverror;
return NULL;
diff --git a/source/smbd/session.c b/source/smbd/session.c
index 8f6907c5378..bf21677f566 100644
--- a/source/smbd/session.c
+++ b/source/smbd/session.c
@@ -62,7 +62,7 @@ BOOL session_claim(uint16 vuid)
}
if (!tdb) {
- tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST,
+ tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT,
O_RDWR | O_CREAT, 0644);
if (!tdb) {
DEBUG(1,("session_claim: failed to open sessionid tdb\n"));
diff --git a/source/smbd/ssl.c b/source/smbd/ssl.c
index dff5f34d5dd..c45afc52d53 100644
--- a/source/smbd/ssl.c
+++ b/source/smbd/ssl.c
@@ -29,8 +29,8 @@
#ifdef WITH_SSL /* should always be defined if this module is compiled */
-#include <ssl.h>
-#include <err.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
BOOL sslEnabled;
SSL *ssl = NULL;
@@ -74,12 +74,12 @@ char buffer[256];
return ok;
}
-static RSA *ssl_temp_rsa_cb(SSL *ssl, int export)
+static RSA *ssl_temp_rsa_cb(SSL *ssl, int is_export, int keylength)
{
static RSA *rsa = NULL;
if(rsa == NULL)
- rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
+ rsa = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
return rsa;
}
@@ -89,11 +89,19 @@ static RSA *rsa = NULL;
*/
int sslutil_init(int isServer)
{
-int err;
+int err, entropybytes;
char *certfile, *keyfile, *ciphers, *cacertDir, *cacertFile;
+char *egdsocket, *entropyfile;
SSL_load_error_strings();
SSLeay_add_ssl_algorithms();
+ egdsocket = lp_ssl_egdsocket();
+ if (egdsocket != NULL && *egdsocket != 0)
+ RAND_egd(egdsocket);
+ entropyfile = lp_ssl_entropyfile();
+ entropybytes = lp_ssl_entropybytes();
+ if (entropyfile != NULL && *entropyfile != 0)
+ RAND_load_file(entropyfile, entropybytes);
switch(lp_ssl_version()){
case SMB_SSL_V2: sslContext = SSL_CTX_new(SSLv2_method()); break;
case SMB_SSL_V3: sslContext = SSL_CTX_new(SSLv3_method()); break;
@@ -120,7 +128,7 @@ char *certfile, *keyfile, *ciphers, *cacertDir, *cacertFile;
if(keyfile == NULL || *keyfile == 0)
keyfile = certfile;
if(certfile != NULL && *certfile != 0){
- if(!SSL_CTX_use_certificate_file(sslContext, certfile, SSL_FILETYPE_PEM)){
+ if(!SSL_CTX_use_certificate_chain_file(sslContext, certfile)){
err = ERR_get_error();
fprintf(stderr, "SSL: error reading certificate from file %s: %s\n",
certfile, ERR_error_string(err, NULL));
@@ -146,9 +154,11 @@ char *certfile, *keyfile, *ciphers, *cacertDir, *cacertFile;
cacertFile = NULL;
if(!SSL_CTX_load_verify_locations(sslContext, cacertFile, cacertDir)){
err = ERR_get_error();
- fprintf(stderr, "SSL: Error error setting CA cert locations: %s\n",
- ERR_error_string(err, NULL));
- fprintf(stderr, "trying default locations.\n");
+ if (cacertFile || cacertDir) {
+ fprintf(stderr, "SSL: Error error setting CA cert locations: %s\n",
+ ERR_error_string(err, NULL));
+ fprintf(stderr, "trying default locations.\n");
+ }
cacertFile = cacertDir = NULL;
if(!SSL_CTX_set_default_verify_paths(sslContext)){
err = ERR_get_error();
diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c
index 65a48300164..03d22a08d03 100644
--- a/source/smbd/statcache.c
+++ b/source/smbd/statcache.c
@@ -3,7 +3,7 @@
Version 3.0
stat cache code
Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 1999-200
+ Copyright (C) Jeremy Allison 1999-2000
This program is free software; you can redistribute it and/or modify
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 5f0652e5780..fb92e48ab68 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -54,7 +54,7 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
char *pp = params;
char *pd = pdata;
int params_sent_thistime, data_sent_thistime, total_sent_thistime;
- int alignment_offset = 3;
+ int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
int data_alignment_offset = 0;
/* Initially set the wcnt area to be 10 - this is true for all
@@ -410,7 +410,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
{
/* Needed to show the msdfs symlinks as directories */
if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
- || !is_msdfs_link(conn, pathreal))
+ || !is_msdfs_link(conn, pathreal, NULL, NULL))
{
DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
pathreal,strerror(errno)));
@@ -1297,318 +1297,302 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
char **pparams,char **ppdata,
int total_data)
{
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
- char *params = *pparams;
- char *pdata = *ppdata;
- uint16 tran_call = SVAL(inbuf, smb_setup0);
- uint16 info_level;
- int mode=0;
- SMB_OFF_T size=0;
- unsigned int data_size;
- SMB_STRUCT_STAT sbuf;
- pstring fname1;
- char *fname;
- char *p;
- int l;
- SMB_OFF_T pos = 0;
- BOOL bad_path = False;
- BOOL delete_pending = False;
- time_t c_time;
-
- if (tran_call == TRANSACT2_QFILEINFO) {
- files_struct *fsp = file_fsp(params,0);
- info_level = SVAL(params,2);
+ int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
+ char *params = *pparams;
+ char *pdata = *ppdata;
+ uint16 tran_call = SVAL(inbuf, smb_setup0);
+ uint16 info_level;
+ int mode=0;
+ SMB_OFF_T size=0;
+ unsigned int data_size;
+ SMB_STRUCT_STAT sbuf;
+ pstring fname1;
+ char *fname;
+ char *p;
+ int l;
+ SMB_OFF_T pos = 0;
+ BOOL bad_path = False;
+ BOOL delete_pending = False;
+ time_t c_time;
+
+ if (tran_call == TRANSACT2_QFILEINFO) {
+ files_struct *fsp = file_fsp(params,0);
+ info_level = SVAL(params,2);
+
+ DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+
+ if(fsp && (fsp->is_directory || fsp->stat_open)) {
+ /*
+ * This is actually a QFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+ fname = fsp->fsp_name;
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (!check_name(fname,conn) ||
+ (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
+ DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
+
+ if((errno == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
- DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+ delete_pending = fsp->directory_delete_on_close;
- if(fsp && (fsp->is_directory || fsp->stat_open)) {
- /*
- * This is actually a QFILEINFO on a directory
- * handle (returned from an NT SMB). NT5.0 seems
- * to do this call. JRA.
- */
- fname = fsp->fsp_name;
- unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (!check_name(fname,conn) ||
- (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
- DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+ CHECK_FSP(fsp,conn);
- delete_pending = fsp->directory_delete_on_close;
+ fname = fsp->fsp_name;
+ if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
+ DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
+ return(UNIXERROR(ERRDOS,ERRbadfid));
+ }
- } else {
- /*
- * Original code - this is an open file.
- */
- CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
+ if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
- fname = fsp->fsp_name;
- if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
- DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
- return(UNIXERROR(ERRDOS,ERRbadfid));
- }
- if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ delete_pending = fsp->delete_on_close;
+ }
+ } else {
+ /* qpathinfo */
+ info_level = SVAL(params,0);
- delete_pending = fsp->delete_on_close;
- }
- } else {
- /* qpathinfo */
- info_level = SVAL(params,0);
+ DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
- DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
+ fname = &fname1[0];
+ pstrcpy(fname,&params[6]);
- fname = &fname1[0];
- pstrcpy(fname,&params[6]);
+ RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (!check_name(fname,conn) || (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
+ DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
+ if((errno == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ }
+ }
- unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (!check_name(fname,conn) ||
- (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
- DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
- }
+ DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
+ fname,info_level,tran_call,total_data));
+ p = strrchr(fname,'/');
+ if (!p)
+ p = fname;
+ else
+ p++;
+ l = strlen(p);
+ mode = dos_mode(conn,fname,&sbuf);
+ size = sbuf.st_size;
+ if (mode & aDIR)
+ size = 0;
+
+ /* from now on we only want the part after the / */
+ fname = p;
+
+ params = Realloc(*pparams,2);
+ if ( params == NULL )
+ return(ERROR(ERRDOS,ERRnomem));
+ *pparams = params;
+ memset((char *)params,'\0',2);
+ data_size = max_data_bytes + 1024;
+ pdata = Realloc(*ppdata, data_size);
+ if ( pdata == NULL )
+ return(ERROR(ERRDOS,ERRnomem));
+ *ppdata = pdata;
- DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
- fname,info_level,tran_call,total_data));
+ if (total_data > 0 && IVAL(pdata,0) == total_data) {
+ /* uggh, EAs for OS2 */
+ DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
+ return(ERROR(ERRDOS,ERReasnotsupported));
+ }
- p = strrchr(fname,'/');
- if (!p)
- p = fname;
- else
- p++;
- l = strlen(p);
- mode = dos_mode(conn,fname,&sbuf);
- size = sbuf.st_size;
- if (mode & aDIR) size = 0;
+ memset((char *)pdata,'\0',data_size);
- /* from now on we only want the part after the / */
- fname = p;
-
- params = Realloc(*pparams,2);
- if ( params == NULL ) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *pparams = params;
- memset((char *)params,'\0',2);
- data_size = max_data_bytes + 1024;
- pdata = Realloc(*ppdata, data_size);
- if ( pdata == NULL ) {
- return(ERROR(ERRDOS,ERRnomem));
- }
- *ppdata = pdata;
+ c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
- if (total_data > 0 && IVAL(pdata,0) == total_data) {
- /* uggh, EAs for OS2 */
- DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
- return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
- }
+ if (lp_dos_filetime_resolution(SNUM(conn))) {
+ c_time &= ~1;
+ sbuf.st_atime &= ~1;
+ sbuf.st_mtime &= ~1;
+ sbuf.st_mtime &= ~1;
+ }
- memset((char *)pdata,'\0',data_size);
+ switch (info_level) {
+ case SMB_INFO_STANDARD:
+ case SMB_INFO_QUERY_EA_SIZE:
+ data_size = (info_level==1?22:26);
+ put_dos_date2(pdata,l1_fdateCreation,c_time);
+ put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
+ put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
+ SIVAL(pdata,l1_cbFile,(uint32)size);
+ SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
+ SSVAL(pdata,l1_attrFile,mode);
+ SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
+ break;
- c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
+ data_size = 24;
+ put_dos_date2(pdata,0,c_time);
+ put_dos_date2(pdata,4,sbuf.st_atime);
+ put_dos_date2(pdata,8,sbuf.st_mtime);
+ SIVAL(pdata,12,(uint32)size);
+ SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
+ SIVAL(pdata,20,mode);
+ break;
- if (lp_dos_filetime_resolution(SNUM(conn))) {
- c_time &= ~1;
- sbuf.st_atime &= ~1;
- sbuf.st_mtime &= ~1;
- sbuf.st_mtime &= ~1;
- }
+ case SMB_INFO_QUERY_ALL_EAS:
+ data_size = 4;
+ SIVAL(pdata,0,data_size);
+ break;
- switch (info_level)
- {
- case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
- data_size = (info_level==1?22:26);
- put_dos_date2(pdata,l1_fdateCreation,c_time);
- put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
- put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
- SIVAL(pdata,l1_cbFile,(uint32)size);
- SIVAL(pdata,l1_cbFileAlloc,SMB_ROUNDUP(size,1024));
- SSVAL(pdata,l1_attrFile,mode);
- SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
- break;
+ case 6:
+ return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
- case SMB_INFO_QUERY_EAS_FROM_LIST:
- data_size = 24;
- put_dos_date2(pdata,0,c_time);
- put_dos_date2(pdata,4,sbuf.st_atime);
- put_dos_date2(pdata,8,sbuf.st_mtime);
- SIVAL(pdata,12,(uint32)size);
- SIVAL(pdata,16,SMB_ROUNDUP(size,1024));
- SIVAL(pdata,20,mode);
- break;
+ case SMB_FILE_BASIC_INFORMATION:
+ case SMB_QUERY_FILE_BASIC_INFO:
- case SMB_INFO_QUERY_ALL_EAS:
- data_size = 4;
- SIVAL(pdata,0,data_size);
- break;
+ if (info_level == SMB_QUERY_FILE_BASIC_INFO)
+ data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
+ else {
+ data_size = 40;
+ SIVAL(pdata,36,0);
+ }
+ put_long_date(pdata,c_time);
+ put_long_date(pdata+8,sbuf.st_atime);
+ put_long_date(pdata+16,sbuf.st_mtime); /* write time */
+ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+ SIVAL(pdata,32,mode);
- case 6:
- return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
+ DEBUG(5,("SMB_QFBI - "));
- case SMB_QUERY_FILE_BASIC_INFO:
- case 1004:
+ {
+ time_t create_time = c_time;
+ DEBUG(5,("create: %s ", ctime(&create_time)));
+ }
- if (info_level == SMB_QUERY_FILE_BASIC_INFO)
- data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
- else {
- data_size = 40;
- SIVAL(pdata,36,0);
- }
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,mode);
+ DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
+ DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
+ DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
+ DEBUG(5,("mode: %x\n", mode));
- DEBUG(5,("SMB_QFBI - "));
- {
- time_t create_time = c_time;
- DEBUG(5,("create: %s ", ctime(&create_time)));
- }
- DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
- DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
- DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
- DEBUG(5,("mode: %x\n", mode));
+ break;
- break;
+ case SMB_FILE_STANDARD_INFORMATION:
+ case SMB_QUERY_FILE_STANDARD_INFO:
- case SMB_QUERY_FILE_STANDARD_INFO:
- data_size = 22;
- SOFF_T(pdata,0,size);
- SOFF_T(pdata,8,size);
- SIVAL(pdata,16,sbuf.st_nlink);
- CVAL(pdata,20) = 0;
- CVAL(pdata,21) = (mode&aDIR)?1:0;
- break;
+ data_size = 22;
+ SOFF_T(pdata,0,size);
+ SOFF_T(pdata,8,size);
+ SIVAL(pdata,16,sbuf.st_nlink);
+ CVAL(pdata,20) = 0;
+ CVAL(pdata,21) = (mode&aDIR)?1:0;
+ break;
- case SMB_QUERY_FILE_EA_INFO:
- data_size = 4;
- break;
+ case SMB_FILE_EA_INFORMATION:
+ case SMB_QUERY_FILE_EA_INFO:
+ data_size = 4;
+ SIVAL(pdata,0,0);
+ break;
- /* Get the 8.3 name - used if NT SMB was negotiated. */
- case SMB_QUERY_FILE_ALT_NAME_INFO:
- {
- pstring short_name;
- pstrcpy(short_name,p);
- /* Mangle if not already 8.3 */
- if(!is_8_3(short_name, True))
- {
- if(!name_map_mangle(short_name,True,True,SNUM(conn)))
- *short_name = '\0';
- }
- strupper(short_name);
- l = dos_PutUniCode(pdata + 4, short_name, sizeof(pstring), False);
- data_size = 4 + l;
- SIVAL(pdata,0,l);
- }
- break;
+ /* Get the 8.3 name - used if NT SMB was negotiated. */
- case SMB_QUERY_FILE_NAME_INFO:
- /*
- * The first part of this code is essential
- * to get security descriptors to work on mapped
- * drives. Don't ask how I discovered this unless
- * you like hearing about me suffering.... :-). JRA.
- */
- if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
- l = l*2;
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
- dos_PutUniCode(pdata + 4, "\\",sizeof(pstring), False);
- } else {
- pstrcpy(pdata+4,fname);
- }
- data_size = 4 + l;
- SIVAL(pdata,0,l);
- break;
+ case SMB_QUERY_FILE_ALT_NAME_INFO:
+ {
+ pstring short_name;
+ pstrcpy(short_name,p);
+ /* Mangle if not already 8.3 */
+ if(!is_8_3(short_name, True)) {
+ if(!name_map_mangle(short_name,True,True,SNUM(conn)))
+ *short_name = '\0';
+ }
+ strupper(short_name);
+ l = dos_PutUniCode(pdata + 4, short_name, sizeof(pstring), False);
+ data_size = 4 + l;
+ SIVAL(pdata,0,l);
+ break;
+ }
- case SMB_QUERY_FILE_ALLOCATION_INFO:
- case SMB_QUERY_FILE_END_OF_FILEINFO:
- data_size = 8;
- SOFF_T(pdata,0,size);
- break;
+ case SMB_QUERY_FILE_NAME_INFO:
+ /*
+ * The first part of this code is essential
+ * to get security descriptors to work on mapped
+ * drives. Don't ask how I discovered this unless
+ * you like hearing about me suffering.... :-). JRA.
+ */
- case SMB_QUERY_FILE_ALL_INFO:
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,mode);
- pdata += 40;
- SOFF_T(pdata,0,size);
- SOFF_T(pdata,8,size);
- SIVAL(pdata,16,sbuf.st_nlink);
- CVAL(pdata,20) = delete_pending;
- CVAL(pdata,21) = (mode&aDIR)?1:0;
- pdata += 24;
- SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
- pdata += 8; /* index number */
- pdata += 4; /* EA info */
- if (mode & aRONLY)
- SIVAL(pdata,0,0xA9);
- else
- SIVAL(pdata,0,0xd01BF);
- pdata += 4;
- SOFF_T(pdata,0,pos); /* current offset */
- pdata += 8;
- SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
- pdata += 4;
- pdata += 4; /* alignment */
- SIVAL(pdata,0,l);
- pstrcpy(pdata+4,fname);
- pdata += 4 + l;
- data_size = PTR_DIFF(pdata,(*ppdata));
- break;
+ if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
+ l = l*2;
+ SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
+ dos_PutUniCode(pdata + 4, "\\",sizeof(pstring), False);
+ } else {
+ pstrcpy(pdata+4,fname);
+ }
+ data_size = 4 + l;
+ SIVAL(pdata,0,l);
+ break;
- /*
- * Windows 2000 completely undocumented new SMB info levels.
- * Thanks Microsoft.... sure you're working on making this
- * protocol a standard.... sure you are... :-).
- * Lying rat-bastards. JRA.
- */
+ case SMB_FILE_ALLOCATION_INFORMATION:
+ case SMB_FILE_END_OF_FILE_INFORMATION:
+ case SMB_QUERY_FILE_ALLOCATION_INFO:
+ case SMB_QUERY_FILE_END_OF_FILEINFO:
+ data_size = 8;
+ SOFF_T(pdata,0,size);
+ break;
- case 1005:
- SIVAL(pdata,0,mode);
- SIVAL(pdata,4,0); /* ??? */
+ case SMB_QUERY_FILE_ALL_INFO:
+ put_long_date(pdata,c_time);
+ put_long_date(pdata+8,sbuf.st_atime);
+ put_long_date(pdata+16,sbuf.st_mtime); /* write time */
+ put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+ SIVAL(pdata,32,mode);
+ pdata += 40;
+ SOFF_T(pdata,0,size);
SOFF_T(pdata,8,size);
- SIVAL(pdata,16,1); /* ??? */
- SIVAL(pdata,20,0); /* ??? */
- data_size = 24;
+ SIVAL(pdata,16,sbuf.st_nlink);
+ CVAL(pdata,20) = delete_pending;
+ CVAL(pdata,21) = (mode&aDIR)?1:0;
+ pdata += 24;
+ SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
+ pdata += 8; /* index number */
+ pdata += 4; /* EA info */
+ if (mode & aRONLY)
+ SIVAL(pdata,0,0xA9);
+ else
+ SIVAL(pdata,0,0xd01BF);
+ pdata += 4;
+ SOFF_T(pdata,0,pos); /* current offset */
+ pdata += 8;
+ SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
+ pdata += 4;
+ pdata += 4; /* alignment */
+ SIVAL(pdata,0,l);
+ pstrcpy(pdata+4,fname);
+ pdata += 4 + l;
+ data_size = PTR_DIFF(pdata,(*ppdata));
break;
- case 1006:
- SIVAL(pdata,0,0x907); /* ??? */
- SIVAL(pdata,4,0x690000); /* ??? */
+ case SMB_FILE_INTERNAL_INFORMATION:
+ /* This should be an index number - looks like dev/ino to me :-) */
+ SIVAL(pdata,0,sbuf.st_dev);
+ SIVAL(pdata,4,sbuf.st_ino);
data_size = 8;
break;
- case 1007:
- SIVAL(pdata,0,0); /* ??? */
- data_size = 4;
- break;
-
- case 1008:
+ case SMB_FILE_ACCESS_INFORMATION:
SIVAL(pdata,0,0x12019F); /* ??? */
data_size = 4;
break;
- case 1009:
+ case SMB_FILE_NAME_INFORMATION:
/* Pathname with leading '\'. */
{
pstring new_fname;
@@ -1622,19 +1606,23 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
}
- case 1014:
- SIVAL(pdata,0,0); /* ??? */
- SIVAL(pdata,4,0); /* ??? */
+ case SMB_FILE_DISPOSITION_INFORMATION:
+ data_size = 1;
+ CVAL(pdata,0) = delete_pending;
+ break;
+
+ case SMB_FILE_POSITION_INFORMATION:
data_size = 8;
+ SOFF_T(pdata,0,pos);
break;
- case 1016:
- SIVAL(pdata,0,0); /* ??? */
+ case SMB_FILE_MODE_INFORMATION:
+ SIVAL(pdata,0,mode);
data_size = 4;
break;
- case 1017:
- SIVAL(pdata,0,0); /* ??? */
+ case SMB_FILE_ALIGNMENT_INFORMATION:
+ SIVAL(pdata,0,0); /* No alignment needed. */
data_size = 4;
break;
@@ -1663,7 +1651,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
#endif
- case 1021:
+ case SMB_FILE_ALTERNATE_NAME_INFORMATION:
/* Last component of pathname. */
{
size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
@@ -1672,8 +1660,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
break;
}
- case 1022:
- {
+ case SMB_FILE_STREAM_INFORMATION:
+ if (mode & aDIR) {
+ data_size = 0;
+ } else {
size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
SIVAL(pdata,0,0); /* ??? */
SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
@@ -1681,59 +1671,57 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
SIVAL(pdata,16,0x20); /* ??? */
SIVAL(pdata,20,0); /* ??? */
data_size = 24 + byte_len;
- break;
}
+ break;
- case 1028:
+ case SMB_FILE_COMPRESSION_INFORMATION:
SOFF_T(pdata,0,size);
SIVAL(pdata,8,0); /* ??? */
SIVAL(pdata,12,0); /* ??? */
data_size = 16;
break;
- case 1034:
+ case SMB_FILE_NETWORK_OPEN_INFORMATION:
put_long_date(pdata,c_time);
put_long_date(pdata+8,sbuf.st_atime);
put_long_date(pdata+16,sbuf.st_mtime); /* write time */
put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,0x20); /* ??? */
- SIVAL(pdata,36,0); /* ??? */
+ SOFF_T(pdata,32,(SMB_OFF_T)0x20); /* Allocation size. */
SOFF_T(pdata,40,size);
SIVAL(pdata,48,mode);
SIVAL(pdata,52,0); /* ??? */
data_size = 56;
break;
- case 1035:
+ case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
SIVAL(pdata,0,mode);
SIVAL(pdata,4,0);
data_size = 8;
break;
+#if 0
/*
- * End new completely undocumented info levels... JRA.
+ * NT4 server just returns "invalid query" to this - if we try to answer
+ * it then NTws gets a BSOD! (tridge).
*/
-#if 0
- /* NT4 server just returns "invalid query" to this - if we try to answer
- it then NTws gets a BSOD! (tridge) */
- case SMB_QUERY_FILE_STREAM_INFO:
- data_size = 24 + l;
- SIVAL(pdata,0,pos);
- SIVAL(pdata,4,size);
- SIVAL(pdata,12,size);
- SIVAL(pdata,20,l);
- pstrcpy(pdata+24,fname);
- break;
+ case SMB_QUERY_FILE_STREAM_INFO:
+ data_size = 24 + l;
+ SIVAL(pdata,0,pos);
+ SIVAL(pdata,4,size);
+ SIVAL(pdata,12,size);
+ SIVAL(pdata,20,l);
+ pstrcpy(pdata+24,fname);
+ break;
#endif
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
+ default:
+ return(ERROR(ERRDOS,ERRunknownlevel));
+ }
- send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
+ send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
- return(-1);
+ return(-1);
}
/****************************************************************************
@@ -1779,11 +1767,12 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
}
return(UNIXERROR(ERRDOS,ERRbadpath));
}
- } else if (fsp->print_file) {
+ } else if (fsp && fsp->print_file) {
/*
* Doing a DELETE_ON_CLOSE should cancel a print job.
*/
- if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
+ if (((info_level == SMB_SET_FILE_DISPOSITION_INFO)||(info_level == SMB_FILE_DISPOSITION_INFORMATION)) &&
+ CVAL(pdata,0)) {
fsp->share_mode = FILE_DELETE_ON_CLOSE;
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
@@ -1798,7 +1787,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
* Original code - this is an open file.
*/
CHECK_FSP(fsp,conn);
- CHECK_ERROR(fsp);
fname = fsp->fsp_name;
fd = fsp->fd;
@@ -1858,7 +1846,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (total_data > 4 && IVAL(pdata,0) == total_data) {
/* uggh, EAs for OS2 */
DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
- return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
+ return(ERROR(ERRDOS,ERReasnotsupported));
}
switch (info_level)
@@ -1923,28 +1911,62 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
break;
}
- /*
- * NT seems to use this call with a size of zero
- * to mean truncate the file. JRA.
- */
-
- case 1019:
- case 1020:
+ case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_SET_FILE_ALLOCATION_INFO:
{
- SMB_OFF_T newsize = IVAL(pdata,0);
+ int ret = -1;
+ size = IVAL(pdata,0);
#ifdef LARGE_SMB_OFF_T
- newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+ size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
#else /* LARGE_SMB_OFF_T */
if (IVAL(pdata,4) != 0) /* more than 32 bits? */
return(ERROR(ERRDOS,ERRunknownlevel));
#endif /* LARGE_SMB_OFF_T */
- DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
- if(newsize == 0)
- size = 0;
+ DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
+ fname, (double)size ));
+
+ if(size != sbuf.st_size) {
+
+ DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
+ fname, (double)size ));
+
+ if (fd == -1) {
+ files_struct *new_fsp = NULL;
+ int access_mode = 0;
+ int action = 0;
+
+ if(global_oplock_break) {
+ /* Queue this file modify as we are the process of an oplock break. */
+
+ DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
+ DEBUGADD(2,( "in oplock break state.\n"));
+
+ push_oplock_pending_smb_message(inbuf, length);
+ return -1;
+ }
+
+ new_fsp = open_file_shared(conn, fname, &sbuf,
+ SET_OPEN_MODE(DOS_OPEN_RDWR),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ 0, 0, &access_mode, &action);
+
+ if (new_fsp == NULL)
+ return(UNIXERROR(ERRDOS,ERRbadpath));
+ ret = vfs_allocate_file_space(new_fsp, size);
+ close_file(new_fsp,True);
+ } else {
+ ret = vfs_allocate_file_space(fsp, size);
+ }
+ if (ret == -1)
+ return allocate_space_error(inbuf, outbuf, errno);
+
+ sbuf.st_size = size;
+ }
+
break;
}
+ case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_SET_FILE_END_OF_FILE_INFO:
{
size = IVAL(pdata,0);
@@ -1958,6 +1980,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
break;
}
+ case SMB_FILE_DISPOSITION_INFORMATION:
case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
{
BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
@@ -2144,7 +2167,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
vfs_set_filelen(new_fsp, size);
close_file(new_fsp,True);
} else {
- vfs_set_filelen(fsp, size);
+ vfs_set_filelen(fsp, size);
}
}
@@ -2351,8 +2374,9 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf,
}
/****************************************************************************
- reply to a SMBfindclose (stop trans2 directory search)
+ Reply to a SMBfindclose (stop trans2 directory search).
****************************************************************************/
+
int reply_findclose(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -2373,8 +2397,9 @@ int reply_findclose(connection_struct *conn,
}
/****************************************************************************
- reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
+ Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
****************************************************************************/
+
int reply_findnclose(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
@@ -2398,10 +2423,10 @@ int reply_findnclose(connection_struct *conn,
return(outsize);
}
-
/****************************************************************************
- reply to a SMBtranss2 - just ignore it!
+ Reply to a SMBtranss2 - just ignore it!
****************************************************************************/
+
int reply_transs2(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index da4c5383197..54ced5a8239 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -127,8 +127,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
if (conn->force_user ||
conn->admin_user ||
- lp_security() == SEC_SHARE ||
- !(vuser) || (vuser->guest)) {
+ (lp_security() == SEC_SHARE)) {
uid = conn->uid;
gid = conn->gid;
current_user.groups = conn->groups;
@@ -280,7 +279,9 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
fstring sid;
char *sep = lp_winbind_separator();
- if (!winbind_lookup_name(name, psid, name_type)) {
+ *name_type = SID_NAME_UNKNOWN;
+
+ if (!winbind_lookup_name(name, psid, name_type) || (*name_type != SID_NAME_USER) ) {
BOOL ret;
DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name));
@@ -296,21 +297,19 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
- if (strequal(domain, global_myworkgroup))
+ if (strequal(domain, global_myworkgroup)) {
fstrcpy(domain, global_myname);
+ ret = local_lookup_name(domain, username, psid, name_type);
+ }
/* No break is deliberate here. JRA. */
default:
if (strcasecmp(global_myname, domain) != 0) {
- DEBUG(5, ("domain %s is not local\n", domain));
- return False;
+ DEBUG(5, ("lookup_name: domain %s is not local\n", domain));
+ ret = local_lookup_name(global_myname, username, psid, name_type);
}
}
-
- ret = local_lookup_name(domain, username, psid,
- name_type);
} else {
- ret = local_lookup_name(global_myname, name, psid,
- name_type);
+ ret = local_lookup_name(global_myname, name, psid, name_type);
}
if (ret) {
@@ -325,9 +324,9 @@ BOOL lookup_name(const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
return ret;
}
- DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n",
- name, sid_to_string(sid, psid),
- (unsigned int)*name_type));
+ DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n",
+ name, sid_to_string(sid, psid),
+ (unsigned int)*name_type));
return True;
}
@@ -341,6 +340,8 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE
if (!name_type)
return False;
+ *name_type = SID_NAME_UNKNOWN;
+
/* Check if this is our own sid. This should perhaps be done by
winbind? For the moment handle it here. */
@@ -421,7 +422,7 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
*THE CANONICAL* convert SID to uid function.
Tries winbind first - then uses local lookup.
Returns True if this name is a user sid and the conversion
- was done correctly, False if not.
+ was done correctly, False if not. sidtype is set by this function.
*****************************************************************/
BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
@@ -435,7 +436,7 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
* First we must look up the name and decide if this is a user sid.
*/
- if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
+ if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) {
DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n",
sid_to_string(sid_str, psid) ));
diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c
index 058b02b5ac1..8e579634249 100644
--- a/source/smbd/vfs-wrap.c
+++ b/source/smbd/vfs-wrap.c
@@ -190,7 +190,7 @@ int vfswrap_close(files_struct *fsp, int fd)
return result;
}
-ssize_t vfswrap_read(files_struct *fsp, int fd, char *data, size_t n)
+ssize_t vfswrap_read(files_struct *fsp, int fd, void *data, size_t n)
{
ssize_t result;
@@ -207,7 +207,7 @@ ssize_t vfswrap_read(files_struct *fsp, int fd, char *data, size_t n)
return result;
}
-ssize_t vfswrap_write(files_struct *fsp, int fd, char *data, size_t n)
+ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n)
{
ssize_t result;
@@ -235,21 +235,104 @@ SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int wh
return result;
}
-int vfswrap_rename(connection_struct *conn, char *old, char *new)
+/*********************************************************
+ For rename across filesystems Patch from Warren Birnbaum
+ <warrenb@hpcvscdp.cv.hp.com>
+**********************************************************/
+
+static int copy_reg(char *source, const char *dest)
{
- int result;
+ SMB_STRUCT_STAT source_stats;
+ int ifd;
+ int ofd;
+
+ if (sys_lstat (source, &source_stats) == -1)
+ return -1;
+
+ if (!S_ISREG (source_stats.st_mode))
+ return -1;
+
+ if (unlink (dest) && errno != ENOENT)
+ return -1;
+
+ if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
+ return -1;
+
+ if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 ) {
+ int saved_errno = errno;
+ close (ifd);
+ errno = saved_errno;
+ return -1;
+ }
+
+ if (transfer_file(ifd, ofd, (size_t)-1) == -1) {
+ int saved_errno = errno;
+ close (ifd);
+ close (ofd);
+ unlink (dest);
+ errno = saved_errno;
+ return -1;
+ }
+
+ if (close (ifd) == -1) {
+ int saved_errno = errno;
+ close (ofd);
+ errno = saved_errno;
+ return -1;
+ }
+ if (close (ofd) == -1)
+ return -1;
+
+ /*
+ * chown turns off set[ug]id bits for non-root,
+ * so do the chmod last.
+ */
+
+ /* Try to copy the old file's modtime and access time. */
+ {
+ struct utimbuf tv;
+
+ tv.actime = source_stats.st_atime;
+ tv.modtime = source_stats.st_mtime;
+ utime (dest, &tv);
+ }
+
+ /*
+ * Try to preserve ownership. For non-root it might fail, but that's ok.
+ * But root probably wants to know, e.g. if NFS disallows it.
+ */
+
+ if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
+ return -1;
- START_PROFILE(syscall_rename);
+ if (chmod (dest, source_stats.st_mode & 07777))
+ return -1;
+
+ if (unlink (source) == -1)
+ return -1;
+
+ return 0;
+}
+
+int vfswrap_rename(connection_struct *conn, char *oldname, char *newname)
+{
+ int result;
+
+ START_PROFILE(syscall_rename);
#ifdef VFS_CHECK_NULL
- if ((old == NULL) || (new == NULL)) {
- smb_panic("NULL pointer passed to vfswrap_rename()\n");
- }
+ if ((oldname == NULL) || (newname == NULL)) {
+ smb_panic("NULL pointer passed to vfswrap_rename()\n");
+ }
#endif
- result = rename(old, new);
- END_PROFILE(syscall_rename);
- return result;
+ result = rename(oldname, newname);
+ if (errno == EXDEV) {
+ /* Rename across filesystems needed. */
+ result = copy_reg(oldname, newname);
+ }
+ END_PROFILE(syscall_rename);
+ return result;
}
int vfswrap_fsync(files_struct *fsp, int fd)
@@ -591,30 +674,60 @@ int vfswrap_readlink(connection_struct *conn, const char *path, char *buf, size_
size_t vfswrap_fget_nt_acl(files_struct *fsp, int fd, SEC_DESC **ppdesc)
{
- return get_nt_acl(fsp, ppdesc);
+ size_t result;
+
+ START_PROFILE(fget_nt_acl);
+ result = get_nt_acl(fsp, ppdesc);
+ END_PROFILE(fget_nt_acl);
+ return result;
}
size_t vfswrap_get_nt_acl(files_struct *fsp, char *name, SEC_DESC **ppdesc)
{
- return get_nt_acl(fsp, ppdesc);
+ size_t result;
+
+ START_PROFILE(get_nt_acl);
+ result = get_nt_acl(fsp, ppdesc);
+ END_PROFILE(get_nt_acl);
+ return result;
}
BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
{
- return set_nt_acl(fsp, security_info_sent, psd);
+ BOOL result;
+
+ START_PROFILE(fset_nt_acl);
+ result = set_nt_acl(fsp, security_info_sent, psd);
+ END_PROFILE(fset_nt_acl);
+ return result;
}
BOOL vfswrap_set_nt_acl(files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd)
{
- return set_nt_acl(fsp, security_info_sent, psd);
+ BOOL result;
+
+ START_PROFILE(set_nt_acl);
+ result = set_nt_acl(fsp, security_info_sent, psd);
+ END_PROFILE(set_nt_acl);
+ return result;
}
int vfswrap_chmod_acl(connection_struct *conn, char *name, mode_t mode)
{
- return chmod_acl(name, mode);
+ int result;
+
+ START_PROFILE(chmod_acl);
+ result = chmod_acl(name, mode);
+ END_PROFILE(chmod_acl);
+ return result;
}
int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode)
{
- return fchmod_acl(fd, mode);
+ int result;
+
+ START_PROFILE(fchmod_acl);
+ result = fchmod_acl(fd, mode);
+ END_PROFILE(fchmod_acl);
+ return result;
}
diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c
index ac00d00e9e1..8d049b51c4a 100644
--- a/source/smbd/vfs.c
+++ b/source/smbd/vfs.c
@@ -415,110 +415,125 @@ ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N)
}
/****************************************************************************
- A vfs set_filelen call.
- set the length of a file from a filedescriptor.
+ An allocate file space call using the vfs interface.
+ Allocates space for a file from a filedescriptor.
Returns 0 on success, -1 on failure.
****************************************************************************/
-int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
+int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
{
int ret;
+ SMB_STRUCT_STAT st;
+ struct vfs_ops *vfs_ops = &fsp->conn->vfs_ops;
+ if (!lp_strict_allocate(SNUM(fsp->conn)))
+ return vfs_set_filelen(fsp, len);
+
release_level_2_oplocks_on_change(fsp);
- if ((ret = fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, len)) != -1) {
- set_filelen_write_cache(fsp, len);
+
+ /*
+ * Actually try and commit the space on disk....
+ */
+
+ DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len ));
+
+ ret = vfs_fstat(fsp,fsp->fd,&st);
+ if (ret == -1)
+ return ret;
+
+ if (len == st.st_size)
+ return 0;
+
+ if (len < st.st_size) {
+ /* Shrink - use ftruncate. */
+
+ DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
+ fsp->fsp_name, (double)st.st_size ));
+
+ if ((ret = vfs_ops->ftruncate(fsp, fsp->fd, len)) != -1) {
+ set_filelen_write_cache(fsp, len);
+ }
+ return ret;
}
- return ret;
-}
+ /* Grow - we need to write out the space.... */
+ {
+ static unsigned char zero_space[65536];
-/****************************************************************************
- Transfer some data between two file_struct's.
-****************************************************************************/
+ SMB_OFF_T start_pos = st.st_size;
+ SMB_OFF_T len_to_write = len - st.st_size;
+ SMB_OFF_T retlen;
-SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp,
- int out_fd, files_struct *out_fsp,
- SMB_OFF_T n, char *header, int headlen, int align)
-{
- static char *buf=NULL;
- static int size=0;
- char *buf1,*abuf;
- SMB_OFF_T total = 0;
+ DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f\n",
+ fsp->fsp_name, (double)st.st_size ));
- DEBUG(4,("vfs_transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
+ if ((retlen = vfs_ops->lseek(fsp, fsp->fd, start_pos, SEEK_SET)) != start_pos)
+ return -1;
- /* Check we have at least somewhere to read from */
+ while ( len_to_write > 0) {
+ SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),len_to_write);
- SMB_ASSERT((in_fd != -1) || (in_fsp != NULL));
+ retlen = vfs_ops->write(fsp,fsp->fd,(char *)zero_space,current_len_to_write);
+ if (retlen <= 0) {
+ /* Write fail - return to original size. */
+ int save_errno = errno;
+ fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, st.st_size);
+ errno = save_errno;
+ DEBUG(10,("vfs_allocate_file_space: file %s, grow. write fail %s\n",
+ fsp->fsp_name, strerror(errno) ));
+ return -1;
+ }
- if (size == 0) {
- size = lp_readsize();
- size = MAX(size,1024);
- }
+ DEBUG(10,("vfs_allocate_file_space: file %s, grow. wrote %.0f\n",
+ fsp->fsp_name, (double)retlen ));
- while (!buf && size>0) {
- buf = (char *)Realloc(buf,size+8);
- if (!buf) size /= 2;
- }
+ len_to_write -= retlen;
+ }
+ set_filelen_write_cache(fsp, len);
+ }
+ return 0;
+}
- if (!buf) {
- DEBUG(0,("Can't allocate transfer buffer!\n"));
- exit(1);
- }
+/****************************************************************************
+ A vfs set_filelen call.
+ set the length of a file from a filedescriptor.
+ Returns 0 on success, -1 on failure.
+****************************************************************************/
- abuf = buf + (align%8);
+int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
+{
+ int ret;
- if (header)
- n += headlen;
+ release_level_2_oplocks_on_change(fsp);
+ if ((ret = fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, len)) != -1)
+ set_filelen_write_cache(fsp, len);
- while (n > 0)
- {
- int s = (int)MIN(n,(SMB_OFF_T)size);
- int ret,ret2=0;
-
- ret = 0;
-
- if (header && (headlen >= MIN(s,1024))) {
- buf1 = header;
- s = headlen;
- ret = headlen;
- headlen = 0;
- header = NULL;
- } else {
- buf1 = abuf;
- }
+ return ret;
+}
- if (header && headlen > 0)
- {
- ret = MIN(headlen,size);
- memcpy(buf1,header,ret);
- headlen -= ret;
- header += ret;
- if (headlen <= 0) header = NULL;
- }
+/****************************************************************************
+ Transfer some data (n bytes) between two file_struct's.
+****************************************************************************/
- if (s > ret) {
- ret += in_fsp ?
- in_fsp->conn->vfs_ops.read(in_fsp,in_fsp->fd,buf1+ret,s-ret) : read(in_fd,buf1+ret,s-ret);
- }
+static files_struct *in_fsp;
+static files_struct *out_fsp;
- if (ret > 0) {
- if (out_fsp)
- ret2 = out_fsp->conn->vfs_ops.write(out_fsp,out_fsp->fd,buf1,ret);
- else
- ret2= (out_fd != -1) ? write_data(out_fd,buf1,ret) : ret;
- }
+static ssize_t read_fn(int fd, void *buf, size_t len)
+{
+ return in_fsp->conn->vfs_ops.read(in_fsp, fd, buf, len);
+}
+
+static ssize_t write_fn(int fd, const void *buf, size_t len)
+{
+ return out_fsp->conn->vfs_ops.write(out_fsp, fd, buf, len);
+}
- if (ret2 > 0) total += ret2;
- /* if we can't write then dump excess data */
- if (ret2 != ret)
- vfs_transfer_file(in_fd, in_fsp, -1,NULL,n-(ret+headlen),NULL,0,0);
+SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
+{
+ in_fsp = in;
+ out_fsp = out;
- if (ret <= 0 || ret2 != ret)
- return(total);
- n -= ret;
- }
- return(total);
+ return transfer_file_internal(in_fsp->fd, out_fsp->fd, n, read_fn, write_fn);
}
/*******************************************************************
diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c
index 7ee2d9af261..89cc6b84d9f 100644
--- a/source/smbwrapper/smbw.c
+++ b/source/smbwrapper/smbw.c
@@ -73,7 +73,7 @@ void smbw_init(void)
exit(1);
}
- charset_initialise();
+ charset_initialize();
in_client = True;
@@ -85,6 +85,8 @@ void smbw_init(void)
lp_load(servicesf,True,False,False);
+ charset_initialize();
+
get_myname(global_myname);
if ((p=smbw_getshared("DEBUG"))) {
diff --git a/source/smbwrapper/wrapped.c b/source/smbwrapper/wrapped.c
index 7b9100dd9ca..b8787a00c01 100644
--- a/source/smbwrapper/wrapped.c
+++ b/source/smbwrapper/wrapped.c
@@ -462,7 +462,7 @@
#endif
#ifdef HAVE_UTIMES
- int utimes(char *name,void *tvp)
+ int utimes(const char *name, const struct timeval *tvp)
{
if (smbw_path(name)) {
return smbw_utimes(name, tvp);
diff --git a/source/tdb/spinlock.c b/source/tdb/spinlock.c
index 731188a1530..0a68981ca2f 100644
--- a/source/tdb/spinlock.c
+++ b/source/tdb/spinlock.c
@@ -1,3 +1,23 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ Samba database functions
+ Copyright (C) Anton Blanchard 2001
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
#if STANDALONE
#if HAVE_CONFIG_H
#include <config.h>
@@ -41,6 +61,7 @@ static inline int __spin_trylock(spinlock_t *lock)
static inline void __spin_unlock(spinlock_t *lock)
{
+ asm volatile("":::"memory");
*lock = 0;
}
@@ -58,27 +79,27 @@ static inline int __spin_is_locked(spinlock_t *lock)
static inline int __spin_trylock(spinlock_t *lock)
{
- int result;
-
- __asm__ __volatile__ (
- " eieio;"
- "0: lwarx %0,0,%1;"
- " cmpwi 0,%0,0;"
- " bne- 1f;"
- " stwcx. %2,0,%1;"
- " bne- 0b;"
- " sync;"
- "1:"
- : "=&r"(result)
- : "r"(lock), "r"(1)
- : "cr0", "memory");
+ unsigned int result;
- return (result == 0) ? 0 : EBUSY;
+ __asm__ __volatile__(
+"1: lwarx %0,0,%1\n\
+ cmpwi 0,%0,0\n\
+ li %0,0\n\
+ bne- 2f\n\
+ li %0,1\n\
+ stwcx. %0,0,%1\n\
+ bne- 1b\n\
+ isync\n\
+2:" : "=&r"(result)
+ : "r"(lock)
+ : "cr0", "memory");
+
+ return (result == 1) ? 0 : EBUSY;
}
static inline void __spin_unlock(spinlock_t *lock)
{
- asm volatile("sync");
+ asm volatile("eieio":::"memory");
*lock = 0;
}
@@ -100,12 +121,15 @@ static inline int __spin_trylock(spinlock_t *lock)
asm volatile("xchgl %0,%1"
: "=r" (oldval), "=m" (*lock)
- : "0" (0));
+ : "0" (0)
+ : "memory");
+
return oldval > 0 ? 0 : EBUSY;
}
static inline void __spin_unlock(spinlock_t *lock)
{
+ asm volatile("":::"memory");
*lock = 1;
}
@@ -152,11 +176,14 @@ static inline int __spin_trylock(spinlock_t *lock)
return EBUSY;
} while (!store_conditional(lock, 1));
+ asm volatile("":::"memory");
+
return 0;
}
static inline void __spin_unlock(spinlock_t *lock)
{
+ asm volatile("":::"memory");
*lock = 0;
}
@@ -216,7 +243,7 @@ static inline void __spin_lock(spinlock_t *lock)
}
}
-static void __read_lock(rwlock_t *rwlock)
+static void __read_lock(tdb_rwlock_t *rwlock)
{
int ntries = 0;
@@ -239,7 +266,7 @@ static void __read_lock(rwlock_t *rwlock)
}
}
-static void __write_lock(rwlock_t *rwlock)
+static void __write_lock(tdb_rwlock_t *rwlock)
{
int ntries = 0;
@@ -262,7 +289,7 @@ static void __write_lock(rwlock_t *rwlock)
}
}
-static void __write_unlock(rwlock_t *rwlock)
+static void __write_unlock(tdb_rwlock_t *rwlock)
{
__spin_lock(&rwlock->lock);
@@ -275,7 +302,7 @@ static void __write_unlock(rwlock_t *rwlock)
__spin_unlock(&rwlock->lock);
}
-static void __read_unlock(rwlock_t *rwlock)
+static void __read_unlock(tdb_rwlock_t *rwlock)
{
__spin_lock(&rwlock->lock);
@@ -296,10 +323,10 @@ static void __read_unlock(rwlock_t *rwlock)
/* lock a list in the database. list -1 is the alloc list */
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type)
{
- rwlock_t *rwlocks;
+ tdb_rwlock_t *rwlocks;
if (!tdb->map_ptr) return -1;
- rwlocks = (rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
+ rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
switch(rw_type) {
case F_RDLCK:
@@ -319,10 +346,10 @@ int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type)
/* unlock the database. */
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type)
{
- rwlock_t *rwlocks;
+ tdb_rwlock_t *rwlocks;
if (!tdb->map_ptr) return -1;
- rwlocks = (rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
+ rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
switch(rw_type) {
case F_RDLCK:
@@ -343,9 +370,9 @@ int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type)
int tdb_create_rwlocks(int fd, unsigned int hash_size)
{
unsigned size, i;
- rwlock_t *rwlocks;
+ tdb_rwlock_t *rwlocks;
- size = (hash_size + 1) * sizeof(rwlock_t);
+ size = (hash_size + 1) * sizeof(tdb_rwlock_t);
rwlocks = malloc(size);
if (!rwlocks)
return -1;
@@ -367,14 +394,14 @@ int tdb_create_rwlocks(int fd, unsigned int hash_size)
int tdb_clear_spinlocks(TDB_CONTEXT *tdb)
{
- rwlock_t *rwlocks;
+ tdb_rwlock_t *rwlocks;
unsigned i;
if (tdb->header.rwlocks == 0) return 0;
if (!tdb->map_ptr) return -1;
/* We're mmapped here */
- rwlocks = (rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
+ rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
for(i = 0; i < tdb->header.hash_size+1; i++) {
__spin_lock_init(&rwlocks[i].lock);
rwlocks[i].count = 0;
diff --git a/source/tdb/spinlock.h b/source/tdb/spinlock.h
index a0dd9cbca5c..d6a2ac6eb88 100644
--- a/source/tdb/spinlock.h
+++ b/source/tdb/spinlock.h
@@ -32,7 +32,7 @@ typedef volatile unsigned long spinlock_t;
typedef struct {
spinlock_t lock;
volatile int count;
-} rwlock_t;
+} tdb_rwlock_t;
int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index c3ded6368b7..4f895ae6cd2 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -78,14 +78,21 @@ static TDB_CONTEXT *tdbs = NULL;
static void tdb_munmap(TDB_CONTEXT *tdb)
{
+ if (tdb->flags & TDB_INTERNAL)
+ return;
+
#ifdef HAVE_MMAP
- if (tdb->map_ptr) munmap(tdb->map_ptr, tdb->map_size);
+ if (tdb->map_ptr)
+ munmap(tdb->map_ptr, tdb->map_size);
#endif
tdb->map_ptr = NULL;
}
static void tdb_mmap(TDB_CONTEXT *tdb)
{
+ if (tdb->flags & TDB_INTERNAL)
+ return;
+
#ifdef HAVE_MMAP
if (!(tdb->flags & TDB_NOMMAP)) {
tdb->map_ptr = mmap(NULL, tdb->map_size,
@@ -101,6 +108,8 @@ static void tdb_mmap(TDB_CONTEXT *tdb)
TDB_LOG((tdb, 2, "tdb_mmap failed for size %d (%s)\n",
tdb->map_size, strerror(errno)));
}
+ } else {
+ tdb->map_ptr = NULL;
}
#else
tdb->map_ptr = NULL;
@@ -111,7 +120,8 @@ static void tdb_mmap(TDB_CONTEXT *tdb)
static void *convert(void *buf, u32 size)
{
u32 i, *p = buf;
- for (i = 0; i < size / 4; i++) p[i] = TDB_BYTEREV(p[i]);
+ for (i = 0; i < size / 4; i++)
+ p[i] = TDB_BYTEREV(p[i]);
return buf;
}
#define DOCONV() (tdb->flags & TDB_CONVERT)
@@ -127,14 +137,15 @@ struct list_struct {
u32 full_hash; /* the full 32 bit hash of the key */
u32 magic; /* try to catch errors */
/* the following union is implied:
- union {
- char record[rec_len];
- struct {
- char key[key_len];
- char data[data_len];
- }
- u32 totalsize; (tailer)
- } */
+ union {
+ char record[rec_len];
+ struct {
+ char key[key_len];
+ char data[data_len];
+ }
+ u32 totalsize; (tailer)
+ }
+ */
};
/* a byte range locking function - return 0 on success
@@ -144,8 +155,10 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
{
struct flock fl;
- if (tdb->flags & TDB_NOLOCK) return 0;
- if (tdb->read_only) return -1;
+ if (tdb->flags & TDB_NOLOCK)
+ return 0;
+ if (tdb->read_only)
+ return -1;
fl.l_type = rw_type;
fl.l_whence = SEEK_SET;
@@ -171,7 +184,8 @@ static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype)
list, ltype));
return -1;
}
- if (tdb->flags & TDB_NOLOCK) return 0;
+ if (tdb->flags & TDB_NOLOCK)
+ return 0;
/* Since fcntl locks don't nest, we do a lock for the first one,
and simply bump the count for future ones */
@@ -196,16 +210,21 @@ static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype)
/* unlock the database: returns void because it's too late for errors. */
static void tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype)
{
- if (tdb->flags & TDB_NOLOCK) return;
+ if (tdb->flags & TDB_NOLOCK)
+ return;
/* Sanity checks */
- if (list < -1 || list >= (int)tdb->header.hash_size) return;
- if (tdb->locked[list+1].count==0) return;
+ if (list < -1 || list >= (int)tdb->header.hash_size)
+ return;
+ if (tdb->locked[list+1].count==0)
+ return;
if (tdb->locked[list+1].count == 1) {
/* Down to last nested lock: unlock underneath */
- if (tdb->header.rwlocks) tdb_spinunlock(tdb, list, ltype);
- else tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0);
+ if (tdb->header.rwlocks)
+ tdb_spinunlock(tdb, list, ltype);
+ else
+ tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0);
}
tdb->locked[list+1].count--;
}
@@ -231,10 +250,14 @@ static u32 tdb_hash(TDB_DATA *key)
static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe)
{
struct stat st;
- if (len <= tdb->map_size) return 0;
- if (tdb->flags & TDB_INTERNAL) return 0;
+ if (len <= tdb->map_size)
+ return 0;
+ if (tdb->flags & TDB_INTERNAL)
+ return 0;
+
+ if (fstat(tdb->fd, &st) == -1)
+ return TDB_ERRCODE(TDB_ERR_IO, -1);
- fstat(tdb->fd, &st);
if (st.st_size < (size_t)len) {
if (!probe) {
TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n",
@@ -253,11 +276,17 @@ static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe)
/* write a lump of data at a specified offset */
static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len)
{
- if (tdb_oob(tdb, off + len, 0) != 0) return -1;
+ if (tdb_oob(tdb, off + len, 0) != 0)
+ return -1;
- if (tdb->map_ptr) memcpy(off + (char *)tdb->map_ptr, buf, len);
+ if (tdb->map_ptr)
+ memcpy(off + (char *)tdb->map_ptr, buf, len);
+#ifdef HAVE_PWRITE
+ else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) {
+#else
else if (lseek(tdb->fd, off, SEEK_SET) != off
|| write(tdb->fd, buf, len) != (ssize_t)len) {
+#endif
TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n",
off, len, strerror(errno)));
return TDB_ERRCODE(TDB_ERR_IO, -1);
@@ -268,16 +297,23 @@ static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len)
/* read a lump of data at a specified offset, maybe convert */
static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv)
{
- if (tdb_oob(tdb, off + len, 0) != 0) return -1;
+ if (tdb_oob(tdb, off + len, 0) != 0)
+ return -1;
- if (tdb->map_ptr) memcpy(buf, off + (char *)tdb->map_ptr, len);
+ if (tdb->map_ptr)
+ memcpy(buf, off + (char *)tdb->map_ptr, len);
+#ifdef HAVE_PREAD
+ else if (pread(tdb->fd, buf, len, off) != (ssize_t)len) {
+#else
else if (lseek(tdb->fd, off, SEEK_SET) != off
|| read(tdb->fd, buf, len) != (ssize_t)len) {
+#endif
TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n",
off, len, strerror(errno)));
return TDB_ERRCODE(TDB_ERR_IO, -1);
}
- if (cv) convert(buf, len);
+ if (cv)
+ convert(buf, len);
return 0;
}
@@ -312,7 +348,8 @@ static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d)
/* read/write a record */
static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
{
- if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) return -1;
+ if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1)
+ return -1;
if (TDB_BAD_MAGIC(rec)) {
TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset));
return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
@@ -328,13 +365,15 @@ static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
/* read a freelist record and check for simple errors */
static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec)
{
- if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) return -1;
+ if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1)
+ return -1;
if (rec->magic != TDB_FREE_MAGIC) {
TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n",
rec->magic, off));
return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
}
- if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) return -1;
+ if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0)
+ return -1;
return 0;
}
@@ -389,7 +428,8 @@ static void tdb_dump_chain(TDB_CONTEXT *tdb, int i)
return;
}
- if (rec_ptr) printf("hash=%d\n", i);
+ if (rec_ptr)
+ printf("hash=%d\n", i);
while (rec_ptr) {
rec_ptr = tdb_dump_record(tdb, rec_ptr);
@@ -473,7 +513,8 @@ static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
tdb_off right, left;
/* Allocation and tailer lock */
- if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1;
+ if (tdb_lock(tdb, -1, F_WRLCK) != 0)
+ return -1;
/* set an initial tailer, so if we fail we don't leave a bogus record */
update_tailer(tdb, offset, rec);
@@ -569,26 +610,39 @@ static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition)
}
#else
char b = 0;
+
+#ifdef HAVE_PWRITE
+ if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) {
+#else
if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 ||
write(tdb->fd, &b, 1) != 1) {
+#endif
TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n",
size+addition, strerror(errno)));
return -1;
}
#endif
+
/* now fill the file with something. This ensures that the file isn't sparse, which would be
very bad if we ran out of disk. This must be done with write, not via mmap */
memset(buf, 0x42, sizeof(buf));
- if (lseek(tdb->fd, size, SEEK_SET) != size) return -1;
while (addition) {
int n = addition>sizeof(buf)?sizeof(buf):addition;
- int ret = write(tdb->fd, buf, n);
+#ifdef HAVE_PWRITE
+ int ret = pwrite(tdb->fd, buf, n, size);
+#else
+ int ret;
+ if (lseek(tdb->fd, size, SEEK_SET) != size)
+ return -1;
+ ret = write(tdb->fd, buf, n);
+#endif
if (ret != n) {
TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n",
n, strerror(errno)));
return -1;
}
addition -= n;
+ size += n;
}
return 0;
}
@@ -603,7 +657,7 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size)
if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
TDB_LOG((tdb, 0, "lock failed in tdb_expand\n"));
- return 0;
+ return -1;
}
/* must know about any previous expansions by another process */
@@ -624,22 +678,24 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size)
/* expand the file itself */
if (!(tdb->flags & TDB_INTERNAL)) {
- if (expand_file(tdb, tdb->map_size, size) != 0) goto fail;
+ if (expand_file(tdb, tdb->map_size, size) != 0)
+ goto fail;
}
tdb->map_size += size;
if (tdb->flags & TDB_INTERNAL)
tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size);
+ else {
+ /*
+ * We must ensure the file is remapped before adding the space
+ * to ensure consistency with systems like OpenBSD where
+ * writes and mmaps are not consistent.
+ */
- /*
- * We must ensure the file is remapped before adding the space
- * to ensure consistency with systems like OpenBSD where
- * writes and mmaps are not consistent.
- */
-
- /* We're ok if the mmap fails as we'll fallback to read/write */
- tdb_mmap(tdb);
+ /* We're ok if the mmap fails as we'll fallback to read/write */
+ tdb_mmap(tdb);
+ }
/* form a new freelist record */
memset(&rec,'\0',sizeof(rec));
@@ -647,7 +703,8 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size)
/* link it into the free list */
offset = tdb->map_size - size;
- if (tdb_free(tdb, offset, &rec) == -1) goto fail;
+ if (tdb_free(tdb, offset, &rec) == -1)
+ goto fail;
tdb_unlock(tdb, -1, F_WRLCK);
return 0;
@@ -668,7 +725,8 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length,
tdb_off rec_ptr, last_ptr, newrec_ptr;
struct list_struct newrec;
- if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0;
+ if (tdb_lock(tdb, -1, F_WRLCK) == -1)
+ return 0;
/* Extra bytes required for tailer */
length += sizeof(tdb_off);
@@ -677,11 +735,13 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length,
last_ptr = FREELIST_TOP;
/* read in the freelist top */
- if (ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) goto fail;
+ if (ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1)
+ goto fail;
/* keep looking until we find a freelist record big enough */
while (rec_ptr) {
- if (rec_free_read(tdb, rec_ptr, rec) == -1) goto fail;
+ if (rec_free_read(tdb, rec_ptr, rec) == -1)
+ goto fail;
if (rec->rec_len >= length) {
/* found it - now possibly split it up */
@@ -733,7 +793,8 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length,
}
/* we didn't find enough space. See if we can expand the
database and if we can then try again */
- if (tdb_expand(tdb, length + sizeof(*rec)) == 0) goto again;
+ if (tdb_expand(tdb, length + sizeof(*rec)) == 0)
+ goto again;
fail:
tdb_unlock(tdb, -1, F_WRLCK);
return 0;
@@ -743,15 +804,16 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length,
static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size)
{
struct tdb_header *newdb;
- int size, ret;
+ int size, ret = -1;
/* We make it up in memory, then write it out if not internal */
size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off);
- if (!(newdb = calloc(size, 1))) return TDB_ERRCODE(TDB_ERR_OOM, -1);
+ if (!(newdb = calloc(size, 1)))
+ return TDB_ERRCODE(TDB_ERR_OOM, -1);
- /* Fill in the header */
- newdb->version = TDB_VERSION;
- newdb->hash_size = hash_size;
+ /* Fill in the header */
+ newdb->version = TDB_VERSION;
+ newdb->hash_size = hash_size;
#ifdef USE_SPINLOCKS
newdb->rwlocks = size;
#endif
@@ -763,16 +825,23 @@ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size)
CONVERT(*newdb);
return 0;
}
- lseek(tdb->fd, 0, SEEK_SET);
- ftruncate(tdb->fd, 0);
+ if (lseek(tdb->fd, 0, SEEK_SET) == -1)
+ goto fail;
+
+ if (ftruncate(tdb->fd, 0) == -1)
+ goto fail;
+
/* This creates an endian-converted header, as if read from disk */
CONVERT(*newdb);
memcpy(&tdb->header, newdb, sizeof(tdb->header));
/* Don't endian-convert the magic food! */
memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
- if (write(tdb->fd, newdb, size) != size) ret = -1;
- else ret = tdb_create_rwlocks(tdb->fd, hash_size);
+ if (write(tdb->fd, newdb, size) != size)
+ ret = -1;
+ else
+ ret = tdb_create_rwlocks(tdb->fd, hash_size);
+ fail:
free(newdb);
return ret;
}
@@ -785,18 +854,21 @@ static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash,
tdb_off rec_ptr;
/* read in the hash top */
- if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) return 0;
+ if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
+ return 0;
/* keep looking until we find the right record */
while (rec_ptr) {
- if (rec_read(tdb, rec_ptr, r) == -1) return 0;
+ if (rec_read(tdb, rec_ptr, r) == -1)
+ return 0;
if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) {
char *k;
/* a very likely hit - read the key */
k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r),
r->key_len);
- if (!k) return 0;
+ if (!k)
+ return 0;
if (memcmp(key.dptr, k, key.dsize) == 0) {
free(k);
@@ -813,9 +885,11 @@ static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash,
static int tdb_keylocked(TDB_CONTEXT *tdb, u32 hash)
{
u32 i;
- if (!tdb->lockedkeys) return 1;
+ if (!tdb->lockedkeys)
+ return 1;
for (i = 0; i < tdb->lockedkeys[0]; i++)
- if (tdb->lockedkeys[i+1] == hash) return 1;
+ if (tdb->lockedkeys[i+1] == hash)
+ return 1;
return TDB_ERRCODE(TDB_ERR_NOLOCK, 0);
}
@@ -826,8 +900,10 @@ static tdb_off tdb_find_lock(TDB_CONTEXT *tdb, TDB_DATA key, int locktype,
u32 hash, rec_ptr;
hash = tdb_hash(&key);
- if (!tdb_keylocked(tdb, hash)) return 0;
- if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) return 0;
+ if (!tdb_keylocked(tdb, hash))
+ return 0;
+ if (tdb_lock(tdb, BUCKET(hash), locktype) == -1)
+ return 0;
if (!(rec_ptr = tdb_find(tdb, key, hash, rec)))
tdb_unlock(tdb, BUCKET(hash), locktype);
return rec_ptr;
@@ -854,7 +930,8 @@ const char *tdb_errorstr(TDB_CONTEXT *tdb)
{
u32 i;
for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++)
- if (tdb->ecode == emap[i].ecode) return emap[i].estring;
+ if (tdb->ecode == emap[i].ecode)
+ return emap[i].estring;
return "Invalid error code";
}
@@ -869,10 +946,14 @@ static int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
int ret = -1;
/* find entry */
- if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec))) return -1;
+ if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec)))
+ return -1;
/* must be long enough key, data and tailer */
- if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off)) goto out;
+ if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off)) {
+ tdb->ecode = TDB_SUCCESS; /* Not really an error */
+ goto out;
+ }
if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len,
dbuf.dptr, dbuf.dsize) == -1)
@@ -882,8 +963,8 @@ static int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
/* update size */
rec.data_len = dbuf.dsize;
ret = rec_write(tdb, rec_ptr, &rec);
- }
- else ret = 0;
+ } else
+ ret = 0;
out:
tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK);
return ret;
@@ -897,7 +978,8 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
TDB_DATA ret;
/* find which hash bucket it is in */
- if (!(rec_ptr = tdb_find_lock(tdb,key,F_RDLCK,&rec))) return tdb_null;
+ if (!(rec_ptr = tdb_find_lock(tdb,key,F_RDLCK,&rec)))
+ return tdb_null;
ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len,
rec.data_len);
@@ -916,7 +998,8 @@ int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
{
struct list_struct rec;
- if (tdb_find_lock(tdb, key, F_RDLCK, &rec) == 0) return 0;
+ if (tdb_find_lock(tdb, key, F_RDLCK, &rec) == 0)
+ return 0;
tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
return 1;
}
@@ -926,13 +1009,26 @@ static int lock_record(TDB_CONTEXT *tdb, tdb_off off)
{
return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0;
}
-/* write locks override our own fcntl readlocks, so check it here */
+/*
+ Write locks override our own fcntl readlocks, so check it here.
+ Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not
+ an error to fail to get the lock here.
+*/
+
static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off)
{
struct tdb_traverse_lock *i;
- for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) return -1;
+ for (i = &tdb->travlocks; i; i = i->next)
+ if (i->off == off)
+ return -1;
return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1);
}
+
+/*
+ Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not
+ an error to fail to get the lock here.
+*/
+
static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off)
{
return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0);
@@ -943,8 +1039,11 @@ static int unlock_record(TDB_CONTEXT *tdb, tdb_off off)
struct tdb_traverse_lock *i;
u32 count = 0;
- if (off == 0) return 0;
- for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) count++;
+ if (off == 0)
+ return 0;
+ for (i = &tdb->travlocks; i; i = i->next)
+ if (i->off == off)
+ count++;
return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0) : 0);
}
@@ -964,16 +1063,21 @@ static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec)
write_unlock_record(tdb, rec_ptr);
/* find previous record in hash chain */
- if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) return -1;
+ if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1)
+ return -1;
for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next)
- if (rec_read(tdb, i, &lastrec) == -1) return -1;
+ if (rec_read(tdb, i, &lastrec) == -1)
+ return -1;
/* unlink it: next ptr is at start of record. */
- if (last_ptr == 0) last_ptr = TDB_HASH_TOP(rec->full_hash);
- if (ofs_write(tdb, last_ptr, &rec->next) == -1) return -1;
+ if (last_ptr == 0)
+ last_ptr = TDB_HASH_TOP(rec->full_hash);
+ if (ofs_write(tdb, last_ptr, &rec->next) == -1)
+ return -1;
/* recover the space */
- if (tdb_free(tdb, rec_ptr, rec) == -1) return -1;
+ if (tdb_free(tdb, rec_ptr, rec) == -1)
+ return -1;
return 0;
}
@@ -984,11 +1088,13 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock,
int want_next = (tlock->off != 0);
/* No traversal allows if you've called tdb_lockkeys() */
- if (tdb->lockedkeys) return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ if (tdb->lockedkeys)
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
/* Lock each chain from the start one. */
for (; tlock->hash < tdb->header.hash_size; tlock->hash++) {
- if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1) return -1;
+ if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1)
+ return -1;
/* No previous record? Start at top of chain. */
if (!tlock->off) {
@@ -1002,14 +1108,16 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock,
if (want_next) {
/* We have offset of old record: grab next */
- if (rec_read(tdb, tlock->off, rec) == -1) goto fail;
+ if (rec_read(tdb, tlock->off, rec) == -1)
+ goto fail;
tlock->off = rec->next;
}
/* Iterate through chain */
while( tlock->off) {
tdb_off current;
- if (rec_read(tdb, tlock->off, rec) == -1) goto fail;
+ if (rec_read(tdb, tlock->off, rec) == -1)
+ goto fail;
if (!TDB_DEAD(rec)) {
/* Woohoo: we found one! */
lock_record(tdb, tlock->off);
@@ -1096,7 +1204,8 @@ TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb)
unlock_record(tdb, tdb->travlocks.off);
tdb->travlocks.off = tdb->travlocks.hash = 0;
- if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) return tdb_null;
+ if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0)
+ return tdb_null;
/* now read the key */
key.dsize = rec.key_len;
key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize);
@@ -1114,7 +1223,8 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
/* Is locked key the old key? If so, traverse will be reliable. */
if (tdb->travlocks.off) {
- if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK)) return tdb_null;
+ if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK))
+ return tdb_null;
if (rec_read(tdb, tdb->travlocks.off, &rec) == -1
|| !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),
rec.key_len))
@@ -1132,7 +1242,8 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
if (!tdb->travlocks.off) {
/* No previous element: do normal find, and lock record */
tdb->travlocks.off = tdb_find_lock(tdb, oldkey, F_WRLCK, &rec);
- if (!tdb->travlocks.off) return tdb_null;
+ if (!tdb->travlocks.off)
+ return tdb_null;
tdb->travlocks.hash = BUCKET(rec.full_hash);
lock_record(tdb, tdb->travlocks.off);
}
@@ -1159,7 +1270,8 @@ int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
struct list_struct rec;
int ret;
- if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec))) return -1;
+ if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec)))
+ return -1;
ret = do_delete(tdb, rec_ptr, &rec);
tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK);
return ret;
@@ -1180,8 +1292,10 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
/* find which hash bucket it is in */
hash = tdb_hash(&key);
- if (!tdb_keylocked(tdb, hash)) return -1;
- if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) return -1;
+ if (!tdb_keylocked(tdb, hash))
+ return -1;
+ if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
+ return -1;
/* check for it existing, on insert. */
if (flag == TDB_INSERT) {
@@ -1191,7 +1305,8 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
}
} else {
/* first try in-place update, on modify or replace. */
- if (tdb_update(tdb, key, dbuf) == 0) goto out;
+ if (tdb_update(tdb, key, dbuf) == 0)
+ goto out;
if (flag == TDB_MODIFY && tdb->ecode == TDB_ERR_NOEXIST)
goto fail;
}
@@ -1201,7 +1316,8 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
/* delete any existing record - if it doesn't exist we don't
care. Doing this first reduces fragmentation, and avoids
coalescing with `allocated' block before it's updated. */
- if (flag != TDB_INSERT) tdb_delete(tdb, key);
+ if (flag != TDB_INSERT)
+ tdb_delete(tdb, key);
/* Copy key+value *before* allocating free space in case malloc
fails and we are left with a dead spot in the tdb. */
@@ -1221,7 +1337,8 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
goto fail;
/* Read hash top into next ptr */
- if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) goto fail;
+ if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1)
+ goto fail;
rec.key_len = key.dsize;
rec.data_len = dbuf.dsize;
@@ -1263,13 +1380,17 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
tdb.map_ptr = NULL;
tdb.lockedkeys = NULL;
tdb.flags = tdb_flags;
+ tdb.open_flags = open_flags;
- if ((open_flags & O_ACCMODE) == O_WRONLY) goto fail;
- if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE;
+ if ((open_flags & O_ACCMODE) == O_WRONLY)
+ goto fail;
+ if (hash_size == 0)
+ hash_size = DEFAULT_HASH_SIZE;
if ((open_flags & O_ACCMODE) == O_RDONLY) {
tdb.read_only = 1;
- /* read only databases don't do locking */
+ /* read only databases don't do locking or clear if first */
tdb.flags |= TDB_NOLOCK;
+ tdb.flags &= ~TDB_CLEAR_IF_FIRST;
}
/* internal databases don't mmap or lock, and start off cleared */
@@ -1280,16 +1401,19 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
goto internal;
}
- if ((tdb.fd = open(name, open_flags, mode)) == -1) goto fail;
+ if ((tdb.fd = open(name, open_flags, mode)) == -1)
+ goto fail;
/* ensure there is only one process initialising at once */
- tdb_brlock(&tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0);
-
+ if (tdb_brlock(&tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1)
+ goto fail;
+
/* we need to zero database if we are the only one with it open */
if ((locked = (tdb_brlock(&tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))
&& (tdb_flags & TDB_CLEAR_IF_FIRST)) {
open_flags |= O_CREAT;
- ftruncate(tdb.fd, 0);
+ if (ftruncate(tdb.fd, 0) == -1)
+ goto fail;
}
if (read(tdb.fd, &tdb.header, sizeof(tdb.header)) != sizeof(tdb.header)
@@ -1297,16 +1421,19 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
|| (tdb.header.version != TDB_VERSION
&& !(rev = (tdb.header.version==TDB_BYTEREV(TDB_VERSION))))) {
/* its not a valid database - possibly initialise it */
- if (!(open_flags & O_CREAT)
- || tdb_new_database(&tdb, hash_size) == -1) goto fail;
+ if (!(open_flags & O_CREAT) || tdb_new_database(&tdb, hash_size) == -1)
+ goto fail;
rev = (tdb.flags & TDB_CONVERT);
}
- if (!rev) tdb.flags &= ~TDB_CONVERT;
+ if (!rev)
+ tdb.flags &= ~TDB_CONVERT;
else {
tdb.flags |= TDB_CONVERT;
convert(&tdb.header, sizeof(tdb.header));
}
- fstat(tdb.fd, &st);
+ if (fstat(tdb.fd, &st) == -1)
+ goto fail;
+
/* Is it already in the open list? If so, fail. */
for (i = tdbs; i; i = i->next) {
if (i->device == st.st_dev && i->inode == st.st_ino) {
@@ -1318,31 +1445,47 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
/* map the database and fill in the return structure */
tdb.name = (char *)strdup(name);
+ if (!tdb.name)
+ goto fail;
tdb.map_size = st.st_size;
tdb.device = st.st_dev;
tdb.inode = st.st_ino;
- tdb.locked = calloc(tdb.header.hash_size+1, sizeof(tdb.locked[0]));
- if (!tdb.locked) goto fail;
+ tdb.locked = calloc(tdb.header.hash_size+1, sizeof(tdb.locked[0]));
+ if (!tdb.locked)
+ goto fail;
tdb_mmap(&tdb);
if (locked) {
tdb_clear_spinlocks(&tdb);
- tdb_brlock(&tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0);
+ if (tdb_brlock(&tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1)
+ goto fail;
}
/* leave this lock in place to indicate it's in use */
- tdb_brlock(&tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0);
+ if (tdb_brlock(&tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
+ goto fail;
internal:
- if (!(ret = malloc(sizeof(tdb)))) goto fail;
+ if (!(ret = malloc(sizeof(tdb))))
+ goto fail;
*ret = tdb;
- tdb_brlock(&tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0);
+ if (tdb_brlock(&tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1)
+ goto fail;
ret->next = tdbs;
tdbs = ret;
return ret;
fail:
- if (tdb.name) free(tdb.name);
- if (tdb.fd != -1) close(tdb.fd);
- tdb_munmap(&tdb);
+ if (tdb.map_ptr) {
+ if (tdb.flags & TDB_INTERNAL)
+ free(tdb.map_ptr);
+ else
+ tdb_munmap(&tdb);
+ }
+ if (tdb.name)
+ free(tdb.name);
+ if (tdb.fd != -1)
+ close(tdb.fd);
+ if (tdb.locked)
+ free(tdb.locked);
return NULL;
}
@@ -1353,15 +1496,19 @@ int tdb_close(TDB_CONTEXT *tdb)
int ret = 0;
if (tdb->map_ptr) {
- if (tdb->flags & TDB_INTERNAL) free(tdb->map_ptr);
- else tdb_munmap(tdb);
+ if (tdb->flags & TDB_INTERNAL)
+ free(tdb->map_ptr);
+ else
+ tdb_munmap(tdb);
}
- if (tdb->name) free(tdb->name);
- if (tdb->fd != -1) {
+ if (tdb->name)
+ free(tdb->name);
+ if (tdb->fd != -1)
ret = close(tdb->fd);
- }
- if (tdb->locked) free(tdb->locked);
- if (tdb->lockedkeys) free(tdb->lockedkeys);
+ if (tdb->locked)
+ free(tdb->locked);
+ if (tdb->lockedkeys)
+ free(tdb->lockedkeys);
/* Remove from contexts list */
for (i = &tdbs; *i; i = &(*i)->next) {
@@ -1383,8 +1530,10 @@ int tdb_lockall(TDB_CONTEXT *tdb)
u32 i;
/* There are no locks on read-only dbs */
- if (tdb->read_only) return TDB_ERRCODE(TDB_ERR_LOCK, -1);
- if (tdb->lockedkeys) return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ if (tdb->read_only)
+ return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ if (tdb->lockedkeys)
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
for (i = 0; i < tdb->header.hash_size; i++)
if (tdb_lock(tdb, i, F_WRLCK))
break;
@@ -1403,7 +1552,8 @@ int tdb_lockall(TDB_CONTEXT *tdb)
void tdb_unlockall(TDB_CONTEXT *tdb)
{
u32 i;
- for (i=0; i < tdb->header.hash_size; i++) tdb_unlock(tdb, i, F_WRLCK);
+ for (i=0; i < tdb->header.hash_size; i++)
+ tdb_unlock(tdb, i, F_WRLCK);
}
int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[])
@@ -1411,7 +1561,8 @@ int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[])
u32 i, j, hash;
/* Can't lock more keys if already locked */
- if (tdb->lockedkeys) return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ if (tdb->lockedkeys)
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
if (!(tdb->lockedkeys = malloc(sizeof(u32) * (number+1))))
return TDB_ERRCODE(TDB_ERR_OOM, -1);
/* First number in array is # keys */
@@ -1420,11 +1571,8 @@ int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[])
/* Insertion sort by bucket */
for (i = 0; i < number; i++) {
hash = tdb_hash(&keys[i]);
- for (j = 0;
- j < i && BUCKET(tdb->lockedkeys[j+1]) < BUCKET(hash);
- j++);
- memmove(&tdb->lockedkeys[j+2], &tdb->lockedkeys[j+1],
- sizeof(u32) * (i-j));
+ for (j = 0; j < i && BUCKET(tdb->lockedkeys[j+1]) < BUCKET(hash); j++);
+ memmove(&tdb->lockedkeys[j+2], &tdb->lockedkeys[j+1], sizeof(u32) * (i-j));
tdb->lockedkeys[j+1] = hash;
}
/* Finally, lock in order */
@@ -1470,3 +1618,47 @@ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , cons
{
tdb->log_fn = fn;
}
+
+
+/* reopen a tdb - this is used after a fork to ensure that we have an independent
+ seek pointer from our parent and to re-establish locks */
+int tdb_reopen(TDB_CONTEXT *tdb)
+{
+ struct stat st;
+
+ tdb_munmap(tdb);
+ close(tdb->fd);
+ tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
+ if (tdb->fd == -1) {
+ TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno)));
+ goto fail;
+ }
+ fstat(tdb->fd, &st);
+ if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
+ TDB_LOG((tdb, 0, "tdb_reopen: file dev/inode has changed!\n"));
+ goto fail;
+ }
+ tdb_mmap(tdb);
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n"));
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ tdb_close(tdb);
+ return -1;
+}
+
+/* reopen all tdb's */
+int tdb_reopen_all(void)
+{
+ TDB_CONTEXT *tdb;
+
+ for (tdb=tdbs; tdb; tdb = tdb->next) {
+ if (tdb_reopen(tdb) != 0) return -1;
+ }
+
+ return 0;
+}
diff --git a/source/tdb/tdb.h b/source/tdb/tdb.h
index cc37825e781..4efe263ee85 100644
--- a/source/tdb/tdb.h
+++ b/source/tdb/tdb.h
@@ -95,6 +95,7 @@ typedef struct tdb_context {
dev_t device; /* uniquely identifies this tdb */
ino_t inode; /* uniquely identifies this tdb */
void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...); /* logging function */
+ int open_flags; /* flags used in the open - needed by reopen */
} TDB_CONTEXT;
typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);
diff --git a/source/tdb/tdbtool.c b/source/tdb/tdbtool.c
index 8c09c76df55..8b396ca5a2a 100644
--- a/source/tdb/tdbtool.c
+++ b/source/tdb/tdbtool.c
@@ -1,3 +1,4 @@
+#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
@@ -111,6 +112,9 @@ static void create_tdb(void)
if (tdb) tdb_close(tdb);
tdb = tdb_open(tok, 0, TDB_CLEAR_IF_FIRST,
O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (!tdb) {
+ printf("Could not create %s: %s\n", tok, strerror(errno));
+ }
}
static void open_tdb(void)
@@ -122,6 +126,9 @@ static void open_tdb(void)
}
if (tdb) tdb_close(tdb);
tdb = tdb_open(tok, 0, 0, O_RDWR, 0600);
+ if (!tdb) {
+ printf("Could not open %s: %s\n", tok, strerror(errno));
+ }
}
static void insert_tdb(void)
diff --git a/source/tdb/tdbutil.c b/source/tdb/tdbutil.c
index 0a2f1f84d45..da4f6718d4c 100644
--- a/source/tdb/tdbutil.c
+++ b/source/tdb/tdbutil.c
@@ -350,7 +350,12 @@ static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode)
{
- TDB_CONTEXT *tdb = tdb_open(name, hash_size, tdb_flags,
+ TDB_CONTEXT *tdb;
+
+ if (!lp_use_mmap())
+ tdb_flags |= TDB_NOMMAP;
+
+ tdb = tdb_open(name, hash_size, tdb_flags,
open_flags, mode);
if (!tdb) return NULL;
diff --git a/source/tests/crypttest.c b/source/tests/crypttest.c
index c9133f40bee..efee2e593d4 100644
--- a/source/tests/crypttest.c
+++ b/source/tests/crypttest.c
@@ -12,6 +12,784 @@
#include <strings.h>
#endif
+#if !defined(HAVE_CRYPT)
+
+/*
+ This bit of code was derived from the UFC-crypt package which
+ carries the following copyright
+
+ Modified for use by Samba by Andrew Tridgell, October 1994
+
+ Note that this routine is only faster on some machines. Under Linux 1.1.51
+ libc 4.5.26 I actually found this routine to be slightly slower.
+
+ Under SunOS I found a huge speedup by using these routines
+ (a factor of 20 or so)
+
+ Warning: I've had a report from Steve Kennedy <steve@gbnet.org>
+ that this crypt routine may sometimes get the wrong answer. Only
+ use UFC_CRYT if you really need it.
+
+*/
+
+/*
+ * UFC-crypt: ultra fast crypt(3) implementation
+ *
+ * Copyright (C) 1991-1998, Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @(#)crypt_util.c 2.31 02/08/92
+ *
+ * Support routines
+ *
+ */
+
+
+#ifndef long32
+#if (SIZEOF_INT == 4)
+#define long32 int
+#elif (SIZEOF_LONG == 4)
+#define long32 long
+#elif (SIZEOF_SHORT == 4)
+#define long32 short
+#else
+/* uggh - no 32 bit type?? probably a CRAY. just hope this works ... */
+#define long32 int
+#endif
+#endif
+
+#ifndef long64
+#ifdef HAVE_LONGLONG
+#define long64 long long long
+#endif
+#endif
+
+#ifndef ufc_long
+#define ufc_long unsigned
+#endif
+
+#ifndef _UFC_64_
+#define _UFC_32_
+#endif
+
+/*
+ * Permutation done once on the 56 bit
+ * key derived from the original 8 byte ASCII key.
+ */
+static int pc1[56] = {
+ 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
+ 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
+ 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
+ 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
+};
+
+/*
+ * How much to rotate each 28 bit half of the pc1 permutated
+ * 56 bit key before using pc2 to give the i' key
+ */
+static int rots[16] = {
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+/*
+ * Permutation giving the key
+ * of the i' DES round
+ */
+static int pc2[48] = {
+ 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
+ 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
+ 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+ 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
+};
+
+/*
+ * The E expansion table which selects
+ * bits from the 32 bit intermediate result.
+ */
+static int esel[48] = {
+ 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
+ 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
+ 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
+ 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
+};
+static int e_inverse[64];
+
+/*
+ * Permutation done on the
+ * result of sbox lookups
+ */
+static int perm32[32] = {
+ 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
+ 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
+};
+
+/*
+ * The sboxes
+ */
+static int sbox[8][4][16]= {
+ { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
+ { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
+ { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
+ { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
+ },
+
+ { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
+ { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
+ { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
+ { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
+ },
+
+ { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
+ { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
+ { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
+ { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
+ },
+
+ { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
+ { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
+ { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
+ { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
+ },
+
+ { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
+ { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
+ { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
+ { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
+ },
+
+ { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
+ { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
+ { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
+ { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
+ },
+
+ { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
+ { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
+ { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
+ { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
+ },
+
+ { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
+ { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
+ { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
+ { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
+ }
+};
+
+/*
+ * This is the final
+ * permutation matrix
+ */
+static int final_perm[64] = {
+ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
+ 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
+ 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
+ 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
+};
+
+/*
+ * The 16 DES keys in BITMASK format
+ */
+#ifdef _UFC_32_
+long32 _ufc_keytab[16][2];
+#endif
+
+#ifdef _UFC_64_
+long64 _ufc_keytab[16];
+#endif
+
+
+#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
+#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
+
+/* Macro to set a bit (0..23) */
+#define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) )
+
+/*
+ * sb arrays:
+ *
+ * Workhorses of the inner loop of the DES implementation.
+ * They do sbox lookup, shifting of this value, 32 bit
+ * permutation and E permutation for the next round.
+ *
+ * Kept in 'BITMASK' format.
+ */
+
+#ifdef _UFC_32_
+long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192];
+static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
+#endif
+
+#ifdef _UFC_64_
+long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096];
+static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
+#endif
+
+/*
+ * eperm32tab: do 32 bit permutation and E selection
+ *
+ * The first index is the byte number in the 32 bit value to be permuted
+ * - second - is the value of this byte
+ * - third - selects the two 32 bit values
+ *
+ * The table is used and generated internally in init_des to speed it up
+ */
+static ufc_long eperm32tab[4][256][2];
+
+/*
+ * do_pc1: permform pc1 permutation in the key schedule generation.
+ *
+ * The first index is the byte number in the 8 byte ASCII key
+ * - second - - the two 28 bits halfs of the result
+ * - third - selects the 7 bits actually used of each byte
+ *
+ * The result is kept with 28 bit per 32 bit with the 4 most significant
+ * bits zero.
+ */
+static ufc_long do_pc1[8][2][128];
+
+/*
+ * do_pc2: permform pc2 permutation in the key schedule generation.
+ *
+ * The first index is the septet number in the two 28 bit intermediate values
+ * - second - - - septet values
+ *
+ * Knowledge of the structure of the pc2 permutation is used.
+ *
+ * The result is kept with 28 bit per 32 bit with the 4 most significant
+ * bits zero.
+ */
+static ufc_long do_pc2[8][128];
+
+/*
+ * efp: undo an extra e selection and do final
+ * permutation giving the DES result.
+ *
+ * Invoked 6 bit a time on two 48 bit values
+ * giving two 32 bit longs.
+ */
+static ufc_long efp[16][64][2];
+
+static unsigned char bytemask[8] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+static ufc_long longmask[32] = {
+ 0x80000000, 0x40000000, 0x20000000, 0x10000000,
+ 0x08000000, 0x04000000, 0x02000000, 0x01000000,
+ 0x00800000, 0x00400000, 0x00200000, 0x00100000,
+ 0x00080000, 0x00040000, 0x00020000, 0x00010000,
+ 0x00008000, 0x00004000, 0x00002000, 0x00001000,
+ 0x00000800, 0x00000400, 0x00000200, 0x00000100,
+ 0x00000080, 0x00000040, 0x00000020, 0x00000010,
+ 0x00000008, 0x00000004, 0x00000002, 0x00000001
+};
+
+
+/*
+ * Silly rewrite of 'bzero'. I do so
+ * because some machines don't have
+ * bzero and some don't have memset.
+ */
+
+static void clearmem(char *start, int cnt)
+ { while(cnt--)
+ *start++ = '\0';
+ }
+
+static int initialized = 0;
+
+/* lookup a 6 bit value in sbox */
+
+#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];
+
+/*
+ * Initialize unit - may be invoked directly
+ * by fcrypt users.
+ */
+
+static void ufc_init_des(void)
+ { int comes_from_bit;
+ int bit, sg;
+ ufc_long j;
+ ufc_long mask1, mask2;
+
+ /*
+ * Create the do_pc1 table used
+ * to affect pc1 permutation
+ * when generating keys
+ */
+ for(bit = 0; bit < 56; bit++) {
+ comes_from_bit = pc1[bit] - 1;
+ mask1 = bytemask[comes_from_bit % 8 + 1];
+ mask2 = longmask[bit % 28 + 4];
+ for(j = 0; j < 128; j++) {
+ if(j & mask1)
+ do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;
+ }
+ }
+
+ /*
+ * Create the do_pc2 table used
+ * to affect pc2 permutation when
+ * generating keys
+ */
+ for(bit = 0; bit < 48; bit++) {
+ comes_from_bit = pc2[bit] - 1;
+ mask1 = bytemask[comes_from_bit % 7 + 1];
+ mask2 = BITMASK(bit % 24);
+ for(j = 0; j < 128; j++) {
+ if(j & mask1)
+ do_pc2[comes_from_bit / 7][j] |= mask2;
+ }
+ }
+
+ /*
+ * Now generate the table used to do combined
+ * 32 bit permutation and e expansion
+ *
+ * We use it because we have to permute 16384 32 bit
+ * longs into 48 bit in order to initialize sb.
+ *
+ * Looping 48 rounds per permutation becomes
+ * just too slow...
+ *
+ */
+
+ clearmem((char*)eperm32tab, sizeof(eperm32tab));
+
+ for(bit = 0; bit < 48; bit++) {
+ ufc_long inner_mask1,comes_from;
+
+ comes_from = perm32[esel[bit]-1]-1;
+ inner_mask1 = bytemask[comes_from % 8];
+
+ for(j = 256; j--;) {
+ if(j & inner_mask1)
+ eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24);
+ }
+ }
+
+ /*
+ * Create the sb tables:
+ *
+ * For each 12 bit segment of an 48 bit intermediate
+ * result, the sb table precomputes the two 4 bit
+ * values of the sbox lookups done with the two 6
+ * bit halves, shifts them to their proper place,
+ * sends them through perm32 and finally E expands
+ * them so that they are ready for the next
+ * DES round.
+ *
+ */
+ for(sg = 0; sg < 4; sg++) {
+ int j1, j2;
+ int s1, s2;
+
+ for(j1 = 0; j1 < 64; j1++) {
+ s1 = s_lookup(2 * sg, j1);
+ for(j2 = 0; j2 < 64; j2++) {
+ ufc_long to_permute, inx;
+
+ s2 = s_lookup(2 * sg + 1, j2);
+ to_permute = ((s1 << 4) | s2) << (24 - 8 * sg);
+
+#ifdef _UFC_32_
+ inx = ((j1 << 6) | j2) << 1;
+ sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0];
+ sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1];
+ sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0];
+ sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1];
+ sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0];
+ sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1];
+ sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0];
+ sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1];
+#endif
+#ifdef _UFC_64_
+ inx = ((j1 << 6) | j2);
+ sb[sg][inx] =
+ ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) |
+ (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1];
+ sb[sg][inx] |=
+ ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) |
+ (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1];
+ sb[sg][inx] |=
+ ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) |
+ (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1];
+ sb[sg][inx] |=
+ ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) |
+ (long64)eperm32tab[3][(to_permute) & 0xff][1];
+#endif
+ }
+ }
+ }
+
+ /*
+ * Create an inverse matrix for esel telling
+ * where to plug out bits if undoing it
+ */
+ for(bit=48; bit--;) {
+ e_inverse[esel[bit] - 1 ] = bit;
+ e_inverse[esel[bit] - 1 + 32] = bit + 48;
+ }
+
+ /*
+ * create efp: the matrix used to
+ * undo the E expansion and effect final permutation
+ */
+ clearmem((char*)efp, sizeof efp);
+ for(bit = 0; bit < 64; bit++) {
+ int o_bit, o_long;
+ ufc_long word_value, inner_mask1, inner_mask2;
+ int comes_from_f_bit, comes_from_e_bit;
+ int comes_from_word, bit_within_word;
+
+ /* See where bit i belongs in the two 32 bit long's */
+ o_long = bit / 32; /* 0..1 */
+ o_bit = bit % 32; /* 0..31 */
+
+ /*
+ * And find a bit in the e permutated value setting this bit.
+ *
+ * Note: the e selection may have selected the same bit several
+ * times. By the initialization of e_inverse, we only look
+ * for one specific instance.
+ */
+ comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */
+ comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */
+ comes_from_word = comes_from_e_bit / 6; /* 0..15 */
+ bit_within_word = comes_from_e_bit % 6; /* 0..5 */
+
+ inner_mask1 = longmask[bit_within_word + 26];
+ inner_mask2 = longmask[o_bit];
+
+ for(word_value = 64; word_value--;) {
+ if(word_value & inner_mask1)
+ efp[comes_from_word][word_value][o_long] |= inner_mask2;
+ }
+ }
+ initialized++;
+ }
+
+/*
+ * Process the elements of the sb table permuting the
+ * bits swapped in the expansion by the current salt.
+ */
+
+#ifdef _UFC_32_
+static void shuffle_sb(long32 *k, ufc_long saltbits)
+ { ufc_long j;
+ long32 x;
+ for(j=4096; j--;) {
+ x = (k[0] ^ k[1]) & (long32)saltbits;
+ *k++ ^= x;
+ *k++ ^= x;
+ }
+ }
+#endif
+
+#ifdef _UFC_64_
+static void shuffle_sb(long64 *k, ufc_long saltbits)
+ { ufc_long j;
+ long64 x;
+ for(j=4096; j--;) {
+ x = ((*k >> 32) ^ *k) & (long64)saltbits;
+ *k++ ^= (x << 32) | x;
+ }
+ }
+#endif
+
+/*
+ * Setup the unit for a new salt
+ * Hopefully we'll not see a new salt in each crypt call.
+ */
+
+static unsigned char current_salt[3] = "&&"; /* invalid value */
+static ufc_long current_saltbits = 0;
+static int direction = 0;
+
+static void setup_salt(const char *s1)
+ { ufc_long i, j, saltbits;
+ const unsigned char *s2 = (const unsigned char *)s1;
+
+ if(!initialized)
+ ufc_init_des();
+
+ if(s2[0] == current_salt[0] && s2[1] == current_salt[1])
+ return;
+ current_salt[0] = s2[0]; current_salt[1] = s2[1];
+
+ /*
+ * This is the only crypt change to DES:
+ * entries are swapped in the expansion table
+ * according to the bits set in the salt.
+ */
+ saltbits = 0;
+ for(i = 0; i < 2; i++) {
+ long c=ascii_to_bin(s2[i]);
+ if(c < 0 || c > 63)
+ c = 0;
+ for(j = 0; j < 6; j++) {
+ if((c >> j) & 0x1)
+ saltbits |= BITMASK(6 * i + j);
+ }
+ }
+
+ /*
+ * Permute the sb table values
+ * to reflect the changed e
+ * selection table
+ */
+ shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits);
+ shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits);
+ shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits);
+ shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits);
+
+ current_saltbits = saltbits;
+ }
+
+static void ufc_mk_keytab(char *key)
+ { ufc_long v1, v2, *k1;
+ int i;
+#ifdef _UFC_32_
+ long32 v, *k2 = &_ufc_keytab[0][0];
+#endif
+#ifdef _UFC_64_
+ long64 v, *k2 = &_ufc_keytab[0];
+#endif
+
+ v1 = v2 = 0; k1 = &do_pc1[0][0][0];
+ for(i = 8; i--;) {
+ v1 |= k1[*key & 0x7f]; k1 += 128;
+ v2 |= k1[*key++ & 0x7f]; k1 += 128;
+ }
+
+ for(i = 0; i < 16; i++) {
+ k1 = &do_pc2[0][0];
+
+ v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i]));
+ v = k1[(v1 >> 21) & 0x7f]; k1 += 128;
+ v |= k1[(v1 >> 14) & 0x7f]; k1 += 128;
+ v |= k1[(v1 >> 7) & 0x7f]; k1 += 128;
+ v |= k1[(v1 ) & 0x7f]; k1 += 128;
+
+#ifdef _UFC_32_
+ *k2++ = v;
+ v = 0;
+#endif
+#ifdef _UFC_64_
+ v <<= 32;
+#endif
+
+ v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i]));
+ v |= k1[(v2 >> 21) & 0x7f]; k1 += 128;
+ v |= k1[(v2 >> 14) & 0x7f]; k1 += 128;
+ v |= k1[(v2 >> 7) & 0x7f]; k1 += 128;
+ v |= k1[(v2 ) & 0x7f];
+
+ *k2++ = v;
+ }
+
+ direction = 0;
+ }
+
+/*
+ * Undo an extra E selection and do final permutations
+ */
+
+ufc_long *_ufc_dofinalperm(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2)
+ { ufc_long v1, v2, x;
+ static ufc_long ary[2];
+
+ x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x;
+ x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x;
+
+ v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3;
+
+ v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1];
+ v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1];
+ v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1];
+ v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1];
+
+ v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1];
+ v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1];
+ v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1];
+ v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1];
+
+ v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1];
+ v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1];
+ v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1];
+ v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1];
+
+ v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1];
+ v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1];
+ v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1];
+ v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1];
+
+ ary[0] = v1; ary[1] = v2;
+ return ary;
+ }
+
+/*
+ * crypt only: convert from 64 bit to 11 bit ASCII
+ * prefixing with the salt
+ */
+
+static char *output_conversion(ufc_long v1, ufc_long v2, const char *salt)
+ { static char outbuf[14];
+ int i, s;
+
+ outbuf[0] = salt[0];
+ outbuf[1] = salt[1] ? salt[1] : salt[0];
+
+ for(i = 0; i < 5; i++)
+ outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f);
+
+ s = (v2 & 0xf) << 2;
+ v2 = (v2 >> 2) | ((v1 & 0x3) << 30);
+
+ for(i = 5; i < 10; i++)
+ outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f);
+
+ outbuf[12] = bin_to_ascii(s);
+ outbuf[13] = 0;
+
+ return outbuf;
+ }
+
+/*
+ * UNIX crypt function
+ */
+
+static ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long);
+
+char *ufc_crypt(const char *key,const char *salt)
+ { ufc_long *s;
+ char ktab[9];
+
+ /*
+ * Hack DES tables according to salt
+ */
+ setup_salt(salt);
+
+ /*
+ * Setup key schedule
+ */
+ clearmem(ktab, sizeof ktab);
+ strncpy(ktab, key, 8);
+ ufc_mk_keytab(ktab);
+
+ /*
+ * Go for the 25 DES encryptions
+ */
+ s = _ufc_doit((ufc_long)0, (ufc_long)0,
+ (ufc_long)0, (ufc_long)0, (ufc_long)25);
+
+ /*
+ * And convert back to 6 bit ASCII
+ */
+ return output_conversion(s[0], s[1], salt);
+ }
+
+
+#ifdef _UFC_32_
+
+/*
+ * 32 bit version
+ */
+
+extern long32 _ufc_keytab[16][2];
+extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
+
+#define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
+
+static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr)
+ { int i;
+ long32 s, *k;
+
+ while(itr--) {
+ k = &_ufc_keytab[0][0];
+ for(i=8; i--; ) {
+ s = *k++ ^ r1;
+ l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4);
+ l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4);
+ s = *k++ ^ r2;
+ l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4);
+ l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4);
+
+ s = *k++ ^ l1;
+ r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4);
+ r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4);
+ s = *k++ ^ l2;
+ r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4);
+ r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4);
+ }
+ s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;
+ }
+ return _ufc_dofinalperm(l1, l2, r1, r2);
+ }
+
+#endif
+
+#ifdef _UFC_64_
+
+/*
+ * 64 bit version
+ */
+
+extern long64 _ufc_keytab[16];
+extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
+
+#define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
+
+static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr)
+ { int i;
+ long64 l, r, s, *k;
+
+ l = (((long64)l1) << 32) | ((long64)l2);
+ r = (((long64)r1) << 32) | ((long64)r2);
+
+ while(itr--) {
+ k = &_ufc_keytab[0];
+ for(i=8; i--; ) {
+ s = *k++ ^ r;
+ l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff);
+ l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff);
+ l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff);
+ l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff);
+
+ s = *k++ ^ l;
+ r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff);
+ r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff);
+ r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff);
+ r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff);
+ }
+ s=l; l=r; r=s;
+ }
+
+ l1 = l >> 32; l2 = l & 0xffffffff;
+ r1 = r >> 32; r2 = r & 0xffffffff;
+ return _ufc_dofinalperm(l1, l2, r1, r2);
+ }
+
+#endif
+
+#define crypt ufc_crypt
+#endif
+
main()
{
char passwd[9];
diff --git a/source/utils/make_printerdef.c b/source/utils/make_printerdef.c
index f403ee79bb6..a449a24fcdd 100644
--- a/source/utils/make_printerdef.c
+++ b/source/utils/make_printerdef.c
@@ -154,6 +154,8 @@ static void lookup_strings(FILE *fichier)
temp2=(char *)malloc(sizeof(pstring));
if(temp == NULL || temp2 == NULL) {
+ safe_free(temp);
+ safe_free(temp2);
fprintf(stderr,"lookup_strings: malloc fail !\n");
exit(1);
}
@@ -216,6 +218,8 @@ static void lookup_entry(FILE *fichier,char *chaine)
temp2=(char *)malloc(sizeof(pstring));
if(temp == NULL || temp2 == NULL) {
+ safe_free(temp);
+ safe_free(temp2);
fprintf(stderr,"lookup_entry: malloc fail !\n");
exit(1);
}
@@ -272,6 +276,9 @@ static char *find_desc(FILE *fichier,char *text)
long_desc=(char *)malloc(sizeof(pstring));
short_desc=(char *)malloc(sizeof(pstring));
if (!chaine || !long_desc || !short_desc) {
+ safe_free(chaine);
+ safe_free(long_desc);
+ safe_free(short_desc);
fprintf(stderr,"find_desc: Unable to malloc memory\n");
exit(1);
}
diff --git a/source/utils/rpccheck.c b/source/utils/rpccheck.c
index f504463027c..1db7de34234 100644
--- a/source/utils/rpccheck.c
+++ b/source/utils/rpccheck.c
@@ -42,6 +42,8 @@ main()
DEBUGLEVEL=10;
ctx=talloc_init();
+ if (!ctx)
+ exit(1);
prs_init(&ps, 1600, 4, ctx, MARSHALL);
diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c
index 028eb481a65..59385decaa4 100644
--- a/source/utils/smbcacls.c
+++ b/source/utils/smbcacls.c
@@ -94,7 +94,7 @@ static BOOL cacls_open_policy_hnd(void)
if (cli_lsa_open_policy(&lsa_cli, lsa_cli.mem_ctx, True,
GENERIC_EXECUTE_ACCESS, &pol)
- != NT_STATUS_NOPROBLEMO) {
+ != NT_STATUS_OK) {
return False;
}
@@ -119,7 +119,7 @@ static void SidToString(fstring str, DOM_SID *sid)
if (!cacls_open_policy_hnd() ||
cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, sid, &names, &types,
- &num_names) != NT_STATUS_NOPROBLEMO ||
+ &num_names) != NT_STATUS_OK ||
!names || !names[0]) {
return;
}
@@ -143,7 +143,7 @@ static BOOL StringToSid(DOM_SID *sid, char *str)
if (!cacls_open_policy_hnd() ||
cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, &str, &sids, &types,
- &num_sids) != NT_STATUS_NOPROBLEMO) {
+ &num_sids) != NT_STATUS_OK) {
result = False;
goto done;
}
diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c
index a4a6e32630a..bba7b15dd28 100644
--- a/source/utils/smbcontrol.c
+++ b/source/utils/smbcontrol.c
@@ -44,7 +44,7 @@ static void usage(BOOL doexit)
{
int i;
if (doexit) {
- printf("Usage: smbcontrol -i\n");
+ printf("Usage: smbcontrol -i -s configfile\n");
printf(" smbcontrol <destination> <message-type> <parameters>\n\n");
} else {
printf("<destination> <message-type> <parameters>\n\n");
@@ -129,7 +129,7 @@ static BOOL send_message(char *dest, int msg_type, void *buf, int len, BOOL dupl
pid_t pid = 0;
TDB_CONTEXT *the_tdb;
- the_tdb = tdb_open_log(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0);
+ the_tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDWR, 0);
if (!the_tdb) {
fprintf(stderr,"Failed to open connections database in send_message.\n");
return False;
@@ -340,23 +340,27 @@ static BOOL do_command(char *dest, char *msg_name, char **params)
setup_logging(argv[0],True);
charset_initialise();
- lp_load(servicesf,False,False,False);
-
- if (!message_init()) exit(1);
if (argc < 2) usage(True);
- while ((opt = getopt(argc, argv,"i")) != EOF) {
+ while ((opt = getopt(argc, argv,"is:")) != EOF) {
switch (opt) {
case 'i':
interactive = True;
break;
+ case 's':
+ pstrcpy(servicesf, optarg);
+ break;
default:
printf("Unknown option %c (%d)\n", (char)opt, opt);
usage(True);
}
}
+ lp_load(servicesf,False,False,False);
+
+ if (!message_init()) exit(1);
+
argc -= optind;
argv = &argv[optind];
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 15512435cc1..b29b5d9a97e 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -1,11 +1,14 @@
/*
- * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright
- * (C) Jeremy Allison 1995-1998
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * smbpasswd module.
+ * Copyright (C) Jeremy Allison 1995-1998
+ * Copyright (C) Tim Potter 2001
*
- * 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 2 of the License, or (at your option)
- * any later version.
+ * 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 2 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
@@ -14,8 +17,7 @@
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
+ * Mass Ave, Cambridge, MA 02139, USA. */
#include "includes.h"
@@ -72,6 +74,9 @@ static void usage(void)
printf(" -e enable user\n");
printf(" -n set no password\n");
printf(" -m machine trust account\n");
+#ifdef WITH_LDAP_SAM
+ printf(" -w ldap admin password\n");
+#endif
}
exit(1);
}
@@ -136,6 +141,294 @@ unable to join domain.\n");
return (int)ret;
}
+/* Initialise client credentials for authenticated pipe access */
+
+void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
+ char* domain, char* password)
+{
+ ZERO_STRUCTP(creds);
+
+ if (lp_encrypted_passwords()) {
+ pwd_make_lm_nt_16(&creds->pwd, password);
+ } else {
+ pwd_set_cleartext(&creds->pwd, password);
+ }
+
+ fstrcpy(creds->user_name, username);
+ fstrcpy(creds->domain, domain);
+}
+
+/*********************************************************
+Join a domain using the administrator username and password
+**********************************************************/
+
+/* Macro for checking RPC error codes to make things more readable */
+
+#define CHECK_RPC_ERR(rpc, msg) \
+ if ((result = rpc) != NT_STATUS_OK) { \
+ DEBUG(0, (msg ": %s\n", get_nt_error_msg(result))); \
+ goto done; \
+ }
+
+#define CHECK_RPC_ERR_DEBUG(rpc, debug_args) \
+ if ((result = rpc) != NT_STATUS_OK) { \
+ DEBUG(0, debug_args); \
+ goto done; \
+ }
+
+static int join_domain_byuser(char *domain, char *remote_machine,
+ char *username, char *password)
+{
+ /* libsmb variables */
+
+ struct nmb_name calling, called;
+ struct ntuser_creds creds;
+ struct cli_state cli;
+ fstring dest_host, acct_name;
+ struct in_addr dest_ip;
+ TALLOC_CTX *mem_ctx;
+
+ /* rpc variables */
+
+ POLICY_HND lsa_pol, sam_pol, domain_pol, user_pol;
+ DOM_SID domain_sid;
+ uint32 user_rid;
+
+ /* Password stuff */
+
+ char *machine_pwd;
+ int plen = 0;
+ uchar pwbuf[516], ntpw[16], sess_key[16];
+ SAM_USERINFO_CTR ctr;
+ SAM_USER_INFO_24 p24;
+ SAM_USER_INFO_10 p10;
+
+ /* Misc */
+
+ uint32 result;
+ int retval = 1;
+
+ /* Connect to remote machine */
+
+ ZERO_STRUCT(cli);
+ ZERO_STRUCT(creds);
+
+ if (!(mem_ctx = talloc_init())) {
+ DEBUG(0, ("Could not initialise talloc context\n"));
+ goto done;
+ }
+
+ if (!cli_initialise(&cli)) {
+ DEBUG(0, ("Could not initialise client structure\n"));
+ goto done;
+ }
+
+ init_rpcclient_creds(&creds, username, domain, password);
+ cli_init_creds(&cli, &creds);
+
+ if (!resolve_srv_name(remote_machine, dest_host, &dest_ip)) {
+ DEBUG(0, ("Could not resolve name %s\n", remote_machine));
+ goto done;
+ }
+
+ make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+
+ if (!cli_establish_connection(&cli, dest_host, &dest_ip, &calling,
+ &called, "IPC$", "IPC", False, True)) {
+ DEBUG(0, ("Error connecting to %s\n", dest_host));
+ goto done;
+ }
+
+ /* Fetch domain sid */
+
+ if (!cli_nt_session_open(&cli, PIPE_LSARPC)) {
+ DEBUG(0, ("Error connecting to SAM pipe\n"));
+ goto done;
+ }
+
+
+ CHECK_RPC_ERR(cli_lsa_open_policy(&cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &lsa_pol),
+ "error opening lsa policy handle");
+
+ CHECK_RPC_ERR(cli_lsa_query_info_policy(&cli, mem_ctx, &lsa_pol,
+ 5, domain, &domain_sid),
+ "error querying info policy");
+
+ cli_lsa_close(&cli, mem_ctx, &lsa_pol);
+
+ cli_nt_session_close(&cli); /* Done with this pipe */
+
+ /* Create domain user */
+
+ if (!cli_nt_session_open(&cli, PIPE_SAMR)) {
+ DEBUG(0, ("Error connecting to SAM pipe\n"));
+ goto done;
+ }
+
+ CHECK_RPC_ERR(cli_samr_connect(&cli, mem_ctx,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &sam_pol),
+ "could not connect to SAM database");
+
+
+ CHECK_RPC_ERR(cli_samr_open_domain(&cli, mem_ctx, &sam_pol,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain_sid, &domain_pol),
+ "could not open domain");
+
+ /* Create domain user */
+
+ fstrcpy(acct_name, global_myname);
+ fstrcat(acct_name, "$");
+
+ strlower(acct_name);
+
+ {
+ uint32 unknown = 0xe005000b;
+
+ result = cli_samr_create_dom_user(&cli, mem_ctx, &domain_pol,
+ acct_name, ACB_WSTRUST,
+ unknown, &user_pol,
+ &user_rid);
+
+ /* We *must* do this.... don't ask... */
+
+ CHECK_RPC_ERR_DEBUG(cli_samr_close(&cli, mem_ctx, &user_pol), ("error closing user policy"));
+ result = NT_STATUS_USER_EXISTS;
+ }
+
+ if (result == NT_STATUS_USER_EXISTS) {
+ uint32 num_rids, *name_types, *user_rids;
+ uint32 flags = 0x3e8;
+ char *names;
+
+ /* Look up existing rid */
+
+ names = (char *)&acct_name[0];
+
+ CHECK_RPC_ERR_DEBUG(
+ cli_samr_lookup_names(&cli, mem_ctx,
+ &domain_pol, flags,
+ 1, &names, &num_rids,
+ &user_rids, &name_types),
+ ("error looking up rid for user %s: %s\n",
+ acct_name, get_nt_error_msg(result)));
+
+ if (name_types[0] != SID_NAME_USER) {
+ DEBUG(0, ("%s is not a user account\n", acct_name));
+ goto done;
+ }
+
+ user_rid = user_rids[0];
+
+ /* Open handle on user */
+
+ CHECK_RPC_ERR_DEBUG(
+ cli_samr_open_user(&cli, mem_ctx, &domain_pol,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ user_rid, &user_pol),
+ ("could not re-open existing user %s: %s\n",
+ acct_name, get_nt_error_msg(result)));
+
+ } else if (result != NT_STATUS_OK) {
+ DEBUG(0, ("error creating domain user: %s\n",
+ get_nt_error_msg(result)));
+ goto done;
+ }
+
+ /* Create a random machine account password */
+
+ {
+ UNISTR2 upw; /* Unicode password */
+
+ upw.buffer = (uint16 *)talloc_zero(mem_ctx, 0xc *
+ sizeof(uint16));
+
+ upw.uni_str_len = 0xc;
+ upw.uni_max_len = 0xc;
+
+ machine_pwd = (char *)upw.buffer;
+ plen = upw.uni_str_len * 2;
+ generate_random_buffer((unsigned char *)machine_pwd, plen, True);
+
+ encode_pw_buffer((char *)pwbuf, machine_pwd, plen, False);
+
+ nt_owf_genW(&upw, ntpw);
+ }
+
+ /* Set password on machine account */
+
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(p24);
+
+ init_sam_user_info24(&p24, (char *)pwbuf,24);
+
+ ctr.switch_value = 24;
+ ctr.info.id24 = &p24;
+
+ /* I don't think this is quite the right place for this
+ calculation. It should be moved somewhere where the credentials
+ are calculated. )-: */
+
+ mdfour(sess_key, cli.pwd.smb_nt_pwd, 16);
+
+ CHECK_RPC_ERR(cli_samr_set_userinfo(&cli, mem_ctx, &user_pol, 24,
+ sess_key, &ctr),
+ "error setting trust account password");
+
+ /* Why do we have to try to (re-)set the ACB to be the same as what
+ we passed in the samr_create_dom_user() call? When a NT
+ workstation is joined to a domain by an administrator the
+ acb_info is set to 0x80. For a normal user with "Add
+ workstations to the domain" rights the acb_info is 0x84. I'm
+ not sure whether it is supposed to make a difference or not. NT
+ seems to cope with either value so don't bomb out if the set
+ userinfo2 level 0x10 fails. -tpot */
+
+ ZERO_STRUCT(ctr);
+ ctr.switch_value = 0x10;
+ ctr.info.id10 = &p10;
+
+ init_sam_user_info10(&p10, ACB_WSTRUST);
+
+ /* Ignoring the return value is necessary for joining a domain
+ as a normal user with "Add workstation to domain" privilege. */
+
+ result = cli_samr_set_userinfo2(&cli, mem_ctx, &user_pol, 0x10,
+ sess_key, &ctr);
+
+ /* Now store the secret in the secrets database */
+
+ strupper(domain);
+
+ if (!secrets_store_domain_sid(domain, &domain_sid) ||
+ !secrets_store_trust_account_password(domain, ntpw)) {
+ DEBUG(0, ("error storing domain secrets\n"));
+ goto done;
+ }
+
+ retval = 0; /* Success! */
+
+ done:
+ /* Close down pipe - this will clean up open policy handles */
+
+ if (cli.nt_pipe_fnum)
+ cli_nt_session_close(&cli);
+
+ /* Display success or failure */
+
+ if (retval != 0) {
+ trust_password_delete(domain);
+ fprintf(stderr,"Unable to join domain %s.\n",domain);
+ } else {
+ printf("Joined domain %s.\n",domain);
+ }
+
+ return retval;
+}
static void set_line_buffering(FILE *f)
{
@@ -247,6 +540,26 @@ static BOOL password_change(const char *remote_machine, char *user_name,
return ret;
}
+#ifdef WITH_LDAP_SAM
+/*******************************************************************
+ Store the LDAP admin password in secrets.tdb
+ ******************************************************************/
+static BOOL store_ldap_admin_pw (char* pw)
+{
+ TDB_DATA kbuf, dbuf;
+ pstring fname;
+ pstring key;
+ char *p;
+
+ if (!pw)
+ return False;
+
+ if (!secrets_init())
+ return False;
+
+ return secrets_store_ldap_pw(lp_ldap_admin_dn(), pw);
+}
+#endif
/*************************************************************
Handle password changing for root.
@@ -256,16 +569,21 @@ static int process_root(int argc, char *argv[])
{
struct passwd *pwd;
int result = 0, ch;
- BOOL joining_domain = False;
+ BOOL joining_domain = False, got_pass = False, got_username = False;
int local_flags = 0;
BOOL stdin_passwd_get = False;
- char *user_name = NULL;
+ fstring user_name, user_password;
+#ifdef WITH_LDAP_SAM
+ fstring ldap_secret;
+#endif
char *new_domain = NULL;
char *new_passwd = NULL;
char *old_passwd = NULL;
char *remote_machine = NULL;
- while ((ch = getopt(argc, argv, "ax:d:e:mnj:r:sR:D:U:L")) != EOF) {
+ user_name[0] = '\0';
+
+ while ((ch = getopt(argc, argv, "axdehmnj:r:sw:R:D:U:L")) != EOF) {
switch(ch) {
case 'L':
local_mode = True;
@@ -275,17 +593,14 @@ static int process_root(int argc, char *argv[])
break;
case 'x':
local_flags |= LOCAL_DELETE_USER;
- user_name = optarg;
new_passwd = xstrdup("XXXXXX");
break;
case 'd':
local_flags |= LOCAL_DISABLE_USER;
- user_name = optarg;
new_passwd = xstrdup("XXXXXX");
break;
case 'e':
local_flags |= LOCAL_ENABLE_USER;
- user_name = optarg;
break;
case 'm':
local_flags |= LOCAL_TRUST_ACCOUNT;
@@ -308,15 +623,38 @@ static int process_root(int argc, char *argv[])
set_line_buffering(stderr);
stdin_passwd_get = True;
break;
+ case 'w':
+#ifdef WITH_LDAP_SAM
+ local_flags |= LOCAL_SET_LDAP_ADMIN_PW;
+ fstrcpy(ldap_secret, optarg);
+ break;
+#else
+ printf("-w not available unless configured --with-ldap\n");
+ goto done;
+#endif
case 'R':
lp_set_name_resolve_order(optarg);
break;
case 'D':
DEBUGLEVEL = atoi(optarg);
break;
- case 'U':
- user_name = optarg;
+ case 'U': {
+ char *lp;
+
+ got_username = True;
+ fstrcpy(user_name, optarg);
+
+ if ((lp = strchr(user_name, '%'))) {
+ *lp = 0;
+ fstrcpy(user_password, lp + 1);
+ got_pass = True;
+ memset(strchr(optarg, '%') + 1, 'X',
+ strlen(user_password));
+ }
+
break;
+ }
+ case 'h':
default:
usage();
}
@@ -325,6 +663,17 @@ static int process_root(int argc, char *argv[])
argc -= optind;
argv += optind;
+#ifdef WITH_LDAP_SAM
+ if (local_flags & LOCAL_SET_LDAP_ADMIN_PW)
+ {
+ printf("Setting stored password for \"%s\" in secrets.tdb\n",
+ lp_ldap_admin_dn());
+ if (!store_ldap_admin_pw(ldap_secret))
+ DEBUG(0,("ERROR: Failed to store the ldap admin password!\n"));
+ goto done;
+ }
+#endif
+
/*
* Ensure both add/delete user are not set
* Ensure add/delete user and either remote machine or join domain are
@@ -342,10 +691,35 @@ static int process_root(int argc, char *argv[])
load_interfaces();
}
- if(joining_domain) {
+ /* Join a domain */
+
+ if (joining_domain) {
+
if (argc != 0)
usage();
- return join_domain(new_domain, remote_machine);
+
+ /* Are we joining by specifing an admin username and
+ password? */
+
+ if (user_name[0]) {
+
+ /* Get administrator password if not specified */
+
+ if (!got_pass) {
+ char *pass = getpass("Password: ");
+
+ if (pass)
+ pstrcpy(user_password, pass);
+ }
+
+ return join_domain_byuser(new_domain, remote_machine,
+ user_name, user_password);
+ } else {
+
+ /* Or just with the server manager? */
+
+ return join_domain(new_domain, remote_machine);
+ }
}
/*
@@ -354,23 +728,29 @@ static int process_root(int argc, char *argv[])
switch(argc) {
case 0:
+ if (!got_username)
+ fstrcpy(user_name, "");
break;
case 1:
- user_name = argv[0];
+ if (got_username)
+ usage();
+ fstrcpy(user_name, argv[0]);
break;
case 2:
- user_name = argv[0];
+ if (got_username || got_pass)
+ usage();
+ fstrcpy(user_name, argv[0]);
new_passwd = xstrdup(argv[1]);
break;
default:
usage();
}
- if (!user_name && (pwd = sys_getpwuid(0))) {
- user_name = xstrdup(pwd->pw_name);
+ if (!user_name[0] && (pwd = sys_getpwuid(0))) {
+ fstrcpy(user_name, pwd->pw_name);
}
- if (!user_name) {
+ if (!user_name[0]) {
fprintf(stderr,"You must specify a username\n");
exit(1);
}
@@ -400,7 +780,7 @@ static int process_root(int argc, char *argv[])
*/
slprintf(buf, sizeof(buf)-1, "%s$", user_name);
- user_name = buf;
+ fstrcpy(user_name, buf);
}
if (remote_machine != NULL) {
@@ -419,10 +799,21 @@ static int process_root(int argc, char *argv[])
*/
if(local_flags & LOCAL_ENABLE_USER) {
- struct smb_passwd *smb_pass = getsmbpwnam(user_name);
- if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL)) {
+
+ SAM_ACCOUNT *sampass = NULL;
+
+ pdb_init_sam(&sampass);
+ if (!pdb_getsampwnam(sampass, user_name)) {
+ printf("ERROR: Unable to locate %s in passdb!\n", user_name);
+ pdb_free_sam(sampass);
+ result = 1;
+ goto done;
+ }
+ if((sampass != NULL) && (pdb_get_lanman_passwd(sampass) != NULL)) {
new_passwd = xstrdup("XXXX"); /* Don't care. */
}
+
+ pdb_free_sam(sampass);
}
if(!new_passwd)
@@ -441,13 +832,27 @@ static int process_root(int argc, char *argv[])
}
if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD))) {
- struct smb_passwd *smb_pass = getsmbpwnam(user_name);
+ SAM_ACCOUNT *sampass = NULL;
+ uint16 acct_ctrl;
+
+ pdb_init_sam(&sampass);
+
+ if (!pdb_getsampwnam(sampass, user_name)) {
+ printf("ERROR: Unable to locate %s in passdb!\n", user_name);
+ pdb_free_sam(sampass);
+ result = 1;
+ goto done;
+ }
+
printf("Password changed for user %s.", user_name );
- if((smb_pass != NULL) && (smb_pass->acct_ctrl & ACB_DISABLED ))
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
+ if(acct_ctrl & ACB_DISABLED)
printf(" User has disabled flag set.");
- if((smb_pass != NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ))
+ if(acct_ctrl & ACB_PWNOTREQ)
printf(" User has no password flag set.");
printf("\n");
+
+ pdb_free_sam(sampass);
}
done:
@@ -571,7 +976,7 @@ int main(int argc, char **argv)
charset_initialise();
- if(!initialize_password_db()) {
+ if(!initialize_password_db(False)) {
fprintf(stderr, "Can't setup password database vectors.\n");
exit(1);
}
diff --git a/source/utils/status.c b/source/utils/status.c
index 4d7792e515a..28726d40f0f 100644
--- a/source/utils/status.c
+++ b/source/utils/status.c
@@ -164,19 +164,344 @@ static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
******************************************************************/
static int profile_dump(void)
{
-#ifndef WITH_PROFILE
- fprintf(stderr,"ERROR: not compiled with profile support\n");
- return -1;
-#else
if (!profile_setup(True)) {
fprintf(stderr,"Failed to initialise profile memory\n");
return -1;
}
- printf("smb_count:\t%u\n", profile_p->smb_count);
- printf("uid_changes:\t%u\n", profile_p->uid_changes);
+ printf("smb_count: %u\n", profile_p->smb_count);
+ printf("uid_changes: %u\n", profile_p->uid_changes);
+ printf("************************ System Calls ****************************\n");
+ printf("opendir_count: %u\n", profile_p->syscall_opendir_count);
+ printf("opendir_time: %u\n", profile_p->syscall_opendir_time);
+ printf("readdir_count: %u\n", profile_p->syscall_readdir_count);
+ printf("readdir_time: %u\n", profile_p->syscall_readdir_time);
+ printf("mkdir_count: %u\n", profile_p->syscall_mkdir_count);
+ printf("mkdir_time: %u\n", profile_p->syscall_mkdir_time);
+ printf("rmdir_count: %u\n", profile_p->syscall_rmdir_count);
+ printf("rmdir_time: %u\n", profile_p->syscall_rmdir_time);
+ printf("closedir_count: %u\n", profile_p->syscall_closedir_count);
+ printf("closedir_time: %u\n", profile_p->syscall_closedir_time);
+ printf("open_count: %u\n", profile_p->syscall_open_count);
+ printf("open_time: %u\n", profile_p->syscall_open_time);
+ printf("close_count: %u\n", profile_p->syscall_close_count);
+ printf("close_time: %u\n", profile_p->syscall_close_time);
+ printf("read_count: %u\n", profile_p->syscall_read_count);
+ printf("read_time: %u\n", profile_p->syscall_read_time);
+ printf("read_bytes: %u\n", profile_p->syscall_read_bytes);
+ printf("write_count: %u\n", profile_p->syscall_write_count);
+ printf("write_time: %u\n", profile_p->syscall_write_time);
+ printf("write_bytes: %u\n", profile_p->syscall_write_bytes);
+ printf("lseek_count: %u\n", profile_p->syscall_lseek_count);
+ printf("lseek_time: %u\n", profile_p->syscall_lseek_time);
+ printf("rename_count: %u\n", profile_p->syscall_rename_count);
+ printf("rename_time: %u\n", profile_p->syscall_rename_time);
+ printf("fsync_count: %u\n", profile_p->syscall_fsync_count);
+ printf("fsync_time: %u\n", profile_p->syscall_fsync_time);
+ printf("stat_count: %u\n", profile_p->syscall_stat_count);
+ printf("stat_time: %u\n", profile_p->syscall_stat_time);
+ printf("fstat_count: %u\n", profile_p->syscall_fstat_count);
+ printf("fstat_time: %u\n", profile_p->syscall_fstat_time);
+ printf("lstat_count: %u\n", profile_p->syscall_lstat_count);
+ printf("lstat_time: %u\n", profile_p->syscall_lstat_time);
+ printf("unlink_count: %u\n", profile_p->syscall_unlink_count);
+ printf("unlink_time: %u\n", profile_p->syscall_unlink_time);
+ printf("chmod_count: %u\n", profile_p->syscall_chmod_count);
+ printf("chmod_time: %u\n", profile_p->syscall_chmod_time);
+ printf("fchmod_count: %u\n", profile_p->syscall_fchmod_count);
+ printf("fchmod_time: %u\n", profile_p->syscall_fchmod_time);
+ printf("chown_count: %u\n", profile_p->syscall_chown_count);
+ printf("chown_time: %u\n", profile_p->syscall_chown_time);
+ printf("fchown_count: %u\n", profile_p->syscall_fchown_count);
+ printf("fchown_time: %u\n", profile_p->syscall_fchown_time);
+ printf("chdir_count: %u\n", profile_p->syscall_chdir_count);
+ printf("chdir_time: %u\n", profile_p->syscall_chdir_time);
+ printf("getwd_count: %u\n", profile_p->syscall_getwd_count);
+ printf("getwd_time: %u\n", profile_p->syscall_getwd_time);
+ printf("utime_count: %u\n", profile_p->syscall_utime_count);
+ printf("utime_time: %u\n", profile_p->syscall_utime_time);
+ printf("ftruncate_count: %u\n", profile_p->syscall_ftruncate_count);
+ printf("ftruncate_time: %u\n", profile_p->syscall_ftruncate_time);
+ printf("fcntl_lock_count: %u\n", profile_p->syscall_fcntl_lock_count);
+ printf("fcntl_lock_time: %u\n", profile_p->syscall_fcntl_lock_time);
+ printf("readlink_count: %u\n", profile_p->syscall_readlink_count);
+ printf("readlink_time: %u\n", profile_p->syscall_readlink_time);
+ printf("symlink_count: %u\n", profile_p->syscall_symlink_count);
+ printf("symlink_time: %u\n", profile_p->syscall_symlink_time);
+ printf("************************ Statcache *******************************\n");
+ printf("lookups: %u\n", profile_p->statcache_lookups);
+ printf("misses: %u\n", profile_p->statcache_misses);
+ printf("hits: %u\n", profile_p->statcache_hits);
+ printf("************************ Writecache ******************************\n");
+ printf("read_hits: %u\n", profile_p->writecache_read_hits);
+ printf("abutted_writes: %u\n", profile_p->writecache_abutted_writes);
+ printf("total_writes: %u\n", profile_p->writecache_total_writes);
+ printf("non_oplock_writes: %u\n", profile_p->writecache_non_oplock_writes);
+ printf("direct_writes: %u\n", profile_p->writecache_direct_writes);
+ printf("init_writes: %u\n", profile_p->writecache_init_writes);
+ printf("flushed_writes[SEEK]: %u\n", profile_p->writecache_flushed_writes[SEEK_FLUSH]);
+ printf("flushed_writes[READ]: %u\n", profile_p->writecache_flushed_writes[READ_FLUSH]);
+ printf("flushed_writes[WRITE]: %u\n", profile_p->writecache_flushed_writes[WRITE_FLUSH]);
+ printf("flushed_writes[READRAW]: %u\n", profile_p->writecache_flushed_writes[READRAW_FLUSH]);
+ printf("flushed_writes[OPLOCK_RELEASE]: %u\n", profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH]);
+ printf("flushed_writes[CLOSE]: %u\n", profile_p->writecache_flushed_writes[CLOSE_FLUSH]);
+ printf("flushed_writes[SYNC]: %u\n", profile_p->writecache_flushed_writes[SYNC_FLUSH]);
+ printf("flushed_writes[SIZECHANGE]: %u\n", profile_p->writecache_flushed_writes[SIZECHANGE_FLUSH]);
+ printf("num_perfect_writes: %u\n", profile_p->writecache_num_perfect_writes);
+ printf("num_write_caches: %u\n", profile_p->writecache_num_write_caches);
+ printf("allocated_write_caches: %u\n", profile_p->writecache_allocated_write_caches);
+ printf("************************ SMB Calls *******************************\n");
+ printf("mkdir_count: %u\n", profile_p->SMBmkdir_count);
+ printf("mkdir_time: %u\n", profile_p->SMBmkdir_time);
+ printf("rmdir_count: %u\n", profile_p->SMBrmdir_count);
+ printf("rmdir_time: %u\n", profile_p->SMBrmdir_time);
+ printf("open_count: %u\n", profile_p->SMBopen_count);
+ printf("open_time: %u\n", profile_p->SMBopen_time);
+ printf("create_count: %u\n", profile_p->SMBcreate_count);
+ printf("create_time: %u\n", profile_p->SMBcreate_time);
+ printf("close_count: %u\n", profile_p->SMBclose_count);
+ printf("close_time: %u\n", profile_p->SMBclose_time);
+ printf("flush_count: %u\n", profile_p->SMBflush_count);
+ printf("flush_time: %u\n", profile_p->SMBflush_time);
+ printf("unlink_count: %u\n", profile_p->SMBunlink_count);
+ printf("unlink_time: %u\n", profile_p->SMBunlink_time);
+ printf("mv_count: %u\n", profile_p->SMBmv_count);
+ printf("mv_time: %u\n", profile_p->SMBmv_time);
+ printf("getatr_count: %u\n", profile_p->SMBgetatr_count);
+ printf("getatr_time: %u\n", profile_p->SMBgetatr_time);
+ printf("setatr_count: %u\n", profile_p->SMBsetatr_count);
+ printf("setatr_time: %u\n", profile_p->SMBsetatr_time);
+ printf("read_count: %u\n", profile_p->SMBread_count);
+ printf("read_time: %u\n", profile_p->SMBread_time);
+ printf("write_count: %u\n", profile_p->SMBwrite_count);
+ printf("write_time: %u\n", profile_p->SMBwrite_time);
+ printf("lock_count: %u\n", profile_p->SMBlock_count);
+ printf("lock_time: %u\n", profile_p->SMBlock_time);
+ printf("unlock_count: %u\n", profile_p->SMBunlock_count);
+ printf("unlock_time: %u\n", profile_p->SMBunlock_time);
+ printf("ctemp_count: %u\n", profile_p->SMBctemp_count);
+ printf("ctemp_time: %u\n", profile_p->SMBctemp_time);
+ printf("mknew_count: %u\n", profile_p->SMBmknew_count);
+ printf("mknew_time: %u\n", profile_p->SMBmknew_time);
+ printf("chkpth_count: %u\n", profile_p->SMBchkpth_count);
+ printf("chkpth_time: %u\n", profile_p->SMBchkpth_time);
+ printf("exit_count: %u\n", profile_p->SMBexit_count);
+ printf("exit_time: %u\n", profile_p->SMBexit_time);
+ printf("lseek_count: %u\n", profile_p->SMBlseek_count);
+ printf("lseek_time: %u\n", profile_p->SMBlseek_time);
+ printf("lockread_count: %u\n", profile_p->SMBlockread_count);
+ printf("lockread_time: %u\n", profile_p->SMBlockread_time);
+ printf("writeunlock_count: %u\n", profile_p->SMBwriteunlock_count);
+ printf("writeunlock_time: %u\n", profile_p->SMBwriteunlock_time);
+ printf("readbraw_count: %u\n", profile_p->SMBreadbraw_count);
+ printf("readbraw_time: %u\n", profile_p->SMBreadbraw_time);
+ printf("readBmpx_count: %u\n", profile_p->SMBreadBmpx_count);
+ printf("readBmpx_time: %u\n", profile_p->SMBreadBmpx_time);
+ printf("readBs_count: %u\n", profile_p->SMBreadBs_count);
+ printf("readBs_time: %u\n", profile_p->SMBreadBs_time);
+ printf("writebraw_count: %u\n", profile_p->SMBwritebraw_count);
+ printf("writebraw_time: %u\n", profile_p->SMBwritebraw_time);
+ printf("writeBmpx_count: %u\n", profile_p->SMBwriteBmpx_count);
+ printf("writeBmpx_time: %u\n", profile_p->SMBwriteBmpx_time);
+ printf("writeBs_count: %u\n", profile_p->SMBwriteBs_count);
+ printf("writeBs_time: %u\n", profile_p->SMBwriteBs_time);
+ printf("writec_count: %u\n", profile_p->SMBwritec_count);
+ printf("writec_time: %u\n", profile_p->SMBwritec_time);
+ printf("setattrE_count: %u\n", profile_p->SMBsetattrE_count);
+ printf("setattrE_time: %u\n", profile_p->SMBsetattrE_time);
+ printf("getattrE_count: %u\n", profile_p->SMBgetattrE_count);
+ printf("getattrE_time: %u\n", profile_p->SMBgetattrE_time);
+ printf("lockingX_count: %u\n", profile_p->SMBlockingX_count);
+ printf("lockingX_time: %u\n", profile_p->SMBlockingX_time);
+ printf("trans_count: %u\n", profile_p->SMBtrans_count);
+ printf("trans_time: %u\n", profile_p->SMBtrans_time);
+ printf("transs_count: %u\n", profile_p->SMBtranss_count);
+ printf("transs_time: %u\n", profile_p->SMBtranss_time);
+ printf("ioctl_count: %u\n", profile_p->SMBioctl_count);
+ printf("ioctl_time: %u\n", profile_p->SMBioctl_time);
+ printf("ioctls_count: %u\n", profile_p->SMBioctls_count);
+ printf("ioctls_time: %u\n", profile_p->SMBioctls_time);
+ printf("copy_count: %u\n", profile_p->SMBcopy_count);
+ printf("copy_time: %u\n", profile_p->SMBcopy_time);
+ printf("move_count: %u\n", profile_p->SMBmove_count);
+ printf("move_time: %u\n", profile_p->SMBmove_time);
+ printf("echo_count: %u\n", profile_p->SMBecho_count);
+ printf("echo_time: %u\n", profile_p->SMBecho_time);
+ printf("writeclose_count: %u\n", profile_p->SMBwriteclose_count);
+ printf("writeclose_time: %u\n", profile_p->SMBwriteclose_time);
+ printf("openX_count: %u\n", profile_p->SMBopenX_count);
+ printf("openX_time: %u\n", profile_p->SMBopenX_time);
+ printf("readX_count: %u\n", profile_p->SMBreadX_count);
+ printf("readX_time: %u\n", profile_p->SMBreadX_time);
+ printf("writeX_count: %u\n", profile_p->SMBwriteX_count);
+ printf("writeX_time: %u\n", profile_p->SMBwriteX_time);
+ printf("trans2_count: %u\n", profile_p->SMBtrans2_count);
+ printf("trans2_time: %u\n", profile_p->SMBtrans2_time);
+ printf("transs2_count: %u\n", profile_p->SMBtranss2_count);
+ printf("transs2_time: %u\n", profile_p->SMBtranss2_time);
+ printf("findclose_count: %u\n", profile_p->SMBfindclose_count);
+ printf("findclose_time: %u\n", profile_p->SMBfindclose_time);
+ printf("findnclose_count: %u\n", profile_p->SMBfindnclose_count);
+ printf("findnclose_time: %u\n", profile_p->SMBfindnclose_time);
+ printf("tcon_count: %u\n", profile_p->SMBtcon_count);
+ printf("tcon_time: %u\n", profile_p->SMBtcon_time);
+ printf("tdis_count: %u\n", profile_p->SMBtdis_count);
+ printf("tdis_time: %u\n", profile_p->SMBtdis_time);
+ printf("negprot_count: %u\n", profile_p->SMBnegprot_count);
+ printf("negprot_time: %u\n", profile_p->SMBnegprot_time);
+ printf("sesssetupX_count: %u\n", profile_p->SMBsesssetupX_count);
+ printf("sesssetupX_time: %u\n", profile_p->SMBsesssetupX_time);
+ printf("ulogoffX_count: %u\n", profile_p->SMBulogoffX_count);
+ printf("ulogoffX_time: %u\n", profile_p->SMBulogoffX_time);
+ printf("tconX_count: %u\n", profile_p->SMBtconX_count);
+ printf("tconX_time: %u\n", profile_p->SMBtconX_time);
+ printf("dskattr_count: %u\n", profile_p->SMBdskattr_count);
+ printf("dskattr_time: %u\n", profile_p->SMBdskattr_time);
+ printf("search_count: %u\n", profile_p->SMBsearch_count);
+ printf("search_time: %u\n", profile_p->SMBsearch_time);
+ printf("ffirst_count: %u\n", profile_p->SMBffirst_count);
+ printf("ffirst_time: %u\n", profile_p->SMBffirst_time);
+ printf("funique_count: %u\n", profile_p->SMBfunique_count);
+ printf("funique_time: %u\n", profile_p->SMBfunique_time);
+ printf("fclose_count: %u\n", profile_p->SMBfclose_count);
+ printf("fclose_time: %u\n", profile_p->SMBfclose_time);
+ printf("nttrans_count: %u\n", profile_p->SMBnttrans_count);
+ printf("nttrans_time: %u\n", profile_p->SMBnttrans_time);
+ printf("nttranss_count: %u\n", profile_p->SMBnttranss_count);
+ printf("nttranss_time: %u\n", profile_p->SMBnttranss_time);
+ printf("ntcreateX_count: %u\n", profile_p->SMBntcreateX_count);
+ printf("ntcreateX_time: %u\n", profile_p->SMBntcreateX_time);
+ printf("ntcancel_count: %u\n", profile_p->SMBntcancel_count);
+ printf("ntcancel_time: %u\n", profile_p->SMBntcancel_time);
+ printf("splopen_count: %u\n", profile_p->SMBsplopen_count);
+ printf("splopen_time: %u\n", profile_p->SMBsplopen_time);
+ printf("splwr_count: %u\n", profile_p->SMBsplwr_count);
+ printf("splwr_time: %u\n", profile_p->SMBsplwr_time);
+ printf("splclose_count: %u\n", profile_p->SMBsplclose_count);
+ printf("splclose_time: %u\n", profile_p->SMBsplclose_time);
+ printf("splretq_count: %u\n", profile_p->SMBsplretq_count);
+ printf("splretq_time: %u\n", profile_p->SMBsplretq_time);
+ printf("sends_count: %u\n", profile_p->SMBsends_count);
+ printf("sends_time: %u\n", profile_p->SMBsends_time);
+ printf("sendb_count: %u\n", profile_p->SMBsendb_count);
+ printf("sendb_time: %u\n", profile_p->SMBsendb_time);
+ printf("fwdname_count: %u\n", profile_p->SMBfwdname_count);
+ printf("fwdname_time: %u\n", profile_p->SMBfwdname_time);
+ printf("cancelf_count: %u\n", profile_p->SMBcancelf_count);
+ printf("cancelf_time: %u\n", profile_p->SMBcancelf_time);
+ printf("getmac_count: %u\n", profile_p->SMBgetmac_count);
+ printf("getmac_time: %u\n", profile_p->SMBgetmac_time);
+ printf("sendstrt_count: %u\n", profile_p->SMBsendstrt_count);
+ printf("sendstrt_time: %u\n", profile_p->SMBsendstrt_time);
+ printf("sendend_count: %u\n", profile_p->SMBsendend_count);
+ printf("sendend_time: %u\n", profile_p->SMBsendend_time);
+ printf("sendtxt_count: %u\n", profile_p->SMBsendtxt_count);
+ printf("sendtxt_time: %u\n", profile_p->SMBsendtxt_time);
+ printf("invalid_count: %u\n", profile_p->SMBinvalid_count);
+ printf("invalid_time: %u\n", profile_p->SMBinvalid_time);
+ printf("************************ Pathworks Calls *************************\n");
+ printf("setdir_count: %u\n", profile_p->pathworks_setdir_count);
+ printf("setdir_time: %u\n", profile_p->pathworks_setdir_time);
+ printf("************************ Trans2 Calls ****************************\n");
+ printf("open_count: %u\n", profile_p->Trans2_open_count);
+ printf("open_time: %u\n", profile_p->Trans2_open_time);
+ printf("findfirst_count: %u\n", profile_p->Trans2_findfirst_count);
+ printf("findfirst_time: %u\n", profile_p->Trans2_findfirst_time);
+ printf("findnext_count: %u\n", profile_p->Trans2_findnext_count);
+ printf("findnext_time: %u\n", profile_p->Trans2_findnext_time);
+ printf("qfsinfo_count: %u\n", profile_p->Trans2_qfsinfo_count);
+ printf("qfsinfo_time: %u\n", profile_p->Trans2_qfsinfo_time);
+ printf("setfsinfo_count: %u\n", profile_p->Trans2_setfsinfo_count);
+ printf("setfsinfo_time: %u\n", profile_p->Trans2_setfsinfo_time);
+ printf("qpathinfo_count: %u\n", profile_p->Trans2_qpathinfo_count);
+ printf("qpathinfo_time: %u\n", profile_p->Trans2_qpathinfo_time);
+ printf("setpathinfo_count: %u\n", profile_p->Trans2_setpathinfo_count);
+ printf("setpathinfo_time: %u\n", profile_p->Trans2_setpathinfo_time);
+ printf("qfileinfo_count: %u\n", profile_p->Trans2_qfileinfo_count);
+ printf("qfileinfo_time: %u\n", profile_p->Trans2_qfileinfo_time);
+ printf("setfileinfo_count: %u\n", profile_p->Trans2_setfileinfo_count);
+ printf("setfileinfo_time: %u\n", profile_p->Trans2_setfileinfo_time);
+ printf("fsctl_count: %u\n", profile_p->Trans2_fsctl_count);
+ printf("fsctl_time: %u\n", profile_p->Trans2_fsctl_time);
+ printf("ioctl_count: %u\n", profile_p->Trans2_ioctl_count);
+ printf("ioctl_time: %u\n", profile_p->Trans2_ioctl_time);
+ printf("findnotifyfirst_count: %u\n", profile_p->Trans2_findnotifyfirst_count);
+ printf("findnotifyfirst_time: %u\n", profile_p->Trans2_findnotifyfirst_time);
+ printf("findnotifynext_count: %u\n", profile_p->Trans2_findnotifynext_count);
+ printf("findnotifynext_time: %u\n", profile_p->Trans2_findnotifynext_time);
+ printf("mkdir_count: %u\n", profile_p->Trans2_mkdir_count);
+ printf("mkdir_time: %u\n", profile_p->Trans2_mkdir_time);
+ printf("session_setup_count: %u\n", profile_p->Trans2_session_setup_count);
+ printf("session_setup_time: %u\n", profile_p->Trans2_session_setup_time);
+ printf("get_dfs_referral_count: %u\n", profile_p->Trans2_get_dfs_referral_count);
+ printf("get_dfs_referral_time: %u\n", profile_p->Trans2_get_dfs_referral_time);
+ printf("report_dfs_inconsistancy_count: %u\n", profile_p->Trans2_report_dfs_inconsistancy_count);
+ printf("report_dfs_inconsistancy_time: %u\n", profile_p->Trans2_report_dfs_inconsistancy_time);
+ printf("************************ NT Transact Calls ***********************\n");
+ printf("create_count: %u\n", profile_p->NT_transact_create_count);
+ printf("create_time: %u\n", profile_p->NT_transact_create_time);
+ printf("ioctl_count: %u\n", profile_p->NT_transact_ioctl_count);
+ printf("ioctl_time: %u\n", profile_p->NT_transact_ioctl_time);
+ printf("set_security_desc_count: %u\n", profile_p->NT_transact_set_security_desc_count);
+ printf("set_security_desc_time: %u\n", profile_p->NT_transact_set_security_desc_time);
+ printf("notify_change_count: %u\n", profile_p->NT_transact_notify_change_count);
+ printf("notify_change_time: %u\n", profile_p->NT_transact_notify_change_time);
+ printf("rename_count: %u\n", profile_p->NT_transact_rename_count);
+ printf("rename_time: %u\n", profile_p->NT_transact_rename_time);
+ printf("query_security_desc_count: %u\n", profile_p->NT_transact_query_security_desc_count);
+ printf("query_security_desc_time: %u\n", profile_p->NT_transact_query_security_desc_time);
+ printf("************************ ACL Calls *******************************\n");
+ printf("get_nt_acl_count: %u\n", profile_p->get_nt_acl_count);
+ printf("get_nt_acl_time: %u\n", profile_p->get_nt_acl_time);
+ printf("fget_nt_acl_count: %u\n", profile_p->fget_nt_acl_count);
+ printf("fget_nt_acl_time: %u\n", profile_p->fget_nt_acl_time);
+ printf("set_nt_acl_count: %u\n", profile_p->set_nt_acl_count);
+ printf("set_nt_acl_time: %u\n", profile_p->set_nt_acl_time);
+ printf("fset_nt_acl_count: %u\n", profile_p->fset_nt_acl_count);
+ printf("fset_nt_acl_time: %u\n", profile_p->fset_nt_acl_time);
+ printf("chmod_acl_count: %u\n", profile_p->chmod_acl_count);
+ printf("chmod_acl_time: %u\n", profile_p->chmod_acl_time);
+ printf("fchmod_acl_count: %u\n", profile_p->fchmod_acl_count);
+ printf("fchmod_acl_time: %u\n", profile_p->fchmod_acl_time);
+ printf("************************ NMBD Calls ****************************\n");
+ printf("name_release_count: %u\n", profile_p->name_release_count);
+ printf("name_release_time: %u\n", profile_p->name_release_time);
+ printf("name_refresh_count: %u\n", profile_p->name_refresh_count);
+ printf("name_refresh_time: %u\n", profile_p->name_refresh_time);
+ printf("name_registration_count: %u\n", profile_p->name_registration_count);
+ printf("name_registration_time: %u\n", profile_p->name_registration_time);
+ printf("node_status_count: %u\n", profile_p->node_status_count);
+ printf("node_status_time: %u\n", profile_p->node_status_time);
+ printf("name_query_count: %u\n", profile_p->name_query_count);
+ printf("name_query_time: %u\n", profile_p->name_query_time);
+ printf("host_announce_count: %u\n", profile_p->host_announce_count);
+ printf("host_announce_time: %u\n", profile_p->host_announce_time);
+ printf("workgroup_announce_count: %u\n", profile_p->workgroup_announce_count);
+ printf("workgroup_announce_time: %u\n", profile_p->workgroup_announce_time);
+ printf("local_master_announce_count: %u\n", profile_p->local_master_announce_count);
+ printf("local_master_announce_time: %u\n", profile_p->local_master_announce_time);
+ printf("master_browser_announce_count: %u\n", profile_p->master_browser_announce_count);
+ printf("master_browser_announce_time: %u\n", profile_p->master_browser_announce_time);
+ printf("lm_host_announce_count: %u\n", profile_p->lm_host_announce_count);
+ printf("lm_host_announce_time: %u\n", profile_p->lm_host_announce_time);
+ printf("get_backup_list_count: %u\n", profile_p->get_backup_list_count);
+ printf("get_backup_list_time: %u\n", profile_p->get_backup_list_time);
+ printf("reset_browser_count: %u\n", profile_p->reset_browser_count);
+ printf("reset_browser_time: %u\n", profile_p->reset_browser_time);
+ printf("announce_request_count: %u\n", profile_p->announce_request_count);
+ printf("announce_request_time: %u\n", profile_p->announce_request_time);
+ printf("lm_announce_request_count: %u\n", profile_p->lm_announce_request_count);
+ printf("lm_announce_request_time: %u\n", profile_p->lm_announce_request_time);
+ printf("domain_logon_count: %u\n", profile_p->domain_logon_count);
+ printf("domain_logon_time: %u\n", profile_p->domain_logon_time);
+ printf("sync_browse_lists_count: %u\n", profile_p->sync_browse_lists_count);
+ printf("sync_browse_lists_time: %u\n", profile_p->sync_browse_lists_time);
+ printf("run_elections_count: %u\n", profile_p->run_elections_count);
+ printf("run_elections_time: %u\n", profile_p->run_elections_time);
+ printf("election_count: %u\n", profile_p->election_count);
+ printf("election_time: %u\n", profile_p->election_time);
+
return 0;
-#endif
}
@@ -310,7 +635,7 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
return profile_dump();
}
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0);
+ tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
if (!tdb) {
printf("connections.tdb not initialised\n");
if (!lp_status(-1))
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
index ae4a12a8825..10292b3033a 100644
--- a/source/utils/testparm.c
+++ b/source/utils/testparm.c
@@ -145,6 +145,11 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
}
}
+ if (lp_status(-1) && lp_max_smbd_processes()) {
+ printf("ERROR: the 'max smbd processes' parameter is set and the 'status' parameter is set to 'no'.\n");
+ ret = 1;
+ }
+
return ret;
}
diff --git a/source/utils/torture.c b/source/utils/torture.c
index 7fef427f364..1277cd2ee32 100644
--- a/source/utils/torture.c
+++ b/source/utils/torture.c
@@ -23,10 +23,55 @@
#include "includes.h"
-static fstring host, workgroup, share, password, username, myname;
+#define MAX_USERS 10
+#define MAX_TIDS 10
+#define MAX_FIDS_PER_TID MAX_USERS
+
+struct cli_state *seed;
+
+typedef struct test_vuser {
+
+ struct cli_state cli;
+
+ fstring username;
+ fstring password;
+ BOOL gotpass;
+ fstring fname;
+
+ int vuid;
+ BOOL vuid_valid;
+ BOOL files_valid;
+
+ struct {
+
+ int tid;
+ int tid_valid;
+
+ int fnum[MAX_FIDS_PER_TID];
+ int backup_fnum[MAX_FIDS_PER_TID];
+ } per_tid[MAX_TIDS];
+
+} TEST_VUSERS;
+
+#if 0
+static struct {
+ fstring *first;
+ fstring *last;
+} errtab; /*keep a list of known errors to reduce noise*/
+#endif
+
+static fstring shares[MAX_TIDS];
+static TEST_VUSERS vusers[MAX_USERS];
+
+static fstring host, workgroup, myname;
+static char *username = vusers[0].username;
+static char *password = vusers[0].password;
+static char *share = shares[0];
+
static int max_protocol = PROTOCOL_NT1;
static char *sockops="TCP_NODELAY";
static int nprocs=1, numops=100;
+static int nusers=1, nshares=0;
static int procnum; /* records process count number when forking */
static struct cli_state current_cli;
static fstring randomfname;
@@ -35,7 +80,6 @@ static BOOL use_level_II_oplocks;
static double create_procs(BOOL (*fn)(int), BOOL *result);
-
static struct timeval tp1,tp2;
static void start_timer(void)
@@ -87,7 +131,6 @@ static void *shm_setup(int size)
return ret;
}
-
static BOOL open_nbt_connection(struct cli_state *c)
{
struct nmb_name called, calling;
@@ -152,7 +195,6 @@ static BOOL open_connection(struct cli_state *c)
return True;
}
-
static BOOL close_connection(struct cli_state *c)
{
BOOL ret = True;
@@ -1005,12 +1047,14 @@ static BOOL run_locktest2(int dummy)
if (cli_unlock(&cli, fnum1, 0, 4)) {
printf("unlock1 succeeded! This is a locking bug\n");
+ correct = False;
} else {
if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False;
}
if (cli_unlock(&cli, fnum1, 0, 8)) {
printf("unlock2 succeeded! This is a locking bug\n");
+ correct = False;
} else {
if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False;
}
@@ -1712,6 +1756,1428 @@ static BOOL run_fdpasstest(int dummy)
return True;
}
+/*test multiple users over a single tcp connection*/
+/*test multiple users over a single tcp connection ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+/*test multiple users over a single tcp connection*/
+
+
+typedef struct subtaboid {
+
+ struct subtaboid *next;
+
+ BOOL status;
+ fstring name;
+ fstring op_error;
+ fstring sys_error;
+
+} SUBTABOID;
+
+typedef struct taboid {
+
+ int owner, share, as_user;
+
+ void *arg;
+
+ SUBTABOID *subtaboids[2];
+
+} TABOID;
+
+static void init_TABOID(TABOID *t, int owner, int share, int as_user)
+{
+ memset( t, '\0', sizeof(*t));
+ t->owner = owner;
+ t->share = share;
+ t->as_user = as_user;
+}
+
+static BOOL run_vusertest_op_null(TABOID *t)
+{
+ return True;
+}
+
+static BOOL run_vusertest_report_full(
+ const char *operation,
+ const char *sub_operation,
+ BOOL failure,
+ BOOL report,
+ fstring *buf,
+ TABOID *t)
+{
+
+ (*buf)[0] = '\0';
+
+ snprintf(*buf,
+ sizeof(*buf),
+ "%8s[%s]:%10s file %10s user %10s(%5d). share %10s tid %5d owner %10s(%5d). fnum %5d was %5d (%s).",
+ operation,
+ failure?"FAILURE":"SUCCESS",
+ sub_operation,
+ vusers[t->owner].fname,
+ vusers[t->as_user].username,
+ /*vusers[t->as_user].vuid,*/
+ vusers[t->as_user].cli.vuid,
+ shares[t->share],
+ /*vusers[t->owner].per_tid[t->share].tid,*/
+ vusers[t->as_user].cli.cnum,
+ vusers[t->owner].username,
+ /*vusers[t->owner].vuid,*/
+ vusers[t->owner].cli.vuid,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner],
+ vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner],
+ failure?cli_errstr(&vusers[t->as_user].cli):""
+ );
+
+ if(report)
+ printf("%s\n", *buf);
+
+ return True;
+}
+
+static BOOL run_vusertest_report(
+ const char *operation,
+ const char *sub_operation,
+ BOOL failure,
+ TABOID *t)
+{
+
+ fstring buf;
+
+ return run_vusertest_report_full(operation, sub_operation, failure, True, &buf, t);
+}
+
+static BOOL run_vusertest_report_failure(
+ const char *operation,
+ const char *sub_operation,
+ TABOID *t)
+{
+
+ fstring buf;
+
+ return run_vusertest_report_full(operation, sub_operation, True, True, &buf, t);
+}
+
+static BOOL run_vusertest_report_success(
+ const char *operation,
+ const char *sub_operation,
+ TABOID *t)
+{
+
+ fstring buf;
+
+ return run_vusertest_report_full(operation, sub_operation, False, True, &buf, t);
+}
+
+static BOOL run_vusertest_op_init(TABOID *t)
+{
+
+ int i, j;
+
+ vusers[t->owner].fname[0] = '\0';
+
+ vusers[t->owner].vuid = 0;
+ vusers[t->owner].vuid_valid = False;
+ vusers[t->owner].files_valid = False;
+
+ for(i = 0; i < sizeof(vusers[t->owner].per_tid)/sizeof(vusers[t->owner].per_tid[0]); i++) {
+
+ vusers[t->owner].per_tid[i].tid = 0;
+ vusers[t->owner].per_tid[i].tid_valid = False;
+
+ for(j = 0; j < sizeof(vusers[t->owner].per_tid[i].fnum)/sizeof(vusers[t->owner].per_tid[i].fnum[0]); j++) {
+
+ vusers[t->owner].per_tid[i].fnum[j] = vusers[t->owner].per_tid[i].backup_fnum[j] = -1;
+ }
+ }
+
+ return True;
+}
+
+static BOOL run_vusertest_op_create(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->owner].per_tid[t->share].tid_valid && vusers[t->as_user].vuid_valid);
+
+ snprintf(vusers[t->owner].fname, sizeof(vusers[t->owner].fname), "muserconn_%d", t->owner);
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ if(!cli_unlink(&vusers[t->as_user].cli, vusers[t->owner].fname)) {
+
+ run_vusertest_report_failure("CREATE", "unlink", t);
+
+ return should_work?False:True;
+ }
+
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] =
+ cli_open(&vusers[t->as_user].cli, vusers[t->owner].fname, O_RDWR|O_CREAT, DENY_NONE);
+
+ if (vusers[t->as_user].per_tid[t->share].fnum[t->owner] == -1) {
+
+ run_vusertest_report_failure("CREATE", "create", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("CREATE", "created", t);
+
+ vusers[t->as_user].files_valid = True; /*not true for all!*/
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_write(TABOID *t)
+{
+
+ BOOL should_work = (
+ vusers[t->owner].per_tid[t->share].tid_valid &&
+ vusers[t->as_user].vuid_valid &&
+ vusers[t->as_user].files_valid
+ );
+
+ fstring msg;
+ int msglen;
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ run_vusertest_report_full("WRITE", "write 2", False, False, &msg, t);
+
+ msglen = strlen(msg)+1;
+
+ if (cli_write(&vusers[t->as_user].cli,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner], 0, (char *)&msglen, 0, sizeof(msglen)) != sizeof(msglen)) {
+
+ run_vusertest_report_failure("WRITE", "write 1", t);
+
+ return should_work?False:True;
+ }
+
+ if (cli_write(&vusers[t->as_user].cli,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner], 0, msg, sizeof(msglen), msglen) != msglen) {
+
+ run_vusertest_report_failure("WRITE", "write 2", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("WRITE", "write", t);
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_create_and_write(TABOID *t)
+{
+
+ BOOL ret = True;
+
+ if(!run_vusertest_op_create(t)) {
+
+ ret = False;
+ }
+
+ if(!run_vusertest_op_write(t)) {
+
+ ret = False;
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_op_openr(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->owner].per_tid[t->share].tid_valid && vusers[t->as_user].vuid_valid);
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] =
+ cli_open(&vusers[t->as_user].cli, vusers[t->owner].fname, O_RDONLY, DENY_NONE);
+
+ if (vusers[t->as_user].per_tid[t->share].fnum[t->owner] == -1) {
+
+ run_vusertest_report_failure("OPENR", "open", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("OPENR", "open", t);
+
+ vusers[t->as_user].files_valid = True; /*not true for all!*/
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_read(TABOID *t)
+{
+
+ fstring msg;
+ int msglen = 0;
+
+ BOOL should_work = (
+ vusers[t->owner].per_tid[t->share].tid_valid &&
+ vusers[t->as_user].vuid_valid &&
+ vusers[t->as_user].files_valid &&
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] != -1
+ );
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ if (cli_read(&vusers[t->as_user].cli,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner], (char *)&msglen, 0, sizeof(msglen)) != sizeof(msglen)) {
+
+ run_vusertest_report_failure("READ", "read 1", t);
+
+ return should_work?False:True;
+ }
+
+ if (cli_read(&vusers[t->as_user].cli,
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner], msg, sizeof(msglen), msglen) != msglen) {
+
+ run_vusertest_report_failure("READ", "read 2", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("READ", "read", t);
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_openr_and_read(TABOID *t)
+{
+
+ BOOL ret = True;
+
+ if(!run_vusertest_op_openr(t)) {
+
+ ret = False;
+ }
+
+ if(!run_vusertest_op_read(t)) {
+
+ ret = False;
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_op_backup_open_fids(TABOID *t)
+{
+
+ memcpy(vusers[t->as_user].per_tid[t->share].backup_fnum,
+ vusers[t->as_user].per_tid[t->share].fnum,
+ sizeof(vusers[t->as_user].per_tid[t->share].fnum));
+
+ return True;
+}
+
+static BOOL run_vusertest_op_close(TABOID *t)
+{
+
+ BOOL should_work = (
+ (
+ vusers[t->owner].per_tid[t->share].tid_valid &&
+ vusers[t->as_user].vuid_valid &&
+ vusers[t->as_user].files_valid
+ )
+ ||
+ (
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] == -1 &&
+ vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner] == -1
+ )
+ );
+
+ BOOL ret = should_work?True:False;
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ if(vusers[t->as_user].per_tid[t->share].fnum[t->owner] != -1) {
+
+ if(!cli_close(&vusers[t->as_user].cli, vusers[t->as_user].per_tid[t->share].fnum[t->owner])) {
+
+ run_vusertest_report_failure("CLOSE", "close", t);
+
+ ret = should_work?False:True;
+ } else {
+
+ run_vusertest_report_success("CLOSE", "close", t);
+ }
+
+ vusers[t->as_user].per_tid[t->share].fnum[t->owner] = -1;
+ }
+
+ if(vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner] != -1 &&
+ vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner] != 0) {
+
+ if(!cli_close(&vusers[t->as_user].cli, vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner])) {
+
+ run_vusertest_report_failure("CLOSE", "close backup", t);
+
+ ret = should_work?False:True;
+
+ } else {
+
+ run_vusertest_report_success("CLOSE", "close backup", t);
+ }
+
+ vusers[t->as_user].per_tid[t->share].backup_fnum[t->owner] = -1;
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_op_tcon(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->as_user].vuid_valid);
+
+ vusers[t->owner].per_tid[t->share].tid_valid = False;
+
+ if (!cli_send_tconX(&vusers[t->as_user].cli,
+ shares[t->share],
+ "?????",
+ vusers[t->as_user].password,
+ strlen(vusers[t->as_user].password)+1)) {
+
+ run_vusertest_report_failure("TCON", "tcon", t);
+
+ return should_work?False:True;
+ }
+
+ vusers[t->owner].per_tid[t->share].tid_valid = True;
+ vusers[t->owner].per_tid[t->share].tid = vusers[t->as_user].cli.cnum;
+
+ run_vusertest_report_success("TCON", "tcon", t);
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_tdis(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->owner].per_tid[t->share].tid_valid && vusers[t->as_user].vuid_valid);
+
+#if 0
+ if(!vusers[t->owner].per_tid[t->share].tid_valid) {
+
+ return True;
+ }
+#endif
+
+ vusers[t->as_user].cli.cnum = vusers[t->owner].per_tid[t->share].tid;
+
+ if(!cli_tdis(&vusers[t->as_user].cli)) {
+
+ run_vusertest_report_failure("TDIS", "tdis", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("TDIS", "tdis", t);
+
+ vusers[t->owner].per_tid[t->share].tid_valid = False;
+
+ return should_work?True:False;
+}
+
+static BOOL run_vusertest_op_ulogon(TABOID *t)
+{
+
+ vusers[t->owner].cli = *seed;
+
+ vusers[t->owner].vuid_valid = False;
+
+ if (!cli_session_setup(&vusers[t->owner].cli,
+ vusers[t->owner].username,
+ vusers[t->owner].password,
+ strlen(vusers[t->owner].password),
+ vusers[t->owner].password,
+ strlen(vusers[t->owner].password),
+ workgroup)) {
+
+
+ run_vusertest_report_failure("ULOGON", "logon", t);
+
+ return False;
+ }
+
+ run_vusertest_report_success("ULOGON", "logon", t);
+
+ vusers[t->owner].vuid_valid = True;
+ vusers[t->owner].vuid = vusers[t->owner].cli.vuid;
+
+ return True;
+}
+
+static BOOL run_vusertest_op_ulogoff(TABOID *t)
+{
+
+ BOOL should_work = (vusers[t->owner].vuid_valid);
+
+#if 0
+ if(!vusers[t->owner].vuid_valid) {
+
+ return True;
+ }
+#endif
+
+ if(!cli_ulogoff(&vusers[t->owner].cli)) {
+
+ run_vusertest_report_failure("ULOGOFF", "logoff", t);
+
+ return should_work?False:True;
+ }
+
+ run_vusertest_report_success("ULOGOFF", "logoff", t);
+
+ vusers[t->owner].vuid_valid = False;
+ vusers[t->owner].files_valid = False;
+
+ return should_work?True:False;
+}
+
+/***********************************************************/
+/***********************************************************/
+
+static BOOL run_vusertest_owner_op(BOOL (*op)(TABOID *t))
+{
+
+ BOOL ret = True;
+
+ int owner = 0;
+
+ for(; owner < nusers; owner++) {
+
+ TABOID t;
+ init_TABOID(&t, owner, 0, owner);
+
+ if(!op(&t)) {
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_owner_share_op(BOOL (*op)(TABOID *t))
+{
+
+ BOOL ret = True;
+
+ int owner = 0;
+
+ for(; owner < nusers; owner++) {
+
+ int share = 0;
+
+ for(; share < nshares; share++) {
+
+ TABOID t;
+ init_TABOID( &t, owner, share, owner);
+
+ if(!op(&t)) {
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_owner_share_preop_user_op(
+ BOOL (*preop)(TABOID *t),
+ BOOL (*op)(TABOID *t),
+ BOOL (*postop)(TABOID *t)
+ )
+{
+
+ BOOL ret = True;
+
+ int owner = 0;
+
+ for(; owner < nusers; owner++) {
+
+ int share = 0;
+
+ for(; share < nshares; share++) {
+
+ TABOID t;
+ init_TABOID( &t, owner, share, owner);
+
+ if(!preop(&t)) {
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+
+ for(t.as_user = 0; t.as_user < nusers; t.as_user++) {
+
+ if(!op(&t)) {
+
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+
+ t.as_user = owner;
+
+ if(!postop(&t)) {
+
+ ret = False;
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+ }
+
+ return ret;
+}
+
+static BOOL run_vusertest_owner_share_user_preop_op(
+ BOOL (*preop)(TABOID *t),
+ BOOL (*op)(TABOID *t),
+ BOOL (*postop)(TABOID *t)
+ )
+{
+
+ BOOL ret = True;
+
+ int owner = 0;
+
+ for(; owner < nusers; owner++) {
+
+ int share = 0;
+
+ for(; share < nshares; share++) {
+
+ int as_user = 0;
+
+ for(; as_user < nusers; as_user++) {
+
+ TABOID t;
+ init_TABOID( &t, owner, share, owner);
+
+ if(!preop(&t)) {
+
+ ret = False;
+
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+
+ t.as_user = as_user;
+
+ if(!op(&t)) {
+
+
+ ret = False;
+
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+
+ t.as_user = owner;
+
+ if(!postop(&t)) {
+
+
+ ret = False;
+
+ printf("^^^^^^^^^^^^^^^^\n");
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*user applies op*/
+
+#define VU_INIT (run_vusertest_owner_op(run_vusertest_op_init))
+
+#define VU_ULOGON (run_vusertest_owner_op(run_vusertest_op_ulogon))
+#define VU_ULOGOFF (run_vusertest_owner_op(run_vusertest_op_ulogoff))
+
+/*each user applies op to each of their shares*/
+
+#define VU_TCON (run_vusertest_owner_share_op(run_vusertest_op_tcon))
+#define VU_TDIS (run_vusertest_owner_share_op(run_vusertest_op_tdis))
+
+#define VU_CREATE_AND_WRITE (run_vusertest_owner_share_op(run_vusertest_op_create_and_write))
+#define VU_OPEN_AND_READ (run_vusertest_owner_share_op(run_vusertest_op_openr_and_read))
+#define VU_READ (run_vusertest_owner_share_op(run_vusertest_op_read))
+#define VU_FCLOSE (run_vusertest_owner_share_op(run_vusertest_op_close))
+#define VU_BACKUP_FIDS (run_vusertest_owner_share_op(run_vusertest_op_backup_open_fids))
+
+/*for u1 for u2 apply op as u2 on u1's tid*/
+
+#define VU_CROSS_READ (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
+ run_vusertest_op_read,\
+ run_vusertest_op_null))
+#define VU_CROSS_OPEN_AND_READ (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
+ run_vusertest_op_openr_and_read,\
+ run_vusertest_op_null))
+#define VU_CROSS_FCLOSE (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
+ run_vusertest_op_close,\
+ run_vusertest_op_null))
+
+#define VU_TCON_TDIS_OPEN_AND_READ (run_vusertest_owner_share_user_preop_op(run_vusertest_op_tcon,\
+ run_vusertest_op_tdis,\
+ run_vusertest_op_openr_and_read))
+
+
+
+/*
+ Check relationship between:
+
+ files open
+
+ session logoff (Samba closes all files for vuid)
+
+ tree disconnection (Samba set conn->used to False then calls close_cnum(conn, vuid), this flushes dir cache, closes files on the conn, frees the conn structure)
+
+ 1. can a user access a tid connected by another
+
+ for u1 {
+ for u2 {
+ u2 opens file on u1's tid
+ }
+ }
+
+ 2. can one user disconnect a tid connected by another
+
+ for u1 {
+ for u2 {
+ connect u1's tid as u1
+ disconnect u1's tid as u2;
+ open and read files as u1
+ }
+}
+
+ 2a. does a disconnect by another invalidate the tid for the original connector
+
+ 3. does a disconnect invalidate a tid with no files open on it
+
+ close files
+ for u1 {
+ disconnect u1's tid
+ open and read files on u1's tid
+ }
+
+ 4. does a disconnect invalidate a tid with files open on it
+
+ open files
+ for u1 {
+ disconnect u1's tid
+ open and read files on u1's tid as u1
+ }
+
+ 5. does a disconnect invalidate files open on a tid.
+
+ open files
+ for u1 {
+ disconnect u1's tid
+ read files on u1's tid as u1
+ }
+
+ 6. can a user session exist with no tid and no open files
+
+ close files
+ for u1 {
+
+ disconnect u1's tid
+ }
+
+ for u1 {
+
+ reconnect u1's tid
+ }
+
+
+ 7. does a logoff invalidate a tid with no files open on it
+
+ close files
+ for u1 {
+ logoff u1
+ open and read files on u1's tid
+ }
+
+ close files
+ for u1 {
+ logon u1
+ open and read files on u1's tid
+ }
+
+ 8. does a logoff invalidate a tid with files open on it
+
+ open files
+ for u1 {
+ logoff u1
+ open and read files on u1's tid
+ }
+
+ for u1 {
+ logon u1
+ open and read files on u1's tid
+ }
+
+ 9. does a logoff invalidate a fid.
+
+ open files
+ for u1 {
+ logoff u1
+ read files on u1's tid
+ }
+
+ for u1 {
+ logon u1
+ read files on u1's tid
+ }
+
+
+ 10. does a logoff invalidate a vuid.
+
+ see 8
+
+ 11. can a connection survive close files, close tids, logoff users
+
+ close files
+ for u1 {
+ disconnect u1's tids
+ logoff u1
+ }
+
+ for u1 {
+ logon u1
+ reconnect u1's tids
+ open and read
+ }
+
+
+
+*/
+
+static BOOL run_vusertest(int dummy)
+{
+ BOOL ret = True;
+
+ int testcnt = 0;
+
+ seed = &vusers[0].cli;
+
+ ZERO_STRUCTP(seed);
+
+ printf("\nopen nbt connection\n");
+
+ if (!open_nbt_connection(seed)) {
+
+ return False;
+ }
+
+ cli_sockopt(seed, sockops);
+
+ printf("\nnegotiate protocol\n");
+
+ /*the CIFS spec says this should be done only once on a VC and W2K doesn't like it more than once. Samba doesn't mind*/
+
+ if (!cli_negprot(seed)) {
+ printf("%s rejected the negprot (%s)\n",host, cli_errstr(seed));
+ cli_shutdown(seed);
+ return False;
+ }
+
+ printf("\nnegotiate protocol again.\n");
+
+ if (!cli_negprot(seed)) {
+
+ printf("%s rejected a second negprot (%s)\n",host, cli_errstr(seed));
+
+ printf("\nshutdown client\n");
+
+ cli_shutdown(seed);
+
+ ZERO_STRUCTP(seed);
+
+ printf("\nopen new nbt session\n");
+
+ if (!open_nbt_connection(seed)) {
+
+ return False;
+ }
+
+ cli_sockopt(seed, sockops);
+
+ printf("\nre negotiate protocol\n");
+
+ if (!cli_negprot(seed)) {
+ printf("%s rejected the negprot (%s)\n",host, cli_errstr(seed));
+ cli_shutdown(seed);
+ return False;
+ }
+ }
+
+ printf("starting vusertest with %d users and %d shares.\n", nusers, nshares);
+
+ /***********************************************************/
+ /***********************************************************/
+
+ printf("\ninitialise\n\n");
+
+ if(!VU_INIT) {
+
+ printf("initialisation failed.\n");
+ return False;
+ }
+
+ printf("\nsetup sessions\n\n");
+
+ if(!VU_ULOGON) {
+
+ printf("setup sessions failed.\n");
+ return False;
+ }
+
+ printf("\nconnect to shares\n\n");
+
+ if(!VU_TCON) {
+
+ printf("connect to shares failed.\n");
+ return False;
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+
+ {
+ char *test = "create and write files";
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_CREATE_AND_WRITE) {
+
+ printf("%s failed.\n", test);
+ return False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "can a user access a tid connected by another?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_CROSS_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_CROSS_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "can one user disconnect a tid connected by another.\n2a does disconnect by another invalidate tid for all?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_TCON_TDIS_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_CROSS_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "does a disconnect invalidate a tid with no files open on it?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "does a disconnect invalidate a tid with files open on it?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "does a disconnect invalidate files open on a tid?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "can a user session exist with no tid and no open files?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+
+ char *test = "does a logoff invalidate a tid with no files open on it?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGON) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "does a logoff invalidate a tid with files open on it?";
+
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGON) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "does a logoff invalidate a fid?";
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!VU_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGON) {
+
+ tret = False;
+ }
+
+ if(!VU_READ) {
+
+ tret = False;
+ }
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ printf("\nTEST:%d does a logoff invalidate a vuid? see 8.\n\n", testcnt);
+
+ testcnt++;
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "can a connection survive close files, disconnect tids, logoff users?";
+ BOOL tret = True;
+
+ printf("\nTEST:%d %s\n\n", testcnt, test);
+
+ testcnt++;
+
+ if(!VU_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGON) {
+
+ tret = False;
+ }
+
+ if(!VU_TCON) {
+
+ tret = False;
+ }
+
+ if(!VU_OPEN_AND_READ) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ /***********************************************************/
+ /***********************************************************/
+
+ {
+ char *test = "clean up.";
+ BOOL tret = True;
+
+ printf("\nTEST:%s\n\n", test);
+
+ if(!VU_CROSS_FCLOSE) {
+
+ tret = False;
+ }
+
+ if(!VU_TDIS) {
+
+ tret = False;
+ }
+
+ if(!VU_ULOGOFF) {
+
+ tret = False;
+ }
+
+ if(!tret) {
+
+ printf("TEST FAILED.\n");
+ ret = False;
+ }
+ }
+
+ cli_shutdown(seed);
+
+ printf("finished vusertest.\n");
+ return ret;
+}
/*
This test checks that
@@ -2039,6 +3505,10 @@ static BOOL run_trans2test(int dummy)
cli_unlink(&cli, fname);
fnum = cli_open(&cli, fname,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+ if (fnum == -1) {
+ printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
+ return False;
+ }
cli_close(&cli, fnum);
if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
@@ -2144,12 +3614,51 @@ static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
return correct;
}
+/****************************************************************************
+ Set or clear the delete on close flag.
+****************************************************************************/
+
+int cli_setfileinfo_test(struct cli_state *cli, int fnum, int level, char *data, int data_len)
+{
+ int param_len = 6;
+ uint16 setup = TRANSACT2_SETFILEINFO;
+ pstring param;
+ char *rparam=NULL, *rdata=NULL;
+
+ memset(param, 0, param_len);
+ SSVAL(param,0,fnum);
+ SSVAL(param,2,level);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ data, data_len, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
+ }
+
+ if (rdata) free(rdata);
+ if (rparam) free(rparam);
+
+ return True;
+}
+
static BOOL run_w2ktest(int dummy)
{
static struct cli_state cli;
int fnum;
char *fname = "\\w2ktest\\w2k.tst";
+ char *fname1 = "\\w2ktest\\w2k.dir";
int level;
+ char data;
BOOL correct = True;
printf("starting w2k test\n");
@@ -2162,12 +3671,41 @@ static BOOL run_w2ktest(int dummy)
O_RDWR | O_CREAT , DENY_NONE);
for (level = 1004; level < 1040; level++) {
- if (!new_trans(&cli, fnum, level)) {
- correct = False;
- }
+ new_trans(&cli, fnum, level);
}
cli_close(&cli, fnum);
+ cli_unlink(&cli, fname);
+
+ /* Check the strange 1013 setinfo call. */
+ cli_mkdir(&cli, fname1);
+ fnum = cli_nt_create_full( &cli, fname1, 0x60080, 0, 7,
+ 1, 0);
+
+ data = 1;
+ if (!cli_setfileinfo_test( &cli, fnum, 1013, &data, 1)) {
+ printf("setfileinfo test 1 failed with %s\n", cli_errstr(&cli));
+ }
+ data = 0;
+ if (!cli_setfileinfo_test( &cli, fnum, 1013, &data, 1)) {
+ printf("setfileinfo test 2 failed with %s\n", cli_errstr(&cli));
+ }
+
+ cli_close(&cli, fnum);
+ cli_rmdir(&cli, fname1);
+
+ fnum = cli_open(&cli, fname, O_RDWR | O_CREAT , DENY_NONE);
+
+ cli_write(&cli, fnum, 0, (char *)&data, 0, sizeof(data));
+ cli_close(&cli, fnum);
+ cli_ulogoff(&cli);
+
+ fnum = cli_open(&cli, fname, O_RDWR , DENY_NONE);
+ if (cli_read(&cli, fnum, &data, 0, 1) != 1) {
+ printf("x test 2 failed with %s\n", cli_errstr(&cli));
+ }
+ cli_close(&cli, fnum);
+ cli_unlink(&cli, fname);
if (!close_connection(&cli)) {
correct = False;
@@ -2955,8 +4493,6 @@ static BOOL run_dirtest(int dummy)
return correct;
}
-
-
static double create_procs(BOOL (*fn)(int), BOOL *result)
{
int i, status;
@@ -3051,7 +4587,10 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
}
-#define FLAG_MULTIPROC 1
+#define FLAG_MULTIPROC (1<<0)
+#define FLAG_MULTIUSER (1<<1)
+#define FLAG_MULTISHARE (1<<2)
+#define FLAG_PROBE (1<<3)
static struct {
char *name;
@@ -3086,6 +4625,7 @@ static struct {
{"OPEN", run_opentest, 0},
{"DELETE", run_deletetest, 0},
{"W2K", run_w2ktest, 0},
+ {"VU", run_vusertest, FLAG_MULTIUSER | FLAG_MULTISHARE},
{NULL, NULL, 0}};
@@ -3093,6 +4633,29 @@ static struct {
/****************************************************************************
run a specified test or "ALL"
****************************************************************************/
+
+static BOOL get_test_flags(char *name, BOOL *flags) {
+
+ int i;
+
+ BOOL all = strequal(name,"ALL") == 0;
+
+ for (i=0;torture_ops[i].name;i++) {
+
+ if (all || strequal(name, torture_ops[i].name)) {
+
+ *flags |= torture_ops[i].flags;
+
+ if(!all) {
+
+ break;
+ }
+ }
+ }
+
+ return True;
+}
+
static BOOL run_test(char *name)
{
BOOL ret = True;
@@ -3137,10 +4700,11 @@ static void usage(void)
{
int i;
- printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
+ printf("Usage: smbtorture //server/share[,share...] <options> TEST1 TEST2 ...\n");
printf("\t-d debuglevel\n");
printf("\t-U user%%pass\n");
+ printf("\t-u user%%pass[,user%%pass...]\n");
printf("\t-N numprocs\n");
printf("\t-n my_netbios_name\n");
printf("\t-W workgroup\n");
@@ -3161,23 +4725,77 @@ static void usage(void)
exit(1);
}
+static BOOL split_password_from_username(char *username, char *password) {
+
+ char * pp = strchr(username,'%');
+ if (pp) {
+ *pp = 0;
+ pstrcpy(password, pp+1);
+ return True;
+ }
+
+ return False;
+}
+
+static BOOL extract_users(char *user_list) {
+
+ const char *separators = ",";
+
+ char *p = strtok(user_list, separators);
+
+ while(p && nusers < MAX_USERS) {
+
+ vusers[nusers].username[0] = '\0';
+ vusers[nusers].password[0] = '\0';
+ vusers[nusers].gotpass = False;
+
+ pstrcpy(vusers[nusers].username, p);
+
+ vusers[nusers].gotpass = split_password_from_username(vusers[nusers].username, vusers[nusers].password);
+
+ nusers++;
+
+ p = strtok(NULL, separators);
+ }
+
+ return True;
+}
+static BOOL extract_shares(char *share_list) {
+ const char *separators = ",";
+ char *p = strtok(share_list, separators);
+
+ while(p && nshares < MAX_TIDS) {
+
+ pstrcpy(shares[nshares], p);
+
+ nshares++;
+
+ p = strtok(NULL, separators);
+ }
+
+ return True;
+}
/****************************************************************************
main program
****************************************************************************/
+
int main(int argc,char *argv[])
{
int opt, i;
char *p;
- int gotpass = 0;
+ int test_flags = 0;
+ BOOL *gotpass = &vusers[0].gotpass;
extern char *optarg;
extern int optind;
extern FILE *dbf;
static pstring servicesf = CONFIGFILE;
BOOL correct = True;
+ fstring user_list;
+ fstring share_list;
dbf = stdout;
@@ -3210,22 +4828,23 @@ static void usage(void)
if (!p) {
usage();
}
+
*p = 0;
- fstrcpy(share, p+1);
+ fstrcpy(share_list, p+1);
get_myname(myname);
if (*username == 0 && getenv("LOGNAME")) {
+
pstrcpy(username,getenv("LOGNAME"));
}
argc--;
argv++;
-
fstrcpy(workgroup, lp_workgroup());
- while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:")) != EOF) {
+ while ((opt = getopt(argc, argv, "hW:U:u:n:N:O:o:m:Ld:")) != EOF) {
switch (opt) {
case 'W':
fstrcpy(workgroup,optarg);
@@ -3253,11 +4872,12 @@ static void usage(void)
break;
case 'U':
pstrcpy(username,optarg);
- p = strchr(username,'%');
- if (p) {
- *p = 0;
- pstrcpy(password, p+1);
- gotpass = 1;
+ *gotpass = split_password_from_username(username, password);
+ break;
+ case 'u':
+ pstrcpy(user_list, optarg);
+ if(!extract_users(user_list)) {
+ usage();
}
break;
default:
@@ -3266,17 +4886,76 @@ static void usage(void)
}
}
+ if (argc == 1) {
+ get_test_flags("ALL", &test_flags);
+ } else {
+ for (i=1;i<argc;i++) {
+
+ get_test_flags(argv[i], &test_flags);
+ }
+ }
- while (!gotpass) {
- p = getpass("Password:");
+ while (!*gotpass) {
+ fstring s;
+ snprintf(s, sizeof(s), "Password for user %s:", username);
+ p = getpass(s);
if (p) {
pstrcpy(password, p);
- gotpass = 1;
+ *gotpass = True;
}
}
- printf("host=%s share=%s user=%s myname=%s\n",
- host, share, username, myname);
+ extract_shares(share_list);
+
+ if(test_flags & FLAG_MULTIUSER) {
+
+ if(nusers == 1) {
+
+ /*generate another user from the one that is already specified*/
+
+ vusers[nusers] = vusers[nusers-1];
+
+ nusers++;
+ }
+
+ for(i = 1; i < nusers; i++) {
+
+ fstring s;
+
+ if(vusers[i].gotpass) {
+
+ continue;
+ }
+
+ snprintf(s, sizeof(s), "Password for user %s:", vusers[i].username);
+
+ p = getpass(s);
+ if (p) {
+
+ pstrcpy(vusers[i].password, p);
+ vusers[i].gotpass = True;
+ }
+ }
+ }
+
+ user_list[0] = '\0';
+
+ for(i = 0; i < nusers; i++) {
+
+ if(!vusers[i].gotpass) {
+
+ continue;
+ }
+
+ if(i) {
+
+ fstrcat(user_list, ", ");
+ }
+
+ fstrcat(user_list, vusers[i].username);
+ }
+
+ printf("host=%s shares=%s users=%s myname=%s\n", host, share_list, user_list, myname);
if (argc == 1) {
correct = run_test("ALL");
diff --git a/source/web/cgi.c b/source/web/cgi.c
index e4fda2d99cd..70299f14c34 100644
--- a/source/web/cgi.c
+++ b/source/web/cgi.c
@@ -85,16 +85,23 @@ static void unescape(char *buf)
static char *grab_line(FILE *f, int *cl)
{
- char *ret;
+ char *ret = NULL;
int i = 0;
- int len = 1024;
-
- ret = (char *)malloc(len);
- if (!ret) return NULL;
-
+ int len = 0;
while ((*cl)) {
- int c = fgetc(f);
+ int c;
+
+ if (i == len) {
+ char *ret2;
+ if (len == 0) len = 1024;
+ else len *= 2;
+ ret2 = (char *)Realloc(ret, len);
+ if (!ret2) return ret;
+ ret = ret2;
+ }
+
+ c = fgetc(f);
(*cl)--;
if (c == EOF) {
@@ -108,13 +115,6 @@ static char *grab_line(FILE *f, int *cl)
ret[i++] = c;
- if (i == len-1) {
- char *ret2;
- ret2 = (char *)realloc(ret, len*2);
- if (!ret2) return ret;
- len *= 2;
- ret = ret2;
- }
}
diff --git a/source/web/statuspage.c b/source/web/statuspage.c
index f3b07425b78..fd251f89c50 100644
--- a/source/web/statuspage.c
+++ b/source/web/statuspage.c
@@ -21,8 +21,79 @@
#include "includes.h"
+#define PIDMAP struct PidMap
+
+PIDMAP {
+ PIDMAP *next, *prev;
+ pid_t pid;
+ char *machine;
+};
+
+static PIDMAP *pidmap;
+static int PID_or_Machine; /* 0 = show PID, else show Machine name */
+
static pid_t smbd_pid;
+/* from 2nd call on, remove old list */
+static void initPid2Machine (void)
+{
+ /* show machine name rather PID on table "Open Files"? */
+ if (PID_or_Machine) {
+ PIDMAP *p, *q;
+
+ for (p = pidmap; p != NULL; ) {
+ DLIST_REMOVE(pidmap, p);
+ SAFE_FREE(p->machine);
+ SAFE_FREE(p);
+ }
+
+ pidmap = NULL;
+ }
+}
+
+/* add new PID <-> Machine name mapping */
+static void addPid2Machine (pid_t pid, char *machine)
+{
+ /* show machine name rather PID on table "Open Files"? */
+ if (PID_or_Machine) {
+ PIDMAP *newmap;
+
+ if ((newmap = (PIDMAP *) malloc (sizeof (PIDMAP))) == NULL) {
+ /* XXX need error message for this?
+ if malloc fails, PID is always shown */
+ return;
+ }
+
+ newmap->pid = pid;
+ newmap->machine = strdup (machine);
+
+ DLIST_ADD(pidmap, newmap);
+ }
+}
+
+/* lookup PID <-> Machine name mapping */
+static char *mapPid2Machine (pid_t pid)
+{
+ static char pidbuf [64];
+ PIDMAP *map;
+
+ /* show machine name rather PID on table "Open Files"? */
+ if (PID_or_Machine) {
+ for (map = pidmap; map != NULL; map = map->next) {
+ if (pid == map->pid) {
+ if (map->machine == NULL) /* no machine name */
+ break; /* show PID */
+
+ return map->machine;
+ }
+ }
+ }
+
+ /* PID not in list or machine name NULL? return pid as string */
+ snprintf (pidbuf, sizeof (pidbuf) - 1, "%d", pid);
+ return pidbuf;
+}
+
static char *tstring(time_t t)
{
static pstring buf;
@@ -33,7 +104,7 @@ static char *tstring(time_t t)
static void print_share_mode(share_mode_entry *e, char *fname)
{
- printf("<tr><td>%d</td>",(int)e->pid);
+ printf("<tr><td>%s</td>", mapPid2Machine (e->pid));
printf("<td>");
switch ((e->share_mode>>4)&0xF) {
case DENY_NONE: printf("DENY_NONE"); break;
@@ -105,6 +176,8 @@ static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* st
if (crec.cnum != -1 || !process_exists(crec.pid) || (crec.pid == smbd_pid))
return 0;
+ addPid2Machine (crec.pid, crec.machine);
+
printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
(int)crec.pid,
crec.machine,crec.addr,
@@ -187,9 +260,15 @@ void status_page(void)
refresh_interval = atoi(v);
}
- tdb = tdb_open_log(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0);
+ if (cgi_variable("show_client_in_col_1")) {
+ PID_or_Machine = 1;
+ }
+
+ tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
if (tdb) tdb_traverse(tdb, traverse_fn1, NULL);
+ initPid2Machine ();
+
printf("<H2>Server Status</H2>\n");
printf("<FORM method=post>\n");
@@ -268,7 +347,7 @@ void status_page(void)
printf("<h3>Open Files</h3>\n");
printf("<table border=1>\n");
- printf("<tr><th>PID</th><th>Sharing</th><th>R/W</th><th>Oplock</th><th>File</th><th>Date</th></tr>\n");
+ printf("<tr><th>%s</th><th>Sharing</th><th>R/W</th><th>Oplock</th><th>File</th><th>Date</th></tr>\n", PID_or_Machine ? "Client" : "PID");
locking_init(1);
share_mode_forall(print_share_mode);
@@ -277,6 +356,9 @@ void status_page(void)
if (tdb) tdb_close(tdb);
+ printf("<br><input type=submit name=\"show_client_in_col_1\" value=\"Show Client in col 1\">\n");
+ printf("<input type=submit name=\"show_pid_in_col_1\" value=\"Show PID in col 1\">\n");
+
printf("</FORM>\n");
if (autorefresh) {
diff --git a/source/web/swat.c b/source/web/swat.c
index 2a141e9898e..251707e74e9 100644
--- a/source/web/swat.c
+++ b/source/web/swat.c
@@ -659,7 +659,7 @@ static BOOL change_password(const char *remote_machine, char *user_name,
return ret;
}
- if(!initialize_password_db()) {
+ if(!initialize_password_db(False)) {
printf("Can't setup password database vectors.\n<p>");
return False;
}