2015年7月15日星期三

速度爆快: Mac OS X上用smbpasswd改Windows domain用户密码

​windows domain用户的密码过期了,为了改密码,还得找台windows机器,而且变更速度很慢!这不爽吧。 据说mac上自带了smbpasswd可以改,可是高版本的OS X就没了,于是安装了smbapasswd,瞬间变更密码了。

发现可以用brew安装samba,很小的东西,里面包含了smbpasswd.
brew install samba
2017/6/10: 不知道从yosemite后的哪个版本开始无法从brew里安装了,研究出了两个方法:
_PWD=$PWD
#根据你自己的系统版本,到 https://bintray.com/homebrew/bottles/samba#files 去找相应的下载文件
wget https://bintray.com/homebrew/bottles/download_file?file_path=samba-3.6.25.el_capitan.bottle.1.tar.gz
cd /usr/local/Cellar
tar xvf $_PWD/download_file\?file_path\=samba-3.6.25.el_capitan.bottle.1.tar.gz
#最关键的是这步,这步会把所有的samba/3.6.25/bin/里的执行文件里的动态链接库的路径里的@@HOMEBREW_CELLAR@@字样给换成/usr/local/Cellar/samba/3.6.25/lib
brew link samba
另一个是用docker,那就没的可说了,就在docker里执行apt-get -y install smbclient。
然后就更改密码,速度爆快,也不知道windows自带的密码变更功能磨磨叽叽在搞什么。
smbpasswd -r domain_server_ip_or_name  -U domain_user_name
然后会提示输入就密码新密码的。
至于根据domain名称如何找到domain server的ip,
一般ping   DOMAIN名称.公司DOMAIN名称.com什么的 就得到了。
实在找不到那就用findsmb工具可以找到。
IP ADDR         NETBIOS NAME     WORKGROUP/OS/VERSION 
---------------------------------------------------------------------
172.21.0.12     TEST_SERVER1       *[TEST_DOMAIN] [Windows Server 2012] 

根据windows域名找ip

有时候需要根据windows domain名称找到确切的server ip,Windows内部是用DNS Query那一套机制的,所以可以用nslookup来找,问题是,时过境迁,老的方法不管用了。


以前的经验是_ldap._tcp.域名 就可以(当然还有一些辅助的查询设定等会儿说),
可是最近一次发现不管用了,得把_ldap换成_kerberos,至少我的环境是这样。
大概的步骤就是
执行
?
1
nslookup
输入
?
1
2
3
4
set querytype=any
set class=any
set nosearch
set debug     (这个要不要无所谓)
然后输入要查询的域名,变态的是要小写字母,还有时需要输入全名,就是包括自己公司域名的那部分,例如:
?
1
_ldap._tcp.testdomain.companyname.com

不行那就换成_kerberos
?
1
_kerberos._tcp.testdomain.companyname.com
然后会出现一堆信息,其中有ip,那就是了,有可能有多个,那不用管,第一个就行,其他的是备用域服务器。

2015/12/01: 发现一般只要
ping   domain名.公司domain名.com什么的 就得到了 domain服务器的IP了。

2015年7月14日星期二

HTTP Proxy 密码自动插入

某些轻量安装包(例如Visual Studio 2013 Express for Windows Desktop),安装包执行过程中需要从网上下载具体的内容,但是老是报错,因为我的环境使用了带有密码认证的http proxy,VS傻傻的不能显示密码输入框。碰到过几次这种事情,最后用nodejs做个自动填充密码的假的本地http proxy转接到真的,通过了。


代码放到:
例如,系统的http proxy设定原为 real_proxy_server:8080,用户是usr1,密码是password1
那么用这个命令建立一个本地假的http proxy,然后把系统的proxy设定改为localhost:8181
node proxy-login-automator.js --host localhost --port 8181 --remote_host real_proxy_server--remote_port 8080 --usr usr1 --pwd password1
HTTPS也是支持的,并不作区分,只要原来的支持就行。
就一个文件proxy-login-automator.js
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
'use strict';
//convert `--key value` to cfg[key]=value
var cfg = process.argv.slice(2/*skip ["node", "xxx.js"]*/).reduce(function (cfg, arg, i, argv) {
    i % 2 === 0 && arg.slice(0, 2) === '--' && (cfg[arg.slice(2)] = argv[i + 1]);
    return cfg;
}, /*init cfg:*/ {host: 'localhost', port: 8080, remote_host: 8080});
if (!cfg.remote_host || !cfg.usr || !cfg.pwd)
    return console.error('Usage of parameters:\n'
        '\t[--host host]\t\t' 'listening address. Default: localhost. (* means all interfaces)\n'
        '\t[--port port]\t\t' 'listening port. Default: 8080\n'
        '\t<--remote_host host>\t\t' 'real proxy server address\n'
        '\t[--remote_port port]\t\t' 'real proxy server port. Default: 8080\n'
        '\t[--pac urlPath]\t\t' 'proxy_auto_config_file_url_path\n'
        '\t[--usr user]\t\t' 'proxy user id\n'
        '\t[--pwd password]\t\t' 'proxy user password\n'
    );
