summaryrefslogtreecommitdiff
path: root/source3/utils
diff options
context:
space:
mode:
Diffstat (limited to 'source3/utils')
-rw-r--r--source3/utils/log2pcaphex.c294
-rw-r--r--source3/utils/net.c111
-rw-r--r--source3/utils/net_ads.c91
-rw-r--r--source3/utils/net_ads_cldap.c28
-rw-r--r--source3/utils/net_groupmap.c17
-rw-r--r--source3/utils/net_help.c10
-rw-r--r--source3/utils/net_lookup.c38
-rw-r--r--source3/utils/net_rpc.c34
-rw-r--r--source3/utils/net_rpc_samsync.c37
-rw-r--r--source3/utils/nmblookup.c2
-rw-r--r--source3/utils/ntlm_auth.c474
-rw-r--r--source3/utils/profiles.c2
-rw-r--r--source3/utils/smbcacls.c4
-rw-r--r--source3/utils/smbgroupedit.c405
-rw-r--r--source3/utils/status.c2
-rw-r--r--source3/utils/testparm.c21
16 files changed, 938 insertions, 632 deletions
diff --git a/source3/utils/log2pcaphex.c b/source3/utils/log2pcaphex.c
new file mode 100644
index 0000000000..4804b99338
--- /dev/null
+++ b/source3/utils/log2pcaphex.c
@@ -0,0 +1,294 @@
+/*
+ Unix SMB/CIFS implementation.
+ Utility to extract pcap files from samba (log level 10) log files
+
+ Copyright (C) Jelmer Vernooij 2003
+ Thanks to Tim Potter for the genial idea
+
+ Portions (from capconvert.c) (C) Andrew Tridgell 1997
+ Portions (from text2pcap.c) (C) Ashok Narayanan 2001
+
+ Example use with -h parameter:
+ log2pcaphex < samba-log-file | text2pcap -T 139,139 - foo.pcap
+
+ TODO: Have correct IP and TCP checksums.
+
+ 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.
+*/
+
+#include "includes.h"
+#include <assert.h>
+
+int quiet = 0;
+int hexformat = 0;
+
+#define itoa(a) ((a) < 0xa?'0'+(a):'A' + (a-0xa))
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+/* tcpdump file format */
+struct tcpdump_file_header {
+ uint32 magic;
+ uint16 major;
+ uint16 minor;
+ int32 zone;
+ uint32 sigfigs;
+ uint32 snaplen;
+ uint32 linktype;
+};
+
+struct tcpdump_packet {
+ struct timeval ts;
+ uint32 caplen;
+ uint32 len;
+};
+
+typedef struct {
+ uint8 ver_hdrlen;
+ uint8 dscp;
+ uint16 packet_length;
+ uint16 identification;
+ uint8 flags;
+ uint8 fragment;
+ uint8 ttl;
+ uint8 protocol;
+ uint16 hdr_checksum;
+ uint32 src_addr;
+ uint32 dest_addr;
+} hdr_ip_t;
+
+static hdr_ip_t HDR_IP = {0x45, 0, 0, 0x3412, 0, 0, 0xff, 6, 0, 0x01010101, 0x02020202};
+
+typedef struct {
+ uint16 source_port;
+ uint16 dest_port;
+ uint32 seq_num;
+ uint32 ack_num;
+ uint8 hdr_length;
+ uint8 flags;
+ uint16 window;
+ uint16 checksum;
+ uint16 urg;
+} hdr_tcp_t;
+
+static hdr_tcp_t HDR_TCP = {139, 139, 0, 0, 0x50, 0, 0, 0, 0};
+
+void print_pcap_header(FILE *out)
+{
+ struct tcpdump_file_header h;
+ h.magic = TCPDUMP_MAGIC;
+ h.major = 2;
+ h.minor = 4;
+ h.zone = 0;
+ h.sigfigs = 0;
+ h.snaplen = 102400; /* As long packets as possible */
+ h.linktype = 101; /* Raw IP */
+ fwrite(&h, sizeof(struct tcpdump_file_header), 1, out);
+}
+
+void print_pcap_packet(FILE *out, unsigned char *data, long length, long caplen)
+{
+ static int i = 0;
+ struct tcpdump_packet p;
+ i++;
+ p.ts.tv_usec = 0;
+ p.ts.tv_sec = 0;
+ p.caplen = caplen;
+ p.len = length;
+ fwrite(&p, sizeof(struct tcpdump_packet), 1, out);
+ fwrite(data, sizeof(unsigned char), caplen, out);
+}
+
+void print_hex_packet(FILE *out, unsigned char *data, long length)
+{
+ long i,cur = 0;
+ while(cur < length) {
+ fprintf(out, "%06lX ", cur);
+ for(i = cur; i < length && i < cur + 16; i++) {
+ fprintf(out, "%02x ", data[i]);
+ }
+
+ cur = i;
+ fprintf(out, "\n");
+ }
+}
+
+void print_netbios_packet(FILE *out, unsigned char *data, long length, long actual_length)
+{
+ unsigned char *newdata; long offset = 0;
+ long newlen;
+
+ newlen = length+sizeof(HDR_IP)+sizeof(HDR_TCP);
+ newdata = malloc(newlen);
+
+ HDR_IP.packet_length = htons(newlen);
+ HDR_TCP.window = htons(0x2000);
+ HDR_TCP.source_port = HDR_TCP.dest_port = htons(139);
+
+ memcpy(newdata+offset, &HDR_IP, sizeof(HDR_IP));offset+=sizeof(HDR_IP);
+ memcpy(newdata+offset, &HDR_TCP, sizeof(HDR_TCP));offset+=sizeof(HDR_TCP);
+ memcpy(newdata+offset,data,length);
+
+ print_pcap_packet(out, newdata, newlen, actual_length+offset);
+ free(newdata);
+}
+
+unsigned char *curpacket = NULL;
+long curpacket_len = 0;
+
+void read_log_msg(FILE *in, unsigned char **_buffer, long *buffersize, long *data_offset, long *data_length)
+{
+ unsigned char *buffer;
+ int tmp; long i;
+ assert(fscanf(in, " size=%ld\n", buffersize));
+ *buffersize+=4; /* for netbios */
+ buffer = malloc(*buffersize);
+ memset(buffer, 0, *buffersize);
+ /* NetBIOS */
+ buffer[0] = 0x00;
+ buffer[1] = 0x00;
+ memcpy(buffer+2, &buffersize, 2);
+ buffer[4] = 0xFF;
+ buffer[5] = 'S';
+ buffer[6] = 'M';
+ buffer[7] = 'B';
+ assert(fscanf(in, " smb_com=0x%x\n", &tmp)); buffer[smb_com] = tmp;
+ assert(fscanf(in, " smb_rcls=%d\n", &tmp)); buffer[smb_rcls] = tmp;
+ assert(fscanf(in, " smb_reh=%d\n", &tmp)); buffer[smb_reh] = tmp;
+ assert(fscanf(in, " smb_err=%d\n", &tmp)); memcpy(buffer+smb_err, &tmp, 2);
+ assert(fscanf(in, " smb_flg=%d\n", &tmp)); buffer[smb_flg] = tmp;
+ assert(fscanf(in, " smb_flg2=%d\n", &tmp)); memcpy(buffer+smb_flg2, &tmp, 2);
+ assert(fscanf(in, " smb_tid=%d\n", &tmp)); memcpy(buffer+smb_tid, &tmp, 2);
+ assert(fscanf(in, " smb_pid=%d\n", &tmp)); memcpy(buffer+smb_pid, &tmp, 2);
+ assert(fscanf(in, " smb_uid=%d\n", &tmp)); memcpy(buffer+smb_uid, &tmp, 2);
+ assert(fscanf(in, " smb_mid=%d\n", &tmp)); memcpy(buffer+smb_mid, &tmp, 2);
+ assert(fscanf(in, " smt_wct=%d\n", &tmp)); buffer[smb_wct] = tmp;
+ for(i = 0; i < buffer[smb_wct]; i++) {
+ assert(fscanf(in, " smb_vwv[%*2d]=%*5d (0x%X)\n", &tmp));
+ memcpy(buffer+smb_vwv+i*2, &tmp, 2);
+ }
+
+ *data_offset = smb_vwv+buffer[smb_wct]*2;
+ assert(fscanf(in, " smb_bcc=%ld\n", data_length)); buffer[(*data_offset)] = *data_length;
+ (*data_offset)+=2;
+ *_buffer = buffer;
+}
+
+long read_log_data(FILE *in, unsigned char *buffer, long data_length)
+{
+ long i, addr; char real[2][16]; int ret;
+ unsigned char tmp;
+ for(i = 0; i < data_length; i++) {
+ if(i % 16 == 0){
+ if(i != 0) { /* Read data after each line */
+ assert(fscanf(in, "%8s %8s", real[0], real[1]) == 2);
+ }
+ ret = fscanf(in, " [%03lX]", &addr);
+ if(!ret) {
+ if(!quiet)fprintf(stderr, "Only first %ld bytes are logged, packet trace will be incomplete\nTry a higher log level\n", i);
+ return i-1;
+ }
+ assert(addr == i);
+ }
+ if(!fscanf(in, "%02lX", &tmp)) {
+ if(!quiet)fprintf(stderr, "Only first %ld bytes are logged, packet trace will be incomplete\nTry a higher log level\n", i-1);
+ return i-1;
+ }
+ buffer[i] = tmp;
+ }
+ return data_length;
+}
+
+int main (int argc, char **argv)
+{
+ const char *infile, *outfile;
+ FILE *out, *in;
+ int opt;
+ poptContext pc;
+ char buffer[4096];
+ long data_offset, data_length;
+ long data_bytes_read;
+ int in_packet = 0;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "quiet", 'q', POPT_ARG_NONE, &quiet, 0, "Be quiet, don't output warnings" },
+ { "hex", 'h', POPT_ARG_NONE, &hexformat, 0, "Output format readable by text2pcap" },
+ POPT_TABLEEND
+ };
+
+ pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
+ POPT_CONTEXT_KEEP_FIRST);
+ poptSetOtherOptionHelp(pc, "[<infile> [<outfile>]]");
+
+
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch (opt) {
+ }
+ }
+
+ poptGetArg(pc); /* Drop argv[0], the program name */
+
+ infile = poptGetArg(pc);
+
+ if(infile) {
+ in = fopen(infile, "r");
+ if(!in) {
+ perror("fopen");
+ return 1;
+ }
+ } else in = stdin;
+
+ outfile = poptGetArg(pc);
+
+ if(outfile) {
+ out = fopen(outfile, "w+");
+ if(!out) {
+ perror("fopen");
+ fprintf(stderr, "Can't find %s, using stdout...\n", outfile);
+ }
+ }
+
+ if(!outfile) out = stdout;
+
+ if(!hexformat)print_pcap_header(out);
+
+ while(!feof(in)) {
+ fgets(buffer, sizeof(buffer), in);
+ if(buffer[0] == '[') { /* Header */
+ if(strstr(buffer, "show_msg")) {
+ in_packet++;
+ if(in_packet == 1)continue;
+ read_log_msg(in, &curpacket, &curpacket_len, &data_offset, &data_length);
+ } else if(in_packet && strstr(buffer, "dump_data")) {
+ data_bytes_read = read_log_data(in, curpacket+data_offset, data_length);
+ } else {
+ if(in_packet){
+ if(hexformat) print_hex_packet(out, curpacket, curpacket_len);
+ else print_netbios_packet(out, curpacket, curpacket_len, data_bytes_read+data_offset);
+ free(curpacket);
+ }
+ in_packet = 0;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/source3/utils/net.c b/source3/utils/net.c
index 8f6b09a3fa..e5c078da29 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -181,6 +181,27 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
}
}
+/****************************************************************************
+ Use the local machine's password for this session
+****************************************************************************/
+int net_use_machine_password(void)
+{
+ char *user_name = NULL;
+
+ if (!secrets_init()) {
+ d_printf("ERROR: Unable to open secrets database\n");
+ exit(1);
+ }
+
+ user_name = NULL;
+ opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
+ if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
+ return -1;
+ }
+ opt_user_name = user_name;
+ return 0;
+}
+
BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_name)
{
@@ -321,7 +342,7 @@ static int net_join(int argc, const char **argv)
if (net_ads_join(argc, argv) == 0)
return 0;
else
- d_printf("ADS join did not work, trying RPC...\n");
+ d_printf("ADS join did not work, falling back to RPC...\n");
}
return net_rpc_join(argc, argv);
}
@@ -334,6 +355,31 @@ static int net_changetrustpw(int argc, const char **argv)
return net_rpc_changetrustpw(argc, argv);
}
+static int net_changesecretpw(int argc, const char **argv)
+{
+ char *trust_pw;
+ uint32 sec_channel_type = SEC_CHAN_WKSTA;
+
+ if(opt_force) {
+ trust_pw = getpass("Enter machine password: ");
+
+ if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
+ d_printf("Unable to write the machine account password in the secrets database");
+ return 1;
+ }
+ else {
+ d_printf("Modified trust account password in secrets database\n");
+ }
+ }
+ else {
+ d_printf("Machine account password change requires the -f flag.\n");
+ d_printf("Do NOT use this function unless you know what it does!\n");
+ d_printf("This function will change the ADS Domain member machine account password in the secrets.tdb file!\n");
+ }
+
+ return 0;
+}
+
static int net_share(int argc, const char **argv)
{
if (net_rpc_check(0))
@@ -416,6 +462,50 @@ static int net_getdomainsid(int argc, const char **argv)
return 0;
}
+#ifdef WITH_FAKE_KASERVER
+
+int net_afskey_usage(int argc, const char **argv)
+{
+ d_printf(" net afskey filename\n"
+ "\tImports a OpenAFS KeyFile into our secrets.tdb\n\n");
+ return -1;
+}
+
+static int net_afskey(int argc, const char **argv)
+{
+ int fd;
+ struct afs_keyfile keyfile;
+
+ if (argc != 1) {
+ d_printf("usage: 'net afskey <keyfile>'\n");
+ return -1;
+ }
+
+ if (!secrets_init()) {
+ d_printf("Could not open secrets.tdb\n");
+ return -1;
+ }
+
+ if ((fd = open(argv[0], O_RDONLY, 0)) < 0) {
+ d_printf("Could not open %s\n", argv[0]);
+ return -1;
+ }
+
+ if (read(fd, &keyfile, sizeof(keyfile)) != sizeof(keyfile)) {
+ d_printf("Could not read keyfile\n");
+ return -1;
+ }
+
+ if (!secrets_store_afs_keyfile(afs_cell(), &keyfile)) {
+ d_printf("Could not write keyfile to secrets.tdb\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+#endif /* WITH_FAKE_KASERVER */
+
static uint32 get_maxrid(void)
{
SAM_ACCOUNT *pwd = NULL;
@@ -516,6 +606,7 @@ static struct functable net_func[] = {
{"SERVICE", net_rap_service},
{"PASSWORD", net_rap_password},
{"CHANGETRUSTPW", net_changetrustpw},
+ {"CHANGESECRETPW", net_changesecretpw},
{"TIME", net_time},
{"LOOKUP", net_lookup},
{"JOIN", net_join},
@@ -525,6 +616,9 @@ static struct functable net_func[] = {
{"GETDOMAINSID", net_getdomainsid},
{"MAXRID", net_maxrid},
{"IDMAP", net_idmap},
+#ifdef WITH_FAKE_KASERVER
+ {"AFSKEY", net_afskey},
+#endif
{"HELP", net_help},
{NULL, NULL}
@@ -649,23 +743,10 @@ static struct functable net_func[] = {
sec_init();
if (opt_machine_pass) {
- char *user = NULL;
/* it is very useful to be able to make ads queries as the
machine account for testing purposes and for domain leave */
- if (!secrets_init()) {
- d_printf("ERROR: Unable to open secrets database\n");
- exit(1);
- }
-
- opt_password = secrets_fetch_machine_password(opt_workgroup, NULL, NULL);
-
- asprintf(&user,"%s$", global_myname());
- opt_user_name = user;
- if (!opt_password) {
- d_printf("ERROR: Unable to fetch machine password\n");
- exit(1);
- }
+ net_use_machine_password();
}
if (!opt_password) {
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 631e235127..3b955742d8 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -127,9 +127,14 @@ static ADS_STRUCT *ads_startup(void)
ADS_STATUS status;
BOOL need_password = False;
BOOL second_time = False;
- char *cp;
+ char *cp;
- ads = ads_init(NULL, opt_target_workgroup, opt_host);
+ /* lp_realm() should be handled by a command line param,
+ However, the join requires that realm be set in smb.conf
+ and compares our realm with the remote server's so this is
+ ok until someone needs more flexibility */
+
+ ads = ads_init(lp_realm(), opt_target_workgroup, opt_host);
if (!opt_user_name) {
opt_user_name = "administrator";
@@ -579,10 +584,7 @@ static int net_ads_leave(int argc, const char **argv)
}
if (!opt_password) {
- char *user_name;
- asprintf(&user_name, "%s$", global_myname());
- opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
- opt_user_name = user_name;
+ net_use_machine_password();
}
if (!(ads = ads_startup())) {
@@ -603,7 +605,6 @@ static int net_ads_leave(int argc, const char **argv)
static int net_ads_join_ok(void)
{
- char *user_name;
ADS_STRUCT *ads = NULL;
if (!secrets_init()) {
@@ -611,9 +612,7 @@ static int net_ads_join_ok(void)
return -1;
}
- asprintf(&user_name, "%s$", global_myname());
- opt_user_name = user_name;
- opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
+ net_use_machine_password();
if (!(ads = ads_startup())) {
return -1;
@@ -648,6 +647,7 @@ int net_ads_join(int argc, const char **argv)
ADS_STRUCT *ads;
ADS_STATUS rc;
char *password;
+ char *machine_account = NULL;
char *tmp_password;
const char *org_unit = "Computers";
char *dn;
@@ -656,6 +656,8 @@ int net_ads_join(int argc, const char **argv)
char *ou_str;
uint32 sec_channel_type = SEC_CHAN_WKSTA;
uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT;
+ char *short_domain_name = NULL;
+ TALLOC_CTX *ctx = NULL;
if (argc > 0) org_unit = argv[0];
@@ -669,6 +671,16 @@ int net_ads_join(int argc, const char **argv)
if (!(ads = ads_startup())) return -1;
+ if (!*lp_realm()) {
+ d_printf("realm must be set in in smb.conf for ADS join to succeed.\n");
+ return -1;
+ }
+
+ if (strcmp(ads->config.realm, lp_realm()) != 0) {
+ d_printf("realm of remote server (%s) and realm in smb.conf (%s) DO NOT match. Aborting join\n", ads->config.realm, lp_realm());
+ return -1;
+ }
+
ou_str = ads_ou_string(org_unit);
asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path);
free(ou_str);
@@ -696,16 +708,47 @@ int net_ads_join(int argc, const char **argv)
rc = ads_domain_sid(ads, &dom_sid);
if (!ADS_ERR_OK(rc)) {
- d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
+ d_printf("ads_domain_sid: %s\n", ads_errstr(rc));
+ return -1;
+ }
+
+ if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
+ d_printf("asprintf failed\n");
return -1;
}
- rc = ads_set_machine_password(ads, global_myname(), password);
+ rc = ads_set_machine_password(ads, machine_account, password);
if (!ADS_ERR_OK(rc)) {
d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
return -1;
}
-
+
+ /* make sure we get the right workgroup */
+
+ if ( !(ctx = talloc_init("net ads join")) ) {
+ d_printf("talloc_init() failed!\n");
+ return -1;
+ }
+
+ rc = ads_workgroup_name(ads, ctx, &short_domain_name);
+ if ( ADS_ERR_OK(rc) ) {
+ if ( !strequal(lp_workgroup(), short_domain_name) ) {
+ d_printf("The workgroup in smb.conf does not match the short\n");
+ d_printf("domain name obtained from the server.\n");
+ d_printf("Using the name [%s] from the server.\n", short_domain_name);
+ d_printf("You should set \"workgroup = %s\" in smb.conf.\n", short_domain_name);
+ }
+ }
+ else
+ short_domain_name = lp_workgroup();
+
+ d_printf("Using short domain name -- %s\n", short_domain_name);
+
+ /* HACK ALRET! Store the sid and password under bother the lp_workgroup()
+ value from smb.conf and the string returned from the server. The former is
+ neede to bootstrap winbindd's first connection to the DC to get the real
+ short domain name --jerry */
+
if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
DEBUG(1,("Failed to save domain sid\n"));
return -1;
@@ -716,10 +759,22 @@ int net_ads_join(int argc, const char **argv)
return -1;
}
- d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm);
+ if (!secrets_store_domain_sid(short_domain_name, &dom_sid)) {
+ DEBUG(1,("Failed to save domain sid\n"));
+ return -1;
+ }
- free(password);
+ if (!secrets_store_machine_password(password, short_domain_name, sec_channel_type)) {
+ DEBUG(1,("Failed to save machine password\n"));
+ return -1;
+ }
+
+ d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->config.realm);
+ SAFE_FREE(password);
+ SAFE_FREE(machine_account);
+ if ( ctx )
+ talloc_destroy(ctx);
return 0;
}
@@ -1020,17 +1075,13 @@ int net_ads_changetrustpw(int argc, const char **argv)
char *host_principal;
char *hostname;
ADS_STATUS ret;
- char *user_name;
if (!secrets_init()) {
DEBUG(1,("Failed to initialise secrets database\n"));
return -1;
}
- asprintf(&user_name, "%s$", global_myname());
- opt_user_name = user_name;
-
- opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
+ net_use_machine_password();
use_in_memory_ccache();
diff --git a/source3/utils/net_ads_cldap.c b/source3/utils/net_ads_cldap.c
index e74e4b5a4c..595e6e9434 100644
--- a/source3/utils/net_ads_cldap.c
+++ b/source3/utils/net_ads_cldap.c
@@ -240,7 +240,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
return -1;
}
- p = os3.data;
+ p = (char *)os3.data;
reply->type = IVAL(p, 0); p += 4;
reply->flags = IVAL(p, 0); p += 4;
@@ -248,25 +248,25 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
memcpy(&reply->guid.info, p, GUID_SIZE);
p += GUID_SIZE;
- p += pull_netlogon_string(reply->forest, p, os3.data);
- p += pull_netlogon_string(reply->unk0, p, os3.data);
- p += pull_netlogon_string(reply->domain, p, os3.data);
- p += pull_netlogon_string(reply->hostname, p, os3.data);
- p += pull_netlogon_string(reply->netbios_domain, p, os3.data);
- p += pull_netlogon_string(reply->unk1, p, os3.data);
- p += pull_netlogon_string(reply->netbios_hostname, p, os3.data);
- p += pull_netlogon_string(reply->unk2, p, os3.data);
+ p += pull_netlogon_string(reply->forest, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->unk0, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->domain, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->hostname, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->netbios_domain, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->unk1, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->netbios_hostname, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->unk2, p, (const char *)os3.data);
if (reply->type == SAMLOGON_AD_R) {
- p += pull_netlogon_string(reply->user_name, p, os3.data);
+ p += pull_netlogon_string(reply->user_name, p, (const char *)os3.data);
} else {
*reply->user_name = 0;
}
- p += pull_netlogon_string(reply->unk3, p, os3.data);
- p += pull_netlogon_string(reply->site_name, p, os3.data);
- p += pull_netlogon_string(reply->unk4, p, os3.data);
- p += pull_netlogon_string(reply->site_name_2, p, os3.data);
+ p += pull_netlogon_string(reply->unk3, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->site_name, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->unk4, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->site_name_2, p, (const char *)os3.data);
reply->version = IVAL(p, 0);
reply->lmnt_token = SVAL(p, 4);
diff --git a/source3/utils/net_groupmap.c b/source3/utils/net_groupmap.c
index 8831839e4e..9937145230 100644
--- a/source3/utils/net_groupmap.c
+++ b/source3/utils/net_groupmap.c
@@ -252,11 +252,21 @@ static int net_groupmap_add(int argc, const char **argv)
}
}
- if ( !unixgrp[0] || (!rid && !string_sid[0]) ) {
+ if ( !unixgrp[0] ) {
d_printf("Usage: net groupmap add {rid=<int>|sid=<string>} unixgroup=<string> [type=<domain|local|builtin>] [ntgroup=<string>] [comment=<string>]\n");
return -1;
}
+ if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) {
+ d_printf("Can't lookup UNIX group %s\n", ntgroup);
+ return -1;
+ }
+
+ if ( (rid == 0) && (string_sid[0] == '\0') ) {
+ d_printf("No rid or sid specified, choosing algorithmic mapping\n");
+ rid = pdb_gid_to_group_rid(gid);
+ }
+
/* append the rid to our own domain/machine SID if we don't have a full SID */
if ( !string_sid[0] ) {
sid_copy(&sid, get_global_sam_sid());
@@ -267,11 +277,6 @@ static int net_groupmap_add(int argc, const char **argv)
if (ntcomment[0])
fstrcpy(ntcomment, "Local Unix group");
- if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) {
- d_printf("Can't lookup UNIX group %s\n", ntgroup);
- return -1;
- }
-
if ( !ntgroup[0] )
fstrcpy( ntgroup, unixgrp );
diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c
index 1f3afb1690..95116a4d2a 100644
--- a/source3/utils/net_help.c
+++ b/source3/utils/net_help.c
@@ -47,7 +47,7 @@ int net_common_flags_usage(int argc, const char **argv)
d_printf("\t-U or --user=<name>\t\tuser name\n");
d_printf("\t-s or --configfile=<path>\t\tpathname of smb.conf file\n");
d_printf("\t-l or --long\t\t\tDisplay full information\n");
- d_printf("\t-V or --version\t\tPrint samba version information\n");
+ d_printf("\t-V or --version\t\t\tPrint samba version information\n");
d_printf("\t-P or --machine-pass\t\tAuthenticate as machine account\n");
return -1;
}
@@ -60,7 +60,8 @@ static int help_usage(int argc, const char **argv)
"\n"\
"Valid functions are:\n"\
" RPC RAP ADS FILE SHARE SESSION SERVER DOMAIN PRINTQ USER GROUP VALIDATE\n"\
-" GROUPMEMBER ADMIN SERVICE PASSWORD TIME LOOKUP GETLOCALSID SETLOCALSID\n");
+" GROUPMEMBER ADMIN SERVICE PASSWORD TIME LOOKUP GETLOCALSID SETLOCALSID\n"\
+" CHANGESCRETPW\n");
return -1;
}
@@ -156,6 +157,8 @@ static int net_usage(int argc, const char **argv)
" net cache\t\tto operate on cache tdb file\n"\
" net getlocalsid [NAME]\tto get the SID for local name\n"\
" net setlocalsid SID\tto set the local domain SID\n"\
+ " net changesecretpw\tto change the machine password in the local secrets database only\n"\
+ " \tthis requires the -f flag as a safety barrier\n"\
"\n"\
" net ads <command>\tto run ADS commands\n"\
" net rap <command>\tto run RAP (pre-RPC) commands\n"\
@@ -193,6 +196,9 @@ int net_help(int argc, const char **argv)
{"PASSWORD", net_rap_password_usage},
{"TIME", net_time_usage},
{"LOOKUP", net_lookup_usage},
+#ifdef WITH_FAKE_KASERVER
+ {"AFSKEY", net_afskey_usage},
+#endif
{"HELP", help_usage},
{NULL, NULL}};
diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c
index 8456da4e0c..cef0ea5fbe 100644
--- a/source3/utils/net_lookup.c
+++ b/source3/utils/net_lookup.c
@@ -23,7 +23,7 @@
int net_lookup_usage(int argc, const char **argv)
{
d_printf(
-" net lookup host HOSTNAME <type>\n\tgives IP for a hostname\n\n"
+" net lookup [host] HOSTNAME[#<type>]\n\tgives IP for a hostname\n\n"
" net lookup ldap [domain]\n\tgives IP of domain's ldap server\n\n"
" net lookup kdc [realm]\n\tgives IP of realm's kerberos KDC\n\n"
" net lookup dc [domain]\n\tgives IP of domains Domain Controllers\n\n"
@@ -37,14 +37,22 @@ static int net_lookup_host(int argc, const char **argv)
{
struct in_addr ip;
int name_type = 0x20;
+ const char *name = argv[0];
+ char *p;
- if (argc == 0) return net_lookup_usage(argc, argv);
- if (argc > 1) name_type = strtol(argv[1], NULL, 0);
+ if (argc == 0)
+ return net_lookup_usage(argc, argv);
- if (!resolve_name(argv[0], &ip, name_type)) {
+ p = strchr_m(name,'#');
+ if (p) {
+ *p = '\0';
+ sscanf(++p,"%x",&name_type);
+ }
+
+ if (!resolve_name(name, &ip, name_type)) {
/* we deliberately use DEBUG() here to send it to stderr
so scripts aren't mucked up */
- DEBUG(0,("Didn't find %s#%02x\n", argv[0], name_type));
+ DEBUG(0,("Didn't find %s#%02x\n", name, name_type));
return -1;
}
@@ -221,7 +229,9 @@ static int net_lookup_kdc(int argc, const char **argv)
/* lookup hosts or IP addresses using internal samba lookup fns */
int net_lookup(int argc, const char **argv)
{
- struct functable func[] = {
+ int i;
+
+ struct functable table[] = {
{"HOST", net_lookup_host},
{"LDAP", net_lookup_ldap},
{"DC", net_lookup_dc},
@@ -230,5 +240,19 @@ int net_lookup(int argc, const char **argv)
{NULL, NULL}
};
- return net_run_function(argc, argv, func, net_lookup_usage);
+ if (argc < 1) {
+ d_printf("\nUsage: \n");
+ return net_lookup_usage(argc, argv);
+ }
+ for (i=0; table[i].funcname; i++) {
+ if (StrCaseCmp(argv[0], table[i].funcname) == 0)
+ return table[i].fn(argc-1, argv+1);
+ }
+
+ /* Default to lookup a hostname so 'net lookup foo#1b' can be
+ used instead of 'net lookup host foo#1b'. The host syntax
+ is a bit confusing as non #00 names can't really be
+ considered hosts as such. */
+
+ return net_lookup_host(argc, argv);
}
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 890d4a012b..fefc5af365 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -84,7 +84,14 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
domain_name, domain_sid);
if (!NT_STATUS_IS_OK(result)) {
- goto error;
+ error:
+ fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ fprintf(stderr, "error: %s\n", nt_errstr(result));
+ }
+
+ exit(1);
}
cli_lsa_close(cli, mem_ctx, &pol);
@@ -92,15 +99,6 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
talloc_destroy(mem_ctx);
return domain_sid;
-
- error:
- fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
-
- if (!NT_STATUS_IS_OK(result)) {
- fprintf(stderr, "error: %s\n", nt_errstr(result));
- }
-
- exit(1);
}
/**
@@ -1709,8 +1707,13 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli
static int rpc_trustdom_add(int argc, const char **argv)
{
- return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
- argc, argv);
+ if (argc > 0) {
+ return run_rpc_command(NULL, PI_SAMR, 0, rpc_trustdom_add_internals,
+ argc, argv);
+ } else {
+ d_printf("Usage: net rpc trustdom add <domain>\n");
+ return -1;
+ }
}
@@ -1726,6 +1729,7 @@ static int rpc_trustdom_add(int argc, const char **argv)
static int rpc_trustdom_del(int argc, const char **argv)
{
d_printf("Sorry, not yet implemented.\n");
+ d_printf("Use 'smbpasswd -x -i' instead.\n");
return -1;
}
@@ -1782,7 +1786,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
/* find the domain controller */
if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
- DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
+ DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
return -1;
}
@@ -1988,8 +1992,8 @@ static int rpc_trustdom_list(int argc, const char **argv)
POLICY_HND connect_hnd;
/* trusted domains listing variables */
- int enum_ctx = 0;
- int num_domains, i, pad_len, col_len = 20;
+ unsigned int num_domains, enum_ctx = 0;
+ int i, pad_len, col_len = 20;
DOM_SID *domain_sids;
char **trusted_dom_names;
fstring pdc_name, dummy;
diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c
index 9eadbbbade..ed69f8a326 100644
--- a/source3/utils/net_rpc_samsync.c
+++ b/source3/utils/net_rpc_samsync.c
@@ -550,7 +550,11 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
map.sid = group_sid;
map.sid_name_use = SID_NAME_DOM_GRP;
fstrcpy(map.nt_name, name);
- fstrcpy(map.comment, comment);
+ if (delta->hdr_grp_desc.buffer) {
+ fstrcpy(map.comment, comment);
+ } else {
+ fstrcpy(map.comment, "");
+ }
if (insert)
pdb_add_group_mapping_entry(&map);
@@ -911,9 +915,40 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
fetch_alias_mem(hdr_delta->target_rid,
&delta->als_mem_info, dom_sid);
break;
+ /* The following types are recognised but not handled */
case SAM_DELTA_DOMAIN_INFO:
d_printf("SAM_DELTA_DOMAIN_INFO not handled\n");
break;
+ case SAM_DELTA_RENAME_GROUP:
+ d_printf("SAM_DELTA_RENAME_GROUP not handled\n");
+ break;
+ case SAM_DELTA_RENAME_USER:
+ d_printf("SAM_DELTA_RENAME_USER not handled\n");
+ break;
+ case SAM_DELTA_RENAME_ALIAS:
+ d_printf("SAM_DELTA_RENAME_ALIAS not handled\n");
+ break;
+ case SAM_DELTA_POLICY_INFO:
+ d_printf("SAM_DELTA_POLICY_INFO not handled\n");
+ break;
+ case SAM_DELTA_TRUST_DOMS:
+ d_printf("SAM_DELTA_TRUST_DOMS not handled\n");
+ break;
+ case SAM_DELTA_PRIVS_INFO:
+ d_printf("SAM_DELTA_PRIVS_INFO not handled\n");
+ break;
+ case SAM_DELTA_SECRET_INFO:
+ d_printf("SAM_DELTA_SECRET_INFO not handled\n");
+ break;
+ case SAM_DELTA_DELETE_GROUP:
+ d_printf("SAM_DELTA_DELETE_GROUP not handled\n");
+ break;
+ case SAM_DELTA_DELETE_USER:
+ d_printf("SAM_DELTA_DELETE_USER not handled\n");
+ break;
+ case SAM_DELTA_MODIFIED_COUNT:
+ d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n");
+ break;
default:
d_printf("Unknown delta record type %d\n", hdr_delta->type);
break;
diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c
index d2c5cbc00e..3c5a22841e 100644
--- a/source3/utils/nmblookup.c
+++ b/source3/utils/nmblookup.c
@@ -109,7 +109,7 @@ static void do_node_status(int fd, const char *name, int type, struct in_addr ip
status = node_status_query(fd,&nname,ip, &count);
if (status) {
for (i=0;i<count;i++) {
- fstrcpy(cleanname, status[i].name);
+ pull_ascii_fstring(cleanname, status[i].name);
for (j=0;cleanname[j];j++) {
if (!isprint((int)cleanname[j])) cleanname[j] = '.';
}
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 1d36a7ce52..7cd7e0b087 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -200,10 +200,24 @@ static NTSTATUS contact_winbind_auth_crap(const char *username,
request.flags = flags;
- fstrcpy(request.data.auth_crap.user, username);
+ if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
+ *error_string = smb_xstrdup(
+ "unable to create utf8 string for username");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (push_utf8_fstring(request.data.auth_crap.domain, domain) == -1) {
+ *error_string = smb_xstrdup(
+ "unable to create utf8 string for domain");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
- fstrcpy(request.data.auth_crap.domain, domain);
- fstrcpy(request.data.auth_crap.workstation, workstation);
+ if (push_utf8_fstring(request.data.auth_crap.workstation,
+ workstation) == -1) {
+ *error_string = smb_xstrdup(
+ "unable to create utf8 string for workstation");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
memcpy(request.data.auth_crap.chal, challenge->data, MIN(challenge->length, 8));
@@ -296,7 +310,7 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
}
DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, request.data, request.length);
+ dump_data(10, (const char *)request.data, request.length);
nt_status = ntlmssp_server_update(ntlmssp_state, request, &reply);
@@ -347,27 +361,35 @@ static void manage_squid_basic_request(enum squid_mode squid_mode,
static void offer_gss_spnego_mechs(void) {
DATA_BLOB token;
- ASN1_DATA asn1;
SPNEGO_DATA spnego;
ssize_t len;
char *reply_base64;
+ pstring principal;
+ pstring myname_lower;
+
ZERO_STRUCT(spnego);
+ pstrcpy(myname_lower, global_myname());
+ strlower_m(myname_lower);
+
+ pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm());
+
/* Server negTokenInit (mech offerings) */
spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = smb_xmalloc(sizeof(char *) * 2);
+ spnego.negTokenInit.mechTypes = smb_xmalloc(sizeof(char *) * 3);
+#ifdef HAVE_KRB5
+ spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
+ spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
+ spnego.negTokenInit.mechTypes[2] = NULL;
+#else
spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP);
spnego.negTokenInit.mechTypes[1] = NULL;
+#endif
+
- ZERO_STRUCT(asn1);
- asn1_push_tag(&asn1, ASN1_SEQUENCE(0));
- asn1_push_tag(&asn1, ASN1_CONTEXT(0));
- asn1_write_GeneralString(&asn1, "NONE");
- asn1_pop_tag(&asn1);
- asn1_pop_tag(&asn1);
- spnego.negTokenInit.mechListMIC = data_blob(asn1.data, asn1.length);
- asn1_free(&asn1);
+ spnego.negTokenInit.mechListMIC = data_blob(principal,
+ strlen(principal));
len = write_spnego_data(&token, &spnego);
free_spnego_data(&spnego);
@@ -391,11 +413,14 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
char *buf, int length)
{
static NTLMSSP_STATE *ntlmssp_state = NULL;
- SPNEGO_DATA spnego;
- DATA_BLOB request, token;
+ SPNEGO_DATA request, response;
+ DATA_BLOB token;
NTSTATUS status;
ssize_t len;
+ char *user = NULL;
+ char *domain = NULL;
+
const char *reply_code;
char *reply_base64;
pstring reply_argument;
@@ -432,9 +457,9 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
return;
}
- request = base64_decode_data_blob(buf + 3);
- len = read_spnego_data(request, &spnego);
- data_blob_free(&request);
+ token = base64_decode_data_blob(buf + 3);
+ len = read_spnego_data(token, &request);
+ data_blob_free(&token);
if (len == -1) {
DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf));
@@ -442,100 +467,159 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
return;
}
- if (spnego.type == SPNEGO_NEG_TOKEN_INIT) {
+ if (request.type == SPNEGO_NEG_TOKEN_INIT) {
/* Second request from Client. This is where the
client offers its mechanism to use. We currently
only support NTLMSSP, the decision for Kerberos
would be taken here. */
- if ( (spnego.negTokenInit.mechTypes == NULL) ||
- (spnego.negTokenInit.mechTypes[0] == NULL) ) {
+ if ( (request.negTokenInit.mechTypes == NULL) ||
+ (request.negTokenInit.mechTypes[0] == NULL) ) {
DEBUG(1, ("Client did not offer any mechanism"));
x_fprintf(x_stdout, "BH\n");
return;
}
- if ( strcmp(spnego.negTokenInit.mechTypes[0], OID_NTLMSSP) != 0 ) {
- DEBUG(1, ("Client did not choose NTLMSSP but %s\n",
- spnego.negTokenInit.mechTypes[0]));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
+ if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) {
- if ( spnego.negTokenInit.mechToken.data == NULL ) {
- DEBUG(1, ("Client did not provide NTLMSSP data\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
+ if ( request.negTokenInit.mechToken.data == NULL ) {
+ DEBUG(1, ("Client did not provide NTLMSSP data\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
- if ( ntlmssp_state != NULL ) {
- DEBUG(1, ("Client wants a new NTLMSSP challenge, but "
- "already got one\n"));
- x_fprintf(x_stdout, "BH\n");
- ntlmssp_server_end(&ntlmssp_state);
- return;
+ if ( ntlmssp_state != NULL ) {
+ DEBUG(1, ("Client wants a new NTLMSSP challenge, but "
+ "already got one\n"));
+ x_fprintf(x_stdout, "BH\n");
+ ntlmssp_server_end(&ntlmssp_state);
+ return;
+ }
+
+ ntlmssp_server_start(&ntlmssp_state);
+ ntlmssp_state->check_password = winbind_pw_check;
+ ntlmssp_state->get_domain = get_winbind_domain;
+ ntlmssp_state->get_global_myname = get_winbind_netbios_name;
+
+ DEBUG(10, ("got NTLMSSP packet:\n"));
+ dump_data(10, (const char *)request.negTokenInit.mechToken.data,
+ request.negTokenInit.mechToken.length);
+
+ response.type = SPNEGO_NEG_TOKEN_TARG;
+ response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
+ response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+
+ status = ntlmssp_server_update(ntlmssp_state,
+ request.negTokenInit.mechToken,
+ &response.negTokenTarg.responseToken);
}
- ntlmssp_server_start(&ntlmssp_state);
- ntlmssp_state->check_password = winbind_pw_check;
- ntlmssp_state->get_domain = get_winbind_domain;
- ntlmssp_state->get_global_myname = get_winbind_netbios_name;
+#ifdef HAVE_KRB5
+ if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) {
- DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, spnego.negTokenInit.mechToken.data,
- spnego.negTokenInit.mechToken.length);
+ char *principal;
+ DATA_BLOB auth_data;
+ DATA_BLOB ap_rep;
+ uint8 session_key[16];
- free_spnego_data(&spnego);
+ if ( request.negTokenInit.mechToken.data == NULL ) {
+ DEBUG(1, ("Client did not provide Kerberos data\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
- spnego.type = SPNEGO_NEG_TOKEN_TARG;
- spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
- spnego.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
+ response.type = SPNEGO_NEG_TOKEN_TARG;
+ response.negTokenTarg.supportedMech = strdup(OID_KERBEROS5_OLD);
+ response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+ response.negTokenTarg.responseToken = data_blob(NULL, 0);
- status = ntlmssp_server_update(ntlmssp_state,
- spnego.negTokenInit.mechToken,
- &spnego.negTokenTarg.responseToken);
+ status = ads_verify_ticket(lp_realm(),
+ &request.negTokenInit.mechToken,
+ &principal, &auth_data, &ap_rep,
+ session_key);
- } else {
+ /* Now in "principal" we have the name we are
+ authenticated as. */
+
+ if (NT_STATUS_IS_OK(status)) {
+
+ domain = strchr(principal, '@');
- /* spnego.type == SPNEGO_NEG_TOKEN_TARG */
+ if (domain == NULL) {
+ DEBUG(1, ("Did not get a valid principal "
+ "from ads_verify_ticket\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
- DATA_BLOB response;
+ *domain++ = '\0';
+ domain = strdup(domain);
+ user = strdup(principal);
- if (spnego.negTokenTarg.responseToken.data == NULL) {
- DEBUG(1, ("Got a negTokenArg without a responseToken!\n"));
+ data_blob_free(&ap_rep);
+ data_blob_free(&auth_data);
+
+ SAFE_FREE(principal);
+ }
+ }
+#endif
+
+ } else {
+
+ if ( (request.negTokenTarg.supportedMech == NULL) ||
+ ( strcmp(request.negTokenTarg.supportedMech, OID_NTLMSSP) != 0 ) ) {
+ /* Kerberos should never send a negTokenTarg, OID_NTLMSSP
+ is the only one we support that sends this stuff */
+ DEBUG(1, ("Got a negTokenTarg for something non-NTLMSSP: %s\n",
+ request.negTokenTarg.supportedMech));
x_fprintf(x_stdout, "BH\n");
return;
}
- status = ntlmssp_server_update(ntlmssp_state,
- spnego.negTokenTarg.responseToken,
- &response);
+ if (request.negTokenTarg.responseToken.data == NULL) {
+ DEBUG(1, ("Got a negTokenTarg without a responseToken!\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
- data_blob_free(&spnego.negTokenTarg.responseToken);
+ status = ntlmssp_server_update(ntlmssp_state,
+ request.negTokenTarg.responseToken,
+ &response.negTokenTarg.responseToken);
- spnego.negTokenTarg.responseToken = response;
+ response.type = SPNEGO_NEG_TOKEN_TARG;
+ response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
+ response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+ if (NT_STATUS_IS_OK(status)) {
+ user = strdup(ntlmssp_state->user);
+ domain = strdup(ntlmssp_state->domain);
+ ntlmssp_server_end(&ntlmssp_state);
+ }
}
+ free_spnego_data(&request);
+
if (NT_STATUS_IS_OK(status)) {
- spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
+ response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
reply_code = "AF";
- pstr_sprintf(reply_argument, "%s\\%s",
- ntlmssp_state->domain, ntlmssp_state->user);
+ pstr_sprintf(reply_argument, "%s\\%s", domain, user);
} else if (NT_STATUS_EQUAL(status,
NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
+ response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
reply_code = "TT";
pstr_sprintf(reply_argument, "*");
} else {
- spnego.negTokenTarg.negResult = SPNEGO_REJECT;
+ response.negTokenTarg.negResult = SPNEGO_REJECT;
reply_code = "NA";
pstrcpy(reply_argument, nt_errstr(status));
}
- len = write_spnego_data(&token, &spnego);
- free_spnego_data(&spnego);
+ SAFE_FREE(user);
+ SAFE_FREE(domain);
+
+ len = write_spnego_data(&token, &response);
+ free_spnego_data(&response);
if (len == -1) {
DEBUG(1, ("Could not write SPNEGO data blob\n"));
@@ -551,16 +635,12 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
SAFE_FREE(reply_base64);
data_blob_free(&token);
- if (NT_STATUS_IS_OK(status)) {
- ntlmssp_server_end(&ntlmssp_state);
- }
-
return;
}
static NTLMSSP_CLIENT_STATE *client_ntlmssp_state = NULL;
-static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
+static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
{
NTSTATUS status;
DATA_BLOB null_blob = data_blob(NULL, 0);
@@ -573,14 +653,12 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
if (client_ntlmssp_state != NULL) {
DEBUG(1, ("Request for initial SPNEGO request where "
"we already have a state\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
+ return False;
}
if ( (opt_username == NULL) || (opt_domain == NULL) ) {
DEBUG(1, ("Need username and domain for NTLMSSP\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
+ return False;
}
if (opt_password == NULL) {
@@ -591,7 +669,7 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
DEBUG(10, ("Requesting password\n"));
x_fprintf(x_stdout, "PW\n");
- return;
+ return True;
}
status = ntlmssp_client_start(&client_ntlmssp_state);
@@ -599,9 +677,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Could not start NTLMSSP client: %s\n",
nt_errstr(status)));
- x_fprintf(x_stdout, "BH\n");
ntlmssp_client_end(&client_ntlmssp_state);
- return;
+ return False;
}
status = ntlmssp_set_username(client_ntlmssp_state, opt_username);
@@ -609,9 +686,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Could not set username: %s\n",
nt_errstr(status)));
- x_fprintf(x_stdout, "BH\n");
ntlmssp_client_end(&client_ntlmssp_state);
- return;
+ return False;
}
status = ntlmssp_set_domain(client_ntlmssp_state, opt_domain);
@@ -619,9 +695,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Could not set domain: %s\n",
nt_errstr(status)));
- x_fprintf(x_stdout, "BH\n");
ntlmssp_client_end(&client_ntlmssp_state);
- return;
+ return False;
}
status = ntlmssp_set_password(client_ntlmssp_state, opt_password);
@@ -629,9 +704,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Could not set password: %s\n",
nt_errstr(status)));
- x_fprintf(x_stdout, "BH\n");
ntlmssp_client_end(&client_ntlmssp_state);
- return;
+ return False;
}
spnego.type = SPNEGO_NEG_TOKEN_INIT;
@@ -645,9 +719,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n",
nt_errstr(status)));
- x_fprintf(x_stdout, "BH\n");
ntlmssp_client_end(&client_ntlmssp_state);
- return;
+ return False;
}
write_spnego_data(&to_server, &spnego);
@@ -657,7 +730,7 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
data_blob_free(&to_server);
x_fprintf(x_stdout, "KK %s\n", to_server_base64);
SAFE_FREE(to_server_base64);
- return;
+ return True;
}
static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
@@ -719,21 +792,110 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
return;
}
-static void manage_client_krb5_init(SPNEGO_DATA spnego)
+#ifdef HAVE_KRB5
+
+static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
{
- DEBUG(1, ("to be done ... \n"));
- x_fprintf(x_stdout, "BH\n");
- return;
+ char *principal;
+ DATA_BLOB tkt, to_server;
+ unsigned char session_key_krb5[16];
+ SPNEGO_DATA reply;
+ char *reply_base64;
+
+ const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
+ ssize_t len;
+
+ if ( (spnego.negTokenInit.mechListMIC.data == NULL) ||
+ (spnego.negTokenInit.mechListMIC.length == 0) ) {
+ DEBUG(1, ("Did not get a principal for krb5\n"));
+ return False;
+ }
+
+ principal = malloc(spnego.negTokenInit.mechListMIC.length+1);
+
+ if (principal == NULL) {
+ DEBUG(1, ("Could not malloc principal\n"));
+ return False;
+ }
+
+ memcpy(principal, spnego.negTokenInit.mechListMIC.data,
+ spnego.negTokenInit.mechListMIC.length);
+ principal[spnego.negTokenInit.mechListMIC.length] = '\0';
+
+ tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5);
+
+ if (tkt.data == NULL) {
+
+ pstring user;
+
+ /* Let's try to first get the TGT, for that we need a
+ password. */
+
+ if (opt_password == NULL) {
+ DEBUG(10, ("Requesting password\n"));
+ x_fprintf(x_stdout, "PW\n");
+ return True;
+ }
+
+ pstr_sprintf(user, "%s@%s", opt_username, opt_domain);
+
+ if (kerberos_kinit_password(user, opt_password, 0) != 0) {
+ DEBUG(10, ("Requesting TGT failed\n"));
+ x_fprintf(x_stdout, "NA\n");
+ return True;
+ }
+
+ tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5);
+ }
+
+ ZERO_STRUCT(reply);
+
+ reply.type = SPNEGO_NEG_TOKEN_INIT;
+ reply.negTokenInit.mechTypes = my_mechs;
+ reply.negTokenInit.reqFlags = 0;
+ reply.negTokenInit.mechToken = tkt;
+ reply.negTokenInit.mechListMIC = data_blob(NULL, 0);
+
+ len = write_spnego_data(&to_server, &reply);
+ data_blob_free(&tkt);
+
+ if (len == -1) {
+ DEBUG(1, ("Could not write SPNEGO data blob\n"));
+ return False;
+ }
+
+ reply_base64 = base64_encode_data_blob(to_server);
+ x_fprintf(x_stdout, "KK %s *\n", reply_base64);
+
+ SAFE_FREE(reply_base64);
+ data_blob_free(&to_server);
+ DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n"));
+ return True;
}
static void manage_client_krb5_targ(SPNEGO_DATA spnego)
{
- DEBUG(1, ("Got a negTokenTarg with a Kerberos token. This should not "
- "happen!\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
+ switch (spnego.negTokenTarg.negResult) {
+ case SPNEGO_ACCEPT_INCOMPLETE:
+ DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n"));
+ x_fprintf(x_stdout, "BH\n");
+ break;
+ case SPNEGO_ACCEPT_COMPLETED:
+ DEBUG(10, ("Accept completed\n"));
+ x_fprintf(x_stdout, "AF\n");
+ break;
+ case SPNEGO_REJECT:
+ DEBUG(10, ("Rejected\n"));
+ x_fprintf(x_stdout, "NA\n");
+ break;
+ default:
+ DEBUG(1, ("Got an invalid negTokenTarg\n"));
+ x_fprintf(x_stdout, "AF\n");
+ }
}
+#endif
+
static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
char *buf, int length)
{
@@ -753,7 +915,7 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
/* We asked for a password and obviously got it :-) */
- opt_password = strndup(request.data, request.length);
+ opt_password = strndup((const char *)request.data, request.length);
if (opt_password == NULL) {
DEBUG(1, ("Out of memory\n"));
@@ -796,14 +958,17 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
while (*mechType != NULL) {
- if (strcmp(*mechType, OID_NTLMSSP) == 0) {
- manage_client_ntlmssp_init(spnego);
- goto out;
+#ifdef HAVE_KRB5
+ if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) ||
+ (strcmp(*mechType, OID_KERBEROS5) == 0) ) {
+ if (manage_client_krb5_init(spnego))
+ goto out;
}
+#endif
- if (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) {
- manage_client_krb5_init(spnego);
- goto out;
+ if (strcmp(*mechType, OID_NTLMSSP) == 0) {
+ if (manage_client_ntlmssp_init(spnego))
+ goto out;
}
mechType++;
@@ -816,17 +981,42 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
if (spnego.type == SPNEGO_NEG_TOKEN_TARG) {
+ if (spnego.negTokenTarg.supportedMech == NULL) {
+ /* On accept/reject Windows does not send the
+ mechanism anymore. Handle that here and
+ shut down the mechanisms. */
+
+ switch (spnego.negTokenTarg.negResult) {
+ case SPNEGO_ACCEPT_COMPLETED:
+ x_fprintf(x_stdout, "AF\n");
+ break;
+ case SPNEGO_REJECT:
+ x_fprintf(x_stdout, "NA\n");
+ break;
+ default:
+ DEBUG(1, ("Got a negTokenTarg with no mech and an "
+ "unknown negResult: %d\n",
+ spnego.negTokenTarg.negResult));
+ x_fprintf(x_stdout, "BH\n");
+ }
+
+ ntlmssp_client_end(&client_ntlmssp_state);
+ goto out;
+ }
+
if (strcmp(spnego.negTokenTarg.supportedMech,
OID_NTLMSSP) == 0) {
manage_client_ntlmssp_targ(spnego);
goto out;
}
+#if HAVE_KRB5
if (strcmp(spnego.negTokenTarg.supportedMech,
OID_KERBEROS5_OLD) == 0) {
manage_client_krb5_targ(spnego);
goto out;
}
+#endif
}
@@ -925,8 +1115,8 @@ static BOOL check_auth_crap(void)
&opt_lm_response,
&opt_nt_response,
flags,
- lm_key,
- nt_key,
+ (unsigned char *)lm_key,
+ (unsigned char *)nt_key,
&error_string);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -940,7 +1130,7 @@ static BOOL check_auth_crap(void)
if (request_lm_key
&& (memcmp(zeros, lm_key,
sizeof(lm_key)) != 0)) {
- hex_encode(lm_key,
+ hex_encode((const unsigned char *)lm_key,
sizeof(lm_key),
&hex_lm_key);
x_fprintf(x_stdout, "LM_KEY: %s\n", hex_lm_key);
@@ -949,7 +1139,7 @@ static BOOL check_auth_crap(void)
if (request_nt_key
&& (memcmp(zeros, nt_key,
sizeof(nt_key)) != 0)) {
- hex_encode(nt_key,
+ hex_encode((const unsigned char *)nt_key,
sizeof(nt_key),
&hex_nt_key);
x_fprintf(x_stdout, "NT_KEY: %s\n", hex_nt_key);
@@ -1023,16 +1213,16 @@ static BOOL test_lm(void)
sizeof(lm_key)) != 0) {
DEBUG(1, ("LM Key does not match expectations!\n"));
DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
+ dump_data(1, (const char *)lm_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
}
if (memcmp(lm_hash, nt_key, 8) != 0) {
DEBUG(1, ("Session Key (first 8, lm hash) does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 8);
+ dump_data(1, (const char *)nt_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
}
return True;
}
@@ -1095,18 +1285,18 @@ static BOOL test_lm_ntlm(void)
sizeof(lm_key)) != 0) {
DEBUG(1, ("LM Key does not match expectations!\n"));
DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
+ dump_data(1, (const char *)lm_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
pass = False;
}
if (memcmp(session_key.data, nt_key,
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, session_key.data, session_key.length);
+ dump_data(1, (const char *)session_key.data, session_key.length);
pass = False;
}
return pass;
@@ -1138,10 +1328,10 @@ static BOOL test_ntlm(void)
flags |= WBFLAG_PAM_NTKEY;
SMBNTencrypt(opt_password,chall.data,nt_response.data);
- E_md4hash(opt_password, nt_hash);
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+ E_md4hash(opt_password, (unsigned char *)nt_hash);
+ SMBsesskeygen_ntv1((const unsigned char *)nt_hash, NULL, session_key.data);
- E_deshash(opt_password, lm_hash);
+ E_deshash(opt_password, (unsigned char *)lm_hash);
nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
opt_workstation,
@@ -1149,8 +1339,8 @@ static BOOL test_ntlm(void)
NULL,
&nt_response,
flags,
- lm_key,
- nt_key,
+ (unsigned char *)lm_key,
+ (unsigned char *)nt_key,
&error_string);
data_blob_free(&nt_response);
@@ -1178,7 +1368,7 @@ static BOOL test_ntlm(void)
DEBUG(1, ("nt_key:\n"));
dump_data(1, nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, session_key.data, session_key.length);
+ dump_data(1, (const char *)session_key.data, session_key.length);
pass = False;
}
return pass;
@@ -1234,17 +1424,17 @@ static BOOL test_ntlm_in_lm(void)
sizeof(lm_key)) != 0) {
DEBUG(1, ("LM Key does not match expectations!\n"));
DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
+ dump_data(1, (const char *)lm_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
pass = False;
}
if (memcmp(lm_hash, nt_key, 8) != 0) {
DEBUG(1, ("Session Key (first 8 lm hash) does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
pass = False;
}
return pass;
@@ -1276,10 +1466,10 @@ static BOOL test_ntlm_in_both(void)
flags |= WBFLAG_PAM_NTKEY;
SMBNTencrypt(opt_password,chall.data,nt_response.data);
- E_md4hash(opt_password, nt_hash);
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+ E_md4hash(opt_password, (unsigned char *)nt_hash);
+ SMBsesskeygen_ntv1((const unsigned char *)nt_hash, NULL, session_key.data);
- E_deshash(opt_password, lm_hash);
+ E_deshash(opt_password, (unsigned char *)lm_hash);
nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
opt_workstation,
@@ -1287,8 +1477,8 @@ static BOOL test_ntlm_in_both(void)
&nt_response,
&nt_response,
flags,
- lm_key,
- nt_key,
+ (unsigned char *)lm_key,
+ (unsigned char *)nt_key,
&error_string);
data_blob_free(&nt_response);
@@ -1316,7 +1506,7 @@ static BOOL test_ntlm_in_both(void)
DEBUG(1, ("nt_key:\n"));
dump_data(1, nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, session_key.data, session_key.length);
+ dump_data(1, (const char *)session_key.data, session_key.length);
pass = False;
}
@@ -1378,9 +1568,9 @@ static BOOL test_ntlmv2(void)
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, nt_session_key.data, nt_session_key.length);
+ dump_data(1, (const char *)nt_session_key.data, nt_session_key.length);
pass = False;
}
return pass;
@@ -1442,9 +1632,9 @@ static BOOL test_lmv2_ntlmv2(void)
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, nt_session_key.data, nt_session_key.length);
+ dump_data(1, (const char *)nt_session_key.data, nt_session_key.length);
pass = False;
}
return pass;
@@ -1557,18 +1747,18 @@ static BOOL test_ntlm_broken(BOOL break_lm)
sizeof(lm_key)) != 0) {
DEBUG(1, ("LM Key does not match expectations!\n"));
DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
+ dump_data(1, (const char *)lm_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
pass = False;
}
if (memcmp(session_key.data, nt_key,
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, session_key.data, session_key.length);
+ dump_data(1, (const char *)session_key.data, session_key.length);
pass = False;
}
return pass;
diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c
index 23df26d150..3230eb21fc 100644
--- a/source3/utils/profiles.c
+++ b/source3/utils/profiles.c
@@ -448,7 +448,7 @@ static int get_sid(DOM_SID *sid, const unsigned char *sid_str)
SIVAL(&sid->sub_auths[i], 0, auth);
i++;
- lstr = strchr(lstr + 1, '-');
+ lstr = (const unsigned char *)strchr(lstr + 1, '-');
}
return 1;
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index c90c042106..58ee57b5dd 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -751,7 +751,7 @@ static struct cli_state *connect_one(const char *share)
POPT_AUTOHELP
{ "delete", 'D', POPT_ARG_STRING, NULL, 'D', "Delete an acl", "ACL" },
{ "modify", 'M', POPT_ARG_STRING, NULL, 'M', "Modify an acl", "ACL" },
- { "add", 'A', POPT_ARG_STRING, NULL, 'A', "Add an acl", "ACL" },
+ { "add", 'a', POPT_ARG_STRING, NULL, 'a', "Add an acl", "ACL" },
{ "set", 'S', POPT_ARG_STRING, NULL, 'S', "Set acls", "ACLS" },
{ "chown", 'C', POPT_ARG_STRING, NULL, 'C', "Change ownership of a file", "USERNAME" },
{ "chgrp", 'G', POPT_ARG_STRING, NULL, 'G', "Change group ownership of a file", "GROUPNAME" },
@@ -796,7 +796,7 @@ static struct cli_state *connect_one(const char *share)
mode = SMB_ACL_MODIFY;
break;
- case 'A':
+ case 'a':
the_acl = smb_xstrdup(poptGetOptArg(pc));
mode = SMB_ACL_ADD;
break;
diff --git a/source3/utils/smbgroupedit.c b/source3/utils/smbgroupedit.c
deleted file mode 100644
index 0faa0513ed..0000000000
--- a/source3/utils/smbgroupedit.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Jean François Micouleau 1998-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.
- */
-
-#include "includes.h"
-
-/*
- * Next two lines needed for SunOS and don't
- * hurt anything else...
- */
-extern char *optarg;
-extern int optind;
-
-/*********************************************************
- Print command usage on stderr and die.
-**********************************************************/
-static void usage(void)
-{
- if (getuid() == 0) {
- printf("smbgroupedit options\n");
- } else {
- printf("You need to be root to use this tool!\n");
- }
- printf("options:\n");
- printf(" -a group create new group\n");
- printf(" -n group NT group name\n");
- printf(" -p privilege only local\n");
- printf(" -d description group description\n");
- printf(" -v list groups\n");
- printf(" -l long list (include details)\n");
- printf(" -s short list (default)\n");
- printf(" -c SID change group\n");
- printf(" -u unix group\n");
- printf(" -d description group description\n");
- printf(" -r rid RID of new group\n");
- printf(" -x group delete this group\n");
- printf("\n");
- printf(" -t[b|d|l] type: builtin, domain, local \n");
- exit(1);
-}
-
-/*********************************************************
- Figure out if the input was an NT group or a SID string.
- Return the SID.
-**********************************************************/
-static BOOL get_sid_from_input(DOM_SID *sid, char *input)
-{
- GROUP_MAP map;
-
- if (StrnCaseCmp( input, "S-", 2)) {
- /* Perhaps its the NT group name? */
- if (!pdb_getgrnam(&map, input, MAPPING_WITHOUT_PRIV)) {
- printf("NT Group %s doesn't exist in mapping DB\n", input);
- return False;
- } else {
- *sid = map.sid;
- }
- } else {
- if (!string_to_sid(sid, input)) {
- printf("converting sid %s from a string failed!\n", input);
- return False;
- }
- }
- return True;
-}
-
-/*********************************************************
- add a group.
-**********************************************************/
-static int addgroup(gid_t gid, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege, uint32 rid)
-{
- PRIVILEGE_SET se_priv;
- DOM_SID sid;
- fstring string_sid;
- fstring comment;
-
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
-
- sid_to_string(string_sid, &sid);
-
- if (ntcomment==NULL)
- fstrcpy(comment, "Local Unix group");
- else
- fstrcpy(comment, ntcomment);
-
- init_privilege(&se_priv);
- if (privilege!=NULL)
- convert_priv_from_text(&se_priv, privilege);
-
- if(!add_initial_entry(gid, string_sid, sid_type, ntgroup,
- comment, se_priv, PR_ACCESS_FROM_NETWORK)) {
- printf("adding entry for group %s failed!\n", ntgroup);
- free_privilege(&se_priv);
- return -1;
- }
-
- free_privilege(&se_priv);
- return 0;
-}
-
-/*********************************************************
- Change a group.
-**********************************************************/
-static int changegroup(char *sid_string, char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *groupdesc, char *privilege)
-{
- DOM_SID sid;
- GROUP_MAP map;
- gid_t gid;
-
- if (!get_sid_from_input(&sid, sid_string)) {
- return -1;
- }
-
- /* Get the current mapping from the database */
- if(!pdb_getgrsid(&map, sid, MAPPING_WITH_PRIV)) {
- printf("This SID does not exist in the database\n");
- return -1;
- }
-
- /* If a new Unix group is specified, check and change */
- if (group!=NULL) {
- gid=nametogid(group);
- if (gid==-1) {
- printf("The UNIX group does not exist\n");
- return -1;
- } else
- map.gid=gid;
- }
-
- /*
- * Allow changing of group type only between domain and local
- * We disallow changing Builtin groups !!! (SID problem)
- */
- if (sid_type==SID_NAME_ALIAS
- || sid_type==SID_NAME_DOM_GRP
- || sid_type==SID_NAME_UNKNOWN) {
- if (map.sid_name_use==SID_NAME_ALIAS
- || map.sid_name_use==SID_NAME_DOM_GRP
- || map.sid_name_use==SID_NAME_UNKNOWN) {
- map.sid_name_use=sid_type;
- } else {
- printf("cannot change group type to builtin\n");
- };
- } else {
- printf("cannot change group type from builtin\n");
- }
-
- if (ntgroup!=NULL)
- fstrcpy(map.nt_name, ntgroup);
-
- /* Change comment if new one */
- if (groupdesc!=NULL)
- fstrcpy(map.comment, groupdesc);
-
- /* Change the privilege if new one */
- if (privilege!=NULL)
- convert_priv_from_text(&map.priv_set, privilege);
-
- if (!pdb_update_group_mapping_entry(&map)) {
- printf("Could not update group database\n");
- free_privilege(&map.priv_set);
- return -1;
- }
-
- free_privilege(&map.priv_set);
- return 0;
-}
-
-/*********************************************************
- Delete the group.
-**********************************************************/
-static int deletegroup(char *group)
-{
- DOM_SID sid;
-
- if (!get_sid_from_input(&sid, group)) {
- return -1;
- }
-
- if(!pdb_delete_group_mapping_entry(sid)) {
- printf("removing group %s from the mapping db failed!\n", group);
- return -1;
- }
-
- return 0;
-}
-
-/*********************************************************
- List the groups.
-**********************************************************/
-static int listgroup(enum SID_NAME_USE sid_type, BOOL long_list)
-{
- int entries,i;
- GROUP_MAP *map=NULL;
- fstring string_sid;
- fstring group_type;
- fstring priv_text;
-
- if (!long_list)
- printf("NT group (SID) -> Unix group\n");
-
- if (!pdb_enum_group_mapping(sid_type, &map, &entries, ENUM_ALL_MAPPED, MAPPING_WITH_PRIV))
- return -1;
-
- for (i=0; i<entries; i++) {
- decode_sid_name_use(group_type, (map[i]).sid_name_use);
- sid_to_string(string_sid, &map[i].sid);
- convert_priv_to_text(&(map[i].priv_set), priv_text);
- free_privilege(&(map[i].priv_set));
-
- if (!long_list)
- printf("%s (%s) -> %s\n", map[i].nt_name, string_sid, gidtoname(map[i].gid));
- else {
- printf("%s\n", map[i].nt_name);
- printf("\tSID : %s\n", string_sid);
- printf("\tUnix group: %s\n", gidtoname(map[i].gid));
- printf("\tGroup type: %s\n", group_type);
- printf("\tComment : %s\n", map[i].comment);
- printf("\tPrivilege : %s\n\n", priv_text);
- }
- }
-
- return 0;
-}
-
-/*********************************************************
- Start here.
-**********************************************************/
-int main (int argc, char **argv)
-{
- int ch;
- BOOL add_group = False;
- BOOL view_group = False;
- BOOL change_group = False;
- BOOL delete_group = False;
- BOOL nt_group = False;
- BOOL priv = False;
- BOOL group_type = False;
- BOOL long_list = False;
-
- char *group = NULL;
- char *sid = NULL;
- char *ntgroup = NULL;
- char *privilege = NULL;
- char *groupt = NULL;
- char *group_desc = NULL;
-
- enum SID_NAME_USE sid_type;
- uint32 rid = -1;
-
- setup_logging("groupedit", True);
-
- if (argc < 2) {
- usage();
- return 0;
- }
-
- if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n",
- dyn_CONFIGFILE);
- exit(1);
- }
-
- if (!init_names())
- exit(1);
-
- if(!initialize_password_db(True)) {
- fprintf(stderr, "Can't setup password database vectors.\n");
- exit(1);
- }
-
- if(get_global_sam_sid()==False) {
- fprintf(stderr, "Can not read machine SID\n");
- return 0;
- }
-
- while ((ch = getopt(argc, argv, "a:c:d:ln:p:r:st:u:vx:")) != EOF) {
- switch(ch) {
- case 'a':
- add_group = True;
- group=optarg;
- break;
- case 'c':
- change_group = True;
- sid=optarg;
- break;
- case 'd':
- group_desc=optarg;
- break;
- case 'l':
- long_list = True;
- break;
- case 'n':
- nt_group = True;
- ntgroup=optarg;
- break;
- case 'p':
- priv = True;
- privilege=optarg;
- break;
- case 'r':
- rid = atoi(optarg);
- break;
- case 's':
- long_list = False;
- break;
- case 't':
- group_type = True;
- groupt=optarg;
- break;
- case 'u':
- group=optarg;
- break;
- case 'v':
- view_group = True;
- break;
- case 'x':
- delete_group = True;
- group=optarg;
- break;
- /*default:
- usage();*/
- }
- }
-
-
- if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) > 1) {
- fprintf (stderr, "Incompatible options on command line!\n");
- usage();
- exit(1);
- }
-
- /* no option on command line -> list groups */
- if (((add_group?1:0) + (view_group?1:0) + (change_group?1:0) + (delete_group?1:0)) == 0)
- view_group = True;
-
-
- if (group_type==False)
- sid_type=SID_NAME_UNKNOWN;
- else {
- switch (groupt[0]) {
- case 'l':
- case 'L':
- sid_type=SID_NAME_ALIAS;
- break;
- case 'd':
- case 'D':
- sid_type=SID_NAME_DOM_GRP;
- break;
- case 'b':
- case 'B':
- sid_type=SID_NAME_WKN_GRP;
- break;
- default:
- sid_type=SID_NAME_UNKNOWN;
- break;
- }
- }
-
- if (add_group) {
- gid_t gid=nametogid(group);
- if (gid==-1) {
- printf("unix group %s doesn't exist!\n", group);
- return -1;
- }
-
- if (rid == -1) {
- rid = pdb_gid_to_group_rid(gid);
- }
- return addgroup(gid, sid_type, ntgroup?ntgroup:group,
- group_desc, privilege, rid);
- }
-
- if (view_group)
- return listgroup(sid_type, long_list);
-
- if (delete_group)
- return deletegroup(group);
-
- if (change_group) {
- return changegroup(sid, group, sid_type, ntgroup, group_desc, privilege);
- }
-
- usage();
-
- return 0;
-}
diff --git a/source3/utils/status.c b/source3/utils/status.c
index 8bf67fc4d6..c17e080b6b 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -597,7 +597,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
} else {
if (locks_only) goto locks;
- d_printf("\nSamba version %s\n",VERSION);
+ d_printf("\nSamba version %s\n",SAMBA_VERSION_STRING);
d_printf("PID Username Group Machine \n");
d_printf("-------------------------------------------------------------------\n");
diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
index 16918ecd4a..0a87b4bc1e 100644
--- a/source3/utils/testparm.c
+++ b/source3/utils/testparm.c
@@ -287,6 +287,27 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
Level II oplocks can only be set if oplocks are also set.\n",
lp_servicename(s) );
}
+
+ if (lp_map_hidden(s) && !(lp_create_mask(s) & S_IXOTH)) {
+ printf("Invalid combination of parameters for service %s. \
+ Map hidden can only work if create mask includes octal 01 (S_IXOTH).\n",
+ lp_servicename(s) );
+ }
+ if (lp_map_hidden(s) && (lp_force_create_mode(s) & S_IXOTH)) {
+ printf("Invalid combination of parameters for service %s. \
+ Map hidden can only work if force create mode excludes octal 01 (S_IXOTH).\n",
+ lp_servicename(s) );
+ }
+ if (lp_map_system(s) && !(lp_create_mask(s) & S_IXGRP)) {
+ printf("Invalid combination of parameters for service %s. \
+ Map system can only work if create mask includes octal 010 (S_IXGRP).\n",
+ lp_servicename(s) );
+ }
+ if (lp_map_system(s) && (lp_force_create_mode(s) & S_IXGRP)) {
+ printf("Invalid combination of parameters for service %s. \
+ Map system can only work if force create mode excludes octal 010 (S_IXGRP).\n",
+ lp_servicename(s) );
+ }
}
}