diff options
author | Jeremy Allison <jra@samba.org> | 1998-04-23 20:12:17 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1998-04-23 20:12:17 +0000 |
commit | 002a47de8e0cf03c79cedbed2db52f391001f459 (patch) | |
tree | 1a23fd1edab2979024d5212f64cdc031d309f481 | |
parent | a85f5bc268a1c13334b86ac3a44a026359c09371 (diff) | |
download | samba-002a47de8e0cf03c79cedbed2db52f391001f459.tar.gz samba-002a47de8e0cf03c79cedbed2db52f391001f459.tar.bz2 samba-002a47de8e0cf03c79cedbed2db52f391001f459.zip |
clientgen.c: Added rap error codes to cli_error, moved from smbpasswd.c
password.c: Changed global cli -> pw_cli, removed strtok (bad strtok, bad :-)
use in security=server, started to extend security=domain code.
smbpasswd.c: Removed rap error code functions.
Jeremy.
(This used to be commit 0f00b8fce1a5cad7f8c212568fa33f09986e5bd6)
-rw-r--r-- | source3/include/proto.h | 5 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 71 | ||||
-rw-r--r-- | source3/smbd/password.c | 215 | ||||
-rw-r--r-- | source3/utils/smbpasswd.c | 66 |
4 files changed, 233 insertions, 124 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 9bba68df48..adf753ccf5 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -51,6 +51,8 @@ void cmd_help(char *dum_in, char *dum_out); /*The following definitions come from clientgen.c */ +char *cli_smb_errstr(struct cli_state *cli); +char *cli_errstr(struct cli_state *cli); BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, @@ -97,7 +99,6 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip); BOOL cli_initialise(struct cli_state *cli); void cli_shutdown(struct cli_state *cli); -char *cli_errstr(struct cli_state *cli); void cli_error(struct cli_state *cli, int *eclass, int *num); void cli_sockopt(struct cli_state *cli, char *options); int cli_setpid(struct cli_state *cli, int pid); @@ -1726,7 +1727,7 @@ struct smb_passwd *getsmbpwuid(unsigned int uid); char *encode_acct_ctrl(uint16 acct_ctrl); BOOL add_smbpwd_entry(struct smb_passwd *newpwd); BOOL mod_smbpwd_entry(struct smb_passwd* pwd); -void *machine_password_lock( char *doman, char *name, BOOL update); +void *machine_password_lock( char *domain, char *name, BOOL update); BOOL machine_password_unlock( void *token ); BOOL get_machine_account_password( void *mach_tok, unsigned char *ret_pwd, time_t *last_change_time); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ea51395a8f..9de6afccee 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -29,6 +29,69 @@ extern int DEBUGLEVEL; +/***************************************************** + RAP error codes - a small start but will be extended. +*******************************************************/ + +struct +{ + int err; + char *message; +} rap_errmap[] = +{ + {5, "User has insufficient privilege" }, + {86, "The specified password is invalid" }, + {2226, "Operation only permitted on a Primary Domain Controller" }, + {2242, "The password of this user has expired." }, + {2243, "The password of this user cannot change." }, + {2244, "This password cannot be used now (password history conflict)." }, + {2245, "The password is shorter than required." }, + {2246, "The password of this user is too recent to change."}, + {0, NULL} +}; + +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +char *cli_smb_errstr(struct cli_state *cli) +{ + return smb_errstr(cli->inbuf); +} + +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char *cli_errstr(struct cli_state *cli) +{ + static fstring error_message; + int errclass; + int errnum; + int i; + + /* + * Errors are of two kinds - smb errors, + * dealt with by cli_smb_errstr, and rap + * errors, whose error code is in cli.error. + */ + + cli_error(cli, &errclass, &errnum); + if(errclass != 0) + return cli_smb_errstr(cli); + + sprintf(error_message, "code %d", cli->error); + + for(i = 0; rap_errmap[i].message != NULL; i++) { + if (rap_errmap[i].err == cli->error) { + fstrcpy( error_message, rap_errmap[i].message); + break; + } + } + + return error_message; +} + /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ @@ -1567,14 +1630,6 @@ void cli_shutdown(struct cli_state *cli) } /**************************************************************************** - return a description of the error -****************************************************************************/ -char *cli_errstr(struct cli_state *cli) -{ - return smb_errstr(cli->inbuf); -} - -/**************************************************************************** return error codes for the last packet ****************************************************************************/ void cli_error(struct cli_state *cli, int *eclass, int *num) diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 04a1795e7f..d627edf1cd 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1673,14 +1673,14 @@ BOOL check_hosts_equiv(char *user) } -static struct cli_state cli; +static struct cli_state pw_cli; /**************************************************************************** return the client state structure ****************************************************************************/ struct cli_state *server_client(void) { - return &cli; + return &pw_cli; } /**************************************************************************** @@ -1692,61 +1692,63 @@ struct cli_state *server_cryptkey(void) struct in_addr dest_ip; extern fstring local_machine; char *p; + BOOL connected_ok = False; - if (!cli_initialise(&cli)) + if (!cli_initialise(&pw_cli)) return NULL; - - for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { - fstrcpy(desthost,p); + + p = lp_passwordserver(); + while(p && next_token( &p, desthost, LIST_SEP)) { standard_sub_basic(desthost); strupper(desthost); if(!resolve_name( desthost, &dest_ip)) { - DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",p)); + DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost)); continue; } if (ismyip(dest_ip)) { - DEBUG(1,("Password server loop - disabling password server %s\n",p)); + DEBUG(1,("Password server loop - disabling password server %s\n",desthost)); continue; } - if (cli_connect(&cli, desthost, &dest_ip)) { - DEBUG(3,("connected to password server %s\n",p)); + if (cli_connect(&pw_cli, desthost, &dest_ip)) { + DEBUG(3,("connected to password server %s\n",desthost)); + connected_ok = True; break; } } - if (!p) { - DEBUG(1,("password server not available\n")); - cli_shutdown(&cli); + if (!connected_ok) { + DEBUG(0,("password server not available\n")); + cli_shutdown(&pw_cli); return NULL; } - if (!cli_session_request(&cli, desthost, 0x20, local_machine)) { + if (!cli_session_request(&pw_cli, desthost, 0x20, local_machine)) { DEBUG(1,("%s rejected the session\n",desthost)); - cli_shutdown(&cli); + cli_shutdown(&pw_cli); return NULL; } DEBUG(3,("got session\n")); - if (!cli_negprot(&cli)) { + if (!cli_negprot(&pw_cli)) { DEBUG(1,("%s rejected the negprot\n",desthost)); - cli_shutdown(&cli); + cli_shutdown(&pw_cli); return NULL; } - if (cli.protocol < PROTOCOL_LANMAN2 || - !(cli.sec_mode & 1)) { + if (pw_cli.protocol < PROTOCOL_LANMAN2 || + !(pw_cli.sec_mode & 1)) { DEBUG(1,("%s isn't in user level security mode\n",desthost)); - cli_shutdown(&cli); + cli_shutdown(&pw_cli); return NULL; } DEBUG(3,("password server OK\n")); - return &cli; + return &pw_cli; } /**************************************************************************** @@ -1759,8 +1761,8 @@ BOOL server_validate(char *user, char *domain, extern fstring local_machine; static unsigned char badpass[24]; - if (!cli.initialised) { - DEBUG(1,("password server %s is not connected\n", cli.desthost)); + if (!pw_cli.initialised) { + DEBUG(1,("password server %s is not connected\n", pw_cli.desthost)); return(False); } @@ -1781,17 +1783,17 @@ BOOL server_validate(char *user, char *domain, * need to detect this as some versions of NT4.x are broken. JRA. */ - if (cli_session_setup(&cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass), + if (cli_session_setup(&pw_cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass), domain)) { - if ((SVAL(cli.inbuf,smb_vwv2) & 1) == 0) { + if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) == 0) { DEBUG(0,("server_validate: password server %s allows users as non-guest \ -with a bad password.\n", cli.desthost)); +with a bad password.\n", pw_cli.desthost)); DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ use this machine as the password server.\n")); - cli_ulogoff(&cli); + cli_ulogoff(&pw_cli); return False; } - cli_ulogoff(&cli); + cli_ulogoff(&pw_cli); } /* @@ -1799,21 +1801,21 @@ use this machine as the password server.\n")); * not guest enabled, we can try with the real password. */ - if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", cli.desthost)); + if (!cli_session_setup(&pw_cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + DEBUG(1,("password server %s rejected the password\n", pw_cli.desthost)); return False; } /* if logged in as guest then reject */ - if ((SVAL(cli.inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli.desthost)); - cli_ulogoff(&cli); + if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) != 0) { + DEBUG(1,("password server %s gave us guest only\n", pw_cli.desthost)); + cli_ulogoff(&pw_cli); return(False); } - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { - DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); - cli_ulogoff(&cli); + if (!cli_send_tconX(&pw_cli, "IPC$", "IPC", "", 1)) { + DEBUG(1,("password server %s refused IPC$ connect\n", pw_cli.desthost)); + cli_ulogoff(&pw_cli); return False; } @@ -1827,43 +1829,48 @@ use this machine as the password server.\n")); */ if (lp_net_wksta_user_logon()) { - DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", cli.desthost)); - if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { - DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); - cli_tdis(&cli); - cli_ulogoff(&cli); + DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", pw_cli.desthost)); + if (!cli_NetWkstaUserLogon(&pw_cli,user,local_machine)) { + DEBUG(1,("password server %s failed NetWkstaUserLogon\n", pw_cli.desthost)); + cli_tdis(&pw_cli); + cli_ulogoff(&pw_cli); return False; } - if (cli.privilages == 0) { - DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); - cli_tdis(&cli); - cli_ulogoff(&cli); + if (pw_cli.privilages == 0) { + DEBUG(1,("password server %s gave guest privilages\n", pw_cli.desthost)); + cli_tdis(&pw_cli); + cli_ulogoff(&pw_cli); return False; } - if (!strequal(cli.eff_name, user)) { + if (!strequal(pw_cli.eff_name, user)) { DEBUG(1,("password server %s gave different username %s\n", - cli.desthost, - cli.eff_name)); - cli_tdis(&cli); - cli_ulogoff(&cli); + pw_cli.desthost, + pw_cli.eff_name)); + cli_tdis(&pw_cli); + cli_ulogoff(&pw_cli); return False; } } else { - DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", cli.desthost)); + DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", pw_cli.desthost)); } - DEBUG(3,("password server %s accepted the password\n", cli.desthost)); + DEBUG(3,("password server %s accepted the password\n", pw_cli.desthost)); - cli_tdis(&cli); - cli_ulogoff(&cli); + cli_tdis(&pw_cli); + cli_ulogoff(&pw_cli); return(True); } #ifdef DOMAIN_CLIENT +/*********************************************************************** + Do the same as security=server, but using NT Domain calls and a session + key from the machine password. +************************************************************************/ + BOOL domain_client_validate( char *user, char *domain, char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen) @@ -1874,6 +1881,11 @@ BOOL domain_client_validate( char *user, char *domain, unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; BOOL encrypted = True; + fstring remote_machine; + char *p; + struct in_addr dest_ip; + struct cli_state cli; + BOOL connected_ok = False; /* * Check that the requested domain is not our own machine name. @@ -1930,6 +1942,101 @@ BOOL domain_client_validate( char *user, char *domain, * see if they were valid. */ + /* + * Treat each name in the 'password server =' line as a potential + * PDC/BDC. Contact each in turn and try and authenticate. + */ + + p = lp_passwordserver(); + while(p && next_token( &p, remote_machine, LIST_SEP)) { + + standard_sub_basic(remote_machine); + strupper(remote_machine); + + if(!resolve_name( remote_machine, &dest_ip)) { + DEBUG(1,("domain_client_validate: Can't resolve address for %s\n", remote_machine)); + continue; + } + + if (ismyip(dest_ip)) { + DEBUG(1,("domain_client_validate: Password server loop - not using password server %s\n",remote_machine)); + continue; + } + + memset(&cli, '\0', sizeof(struct cli_state)); + + if (!cli_connect(&cli, remote_machine, &dest_ip)) { + DEBUG(0,("domain_client_validate: unable to connect to SMB server on \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + continue; + } + + if (!cli_session_request(&cli, remote_machine, 0x20, myname)) { + DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + continue; + } + + cli.protocol = PROTOCOL_NT1; + + if (!cli_negprot(&cli)) { + DEBUG(0,("domain_client_validate: machine %s rejected the negotiate protocol. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + continue; + } + + if (cli.protocol != PROTOCOL_NT1) { + DEBUG(0,("domain_client_validate: machine %s didn't negotiate NT protocol.\n", + remote_machine)); + cli_shutdown(&cli); + continue; + } + + /* + * Do an anonymous session setup. + */ + + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + continue; + } + + if (!(cli.sec_mode & 1)) { + DEBUG(1,("domain_client_validate: machine %s isn't in user level security mode\n", + remote_machine)); + cli_shutdown(&cli); + continue; + } + + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("domain_client_validate: machine %s rejected the tconX on the IPC$ share. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + continue; + } + + /* + * We have an anonymous connection to IPC$. + */ + connected_ok = True; + break; + } + + if (!connected_ok) { + DEBUG(0,("domain_client_validate: Domain password server not available.\n")); + cli_shutdown(&cli); + return False; + } + + /* + * Ok - we have an anonymous connection to the IPC$ share. + * Now start the NT Domain stuff :-). + */ + return False; } #endif /* DOMAIN_CLIENT */ diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index cf9cd54ef3..91ccb609bb 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -19,60 +19,6 @@ #include "includes.h" -/* - * Password changing error codes. - */ - -struct -{ - int err; - char *message; -} pw_change_errmap[] = -{ - {5, "User has insufficient privilege" }, - {86, "The specified password is invalid" }, - {2226, "Operation only permitted on a Primary Domain Controller" }, - {2242, "The password of this user has expired." }, - {2243, "The password of this user cannot change." }, - {2244, "This password cannot be used now (password history conflict)." }, - {2245, "The password is shorter than required." }, - {2246, "The password of this user is too recent to change."}, - {0, NULL} -}; - -/****************************************************** - Return an error message for a remote password change. -*******************************************************/ - -char *get_error_message(struct cli_state *cli) -{ - static fstring error_message; - int errclass; - int errnum; - int i; - - /* - * Errors are of two kinds - smb errors, - * dealt with by cli_errstr, and rap - * errors, whose error code is in cli.error. - */ - - cli_error(cli, &errclass, &errnum); - if(errclass != 0) - return cli_errstr(cli); - - sprintf(error_message, "code %d", cli->error); - - for(i = 0; pw_change_errmap[i].message != NULL; i++) { - if (pw_change_errmap[i].err == cli->error) { - fstrcpy( error_message, pw_change_errmap[i].message); - break; - } - } - - return error_message; -} - /********************************************************* Print command usage on stderr and die. **********************************************************/ @@ -365,13 +311,13 @@ int main(int argc, char **argv) if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { fprintf(stderr, "%s: unable to connect to SMB server on machine %s. Error was : %s.\n", - prog_name, remote_machine, get_error_message(&cli) ); + prog_name, remote_machine, cli_errstr(&cli) ); exit(1); } if (!cli_session_request(&cli, remote_machine, 0x20, myname)) { fprintf(stderr, "%s: machine %s rejected the session setup. Error was : %s.\n", - prog_name, remote_machine, get_error_message(&cli) ); + prog_name, remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); exit(1); } @@ -380,7 +326,7 @@ int main(int argc, char **argv) if (!cli_negprot(&cli)) { fprintf(stderr, "%s: machine %s rejected the negotiate protocol. Error was : %s.\n", - prog_name, remote_machine, get_error_message(&cli) ); + prog_name, remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); exit(1); } @@ -388,21 +334,21 @@ int main(int argc, char **argv) if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd), "", 0, "")) { fprintf(stderr, "%s: machine %s rejected the session setup. Error was : %s.\n", - prog_name, remote_machine, get_error_message(&cli) ); + prog_name, remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); exit(1); } if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { fprintf(stderr, "%s: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", - prog_name, remote_machine, get_error_message(&cli) ); + prog_name, remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); exit(1); } if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { fprintf(stderr, "%s: machine %s rejected the password change: Error was : %s.\n", - prog_name, remote_machine, get_error_message(&cli) ); + prog_name, remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); exit(1); } |