console.error('Using parameters:\n' + JSON.stringify(cfg, null'  '));
cfg.buf_proxy_basic_auth = new Buffer('Proxy-Authorization: Basic ' new Buffer(cfg.usr + ':' + cfg.pwd).toString('base64'));
var CR = 0xd, LF = 0xa, BUF_CR_LF = new Buffer([0xd, 0xa]), BUF_LF = new Buffer([0xa]), BUF_CR = new Buffer([0xd]), BUF_CR_LF_CR_LF = new Buffer([0xd, 0xa, 0xd, 0xa]), BUF_LF_LF = new Buffer([0xa, 0xa]);
var STATE_NONE = 0, STATE_FOUND_LF = 1, STATE_FOUND_LF_CR = 2;
var net = require('net'), t;
var HTTPParser = process.binding('http_parser').HTTPParser;
net.createServer({allowHalfOpen: true}, function (socket) {
    var realCon = net.connect({port: cfg.remote_port, host: cfg.remote_host, allowHalfOpen: true});
    realCon.on('data'function (buf) {
        //console.log('<<<<' + (t=new Date()) + '.' + t.getMilliseconds() + '\n' + buf.toString('ascii'));
        socket.write(buf);
    }).on('end'function () {
        socket.end();
    }).on('close'function () {
        socket.end();
    }).on('error', dummy);
    var parser = new HTTPParser(HTTPParser.REQUEST);
    parser[HTTPParser.kOnHeadersComplete] = function () {
        //console.log('---- kOnHeadersComplete----');
        //console.log(arguments);
        parser.__is_headers_complete = true;
    };
    //parser[HTTPParser.kOnMessageComplete] = function () {
    //    console.log('---- kOnMessageComplete----');
    //    console.log(arguments);
    //};
    var state = STATE_NONE;
    socket.on('data'function (buf) {
        //console.log('>>>>' + (t = new Date()) + '.' + t.getMilliseconds() + '\n' + buf.toString('ascii'));
        //var ret = parser.execute(buf);
        //console.log('\n\n----parser result: ' + ret + ' buf len:' + buf.length);
        //realCon.write(buf);
        //return;
        var buf_ary = [], unsavedStart = 0, buf_len = buf.length;
        //process orphan CR
        if (state === STATE_FOUND_LF_CR && buf[0] !== LF) {
            parser.execute(BUF_CR);
            buf_ary.push(BUF_CR);
        }
        for (var i = 0; i < buf_len; i++) {
            //find first LF
            if (state === STATE_NONE) {
                if (buf[i] === LF) {
                    state = STATE_FOUND_LF;
                }
                continue;
            }
            //find second CR LF or LF
            if (buf[i] === LF) {
                parser.__is_headers_complete = false;
                parser.execute(buf.slice(unsavedStart, i + 1));
                if (parser.__is_headers_complete) {
                    //console.log('insert auth header');
                    buf_ary.push(buf.slice(unsavedStart, buf[i - 1] === CR ? i - 1 : i));
                    buf_ary.push(cfg.buf_proxy_basic_auth);
                    buf_ary.push(state === STATE_FOUND_LF_CR ? BUF_CR_LF_CR_LF : BUF_LF_LF);
                    unsavedStart = i + 1;
                    state = STATE_NONE;
                }
                else {
                    state = STATE_FOUND_LF;
                }
            }
            else if (buf[i] === CR && state === STATE_FOUND_LF) {
                state = STATE_FOUND_LF_CR;
            else {
                state = STATE_NONE;
            }
        }
        if (unsavedStart < buf_len) {
            //strip last CR if found LF_CR
            buf = buf.slice(unsavedStart, state === STATE_FOUND_LF_CR ? buf_len - 1 : buf_len);
            if (buf.length) {
                parser.execute(buf);
                buf_ary.push(buf);
            }
        }
        buf = Buffer.concat(buf_ary);
        realCon.write(buf);
    }).on('end', cleanup).on('close', cleanup).on('error', dummy);
    function cleanup() {
        if (parser) {
            parser.close();
            parser = null;
        }
        realCon.end();
    }
}).listen(cfg.port, cfg.host === '*' ? undefined : cfg.host);
function dummy() {
}