From 389a16d9d5331ddc7ae61d3d4ef3a4ee48734d4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Oct 2002 17:10:29 +0000 Subject: [PATCH] Added new error codes. Fix up connection code to retry in the same way that app-head does. Jeremy. (This used to be commit b521abd86b10573ca8f9116907c81e6deb55f049) --- source3/auth/auth_domain.c | 33 ++++++++++++++++-------- source3/client/smbspool.c | 2 +- source3/include/doserr.h | 47 +++++++++++++++++++++++++++++----- source3/libsmb/cliconnect.c | 12 ++++++++- source3/nsswitch/winbindd_cm.c | 22 +++++++++++++--- source3/rpcclient/rpcclient.c | 2 +- source3/smbd/change_trust_pw.c | 2 +- source3/utils/net.c | 4 +-- source3/utils/smbcacls.c | 2 +- source3/utils/smbtree.c | 2 +- 10 files changed, 99 insertions(+), 29 deletions(-) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 59b9233a2d8..129c486562d 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -88,8 +88,7 @@ static NTSTATUS rpc_resolve_dc(const char *server, way to find it, but until we have a RPC call that does this it will have to do */ if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) { - DEBUG(2, ("connect_to_domain_password_server: Can't " - "resolve name for IP %s\n", server)); + DEBUG(2, ("rpc_resolve_dc: Can't resolve name for IP %s\n", server)); return NT_STATUS_NO_LOGON_SERVERS; } @@ -100,7 +99,7 @@ static NTSTATUS rpc_resolve_dc(const char *server, fstrcpy(remote_machine, server); strupper(remote_machine); if (!resolve_name(remote_machine, dest_ip, 0x20)) { - DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", + DEBUG(1,("rpc_resolve_dc: Can't resolve address for %s\n", remote_machine)); return NT_STATUS_NO_LOGON_SERVERS; } @@ -126,18 +125,20 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, const char *server, const char *setup_creds_as, uint16 sec_chan, - const unsigned char *trust_passwd) + const unsigned char *trust_passwd, + BOOL *retry) { struct in_addr dest_ip; fstring remote_machine; NTSTATUS result; uint32 neg_flags = 0x000001ff; - if (lp_security() == SEC_ADS) { + *retry = False; + + if (lp_security() == SEC_ADS) result = ads_resolve_dc(remote_machine, &dest_ip); - } else { + else result = rpc_resolve_dc(server, remote_machine, &dest_ip); - } if (!NT_STATUS_IS_OK(result)) { DEBUG(2,("connect_to_domain_password_server: unable to resolve DC: %s\n", @@ -165,12 +166,14 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA. */ + *retry = True; + if (!grab_server_mutex(server)) return NT_STATUS_NO_LOGON_SERVERS; /* Attempt connection */ result = cli_full_connection(cli, global_myname, remote_machine, - &dest_ip, 0, "IPC$", "IPC", "", "", "",0); + &dest_ip, 0, "IPC$", "IPC", "", "", "",0, retry); if (!NT_STATUS_IS_OK(result)) { release_server_mutex(); @@ -235,7 +238,10 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, uint16 sec_chan, const unsigned char *trust_passwd) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + BOOL retry = True; fstring dc_name; + int i; /* * Ignore addresses we have already tried. @@ -247,7 +253,10 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, if (!lookup_dc_name(global_myname, domain, ip, dc_name)) return NT_STATUS_NO_LOGON_SERVERS; - return connect_to_domain_password_server(cli, dc_name, setup_creds_as, sec_chan, trust_passwd); + for (i = 0; (!NT_STATUS_IS_OK(ret)) && retry && (i < 3); i++) + ret = connect_to_domain_password_server(cli, dc_name, setup_creds_as, + sec_chan, trust_passwd, &retry); + return ret; } /*********************************************************************** @@ -371,7 +380,11 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) { nt_status = find_connect_pdc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time); } else { - nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as, sec_chan, trust_passwd); + int i; + BOOL retry = False; + for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) + nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as, + sec_chan, trust_passwd, &retry); } } diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c index ecb5c311c54..ff109635331 100644 --- a/source3/client/smbspool.c +++ b/source3/client/smbspool.c @@ -282,7 +282,7 @@ smb_connect(char *workgroup, /* I - Workgroup */ get_myname(myname); nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????", - username, workgroup, password, 0); + username, workgroup, password, 0, NULL); if (!NT_STATUS_IS_OK(nt_status)) { fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status)); diff --git a/source3/include/doserr.h b/source3/include/doserr.h index 93936463e68..576aeda2bf7 100644 --- a/source3/include/doserr.h +++ b/source3/include/doserr.h @@ -82,13 +82,28 @@ #define ERRnoipc 66 /* don't support ipc */ /* These errors seem to be only returned by the NT printer driver system */ - +#define ERRdriveralreadyinstalled 1795 /* ERROR_PRINTER_DRIVER_ALREADY_INSTALLED */ +#define ERRunknownprinterport 1796 /* ERROR_UNKNOWN_PORT */ #define ERRunknownprinterdriver 1797 /* ERROR_UNKNOWN_PRINTER_DRIVER */ +#define ERRunknownprintprocessor 1798 /* ERROR_UNKNOWN_PRINTPROCESSOR */ +#define ERRinvalidseparatorfile 1799 /* ERROR_INVALID_SEPARATOR_FILE */ +#define ERRinvalidjobpriority 1800 /* ERROR_INVALID_PRIORITY */ #define ERRinvalidprintername 1801 /* ERROR_INVALID_PRINTER_NAME */ #define ERRprinteralreadyexists 1802 /* ERROR_PRINTER_ALREADY_EXISTS */ +#define ERRinvalidprintercommand 1803 /* ERROR_INVALID_PRINTER_COMMAND */ #define ERRinvaliddatatype 1804 /* ERROR_INVALID_DATATYPE */ #define ERRinvalidenvironment 1805 /* ERROR_INVALID_ENVIRONMENT */ + +#define ERRunknownprintmonitor 3000 /* ERROR_UNKNOWN_PRINT_MONITOR */ #define ERRprinterdriverinuse 3001 /* ERROR_PRINTER_DRIVER_IN_USE */ +#define ERRspoolfilenotfound 3002 /* ERROR_SPOOL_FILE_NOT_FOUND */ +#define ERRnostartdoc 3003 /* ERROR_SPL_NO_STARTDOC */ +#define ERRnoaddjob 3004 /* ERROR_SPL_NO_ADDJOB */ +#define ERRprintprocessoralreadyinstalled 3005 /* ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED */ +#define ERRprintmonitoralreadyinstalled 3006 /* ERROR_PRINT_MONITOR_ALREADY_INSTALLED */ +#define ERRinvalidprintmonitor 3007 /* ERROR_INVALID_PRINT_MONITOR */ +#define ERRprintmonitorinuse 3008 /* ERROR_PRINT_MONITOR_IN_USE */ +#define ERRprinterhasjobsqueued 3009 /* ERROR_PRINTER_HAS_JOBS_QUEUED */ /* Error codes for the ERRSRV class */ @@ -171,20 +186,38 @@ #define WERR_CAN_NOT_COMPLETE W_ERROR(1003) #define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) #define WERR_SERVER_UNAVAILABLE W_ERROR(1722) -#define WERR_UNKNOWN_PRINTER_DRIVER W_ERROR(1797) -#define WERR_INVALID_PRINTER_NAME W_ERROR(1801) -#define WERR_PRINTER_ALREADY_EXISTS W_ERROR(1802) -#define WERR_INVALID_DATATYPE W_ERROR(1804) -#define WERR_INVALID_ENVIRONMENT W_ERROR(1805) #define WERR_INVALID_FORM_NAME W_ERROR(1902) #define WERR_INVALID_FORM_SIZE W_ERROR(1903) #define WERR_BUF_TOO_SMALL W_ERROR(2123) #define WERR_JOB_NOT_FOUND W_ERROR(2151) #define WERR_DEST_NOT_FOUND W_ERROR(2152) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) -#define WERR_PRINTER_DRIVER_IN_USE W_ERROR(3001) #define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) +#define WERR_PRINTER_DRIVER_ALREADY_INSTALLED W_ERROR(ERRdriveralreadyinstalled) +#define WERR_UNKNOWN_PORT W_ERROR(ERRunknownprinterport) +#define WERR_UNKNOWN_PRINTER_DRIVER W_ERROR(ERRunknownprinterdriver) +#define WERR_UNKNOWN_PRINTPROCESSOR W_ERROR(ERRunknownprintprocessor) +#define WERR_INVALID_SEPARATOR_FILE W_ERROR(ERRinvalidseparatorfile) +#define WERR_INVALID_PRIORITY W_ERROR(ERRinvalidjobpriority) +#define WERR_INVALID_PRINTER_NAME W_ERROR(ERRinvalidprintername) +#define WERR_PRINTER_ALREADY_EXISTS W_ERROR(ERRprinteralreadyexists) +#define WERR_INVALID_PRINTER_COMMAND W_ERROR(ERRinvalidprintercommand) +#define WERR_INVALID_DATATYPE W_ERROR(ERRinvaliddatatype) +#define WERR_INVALID_ENVIRONMENT W_ERROR(ERRinvalidenvironment) + +#define WERR_UNKNOWN_PRINT_MONITOR W_ERROR(ERRunknownprintmonitor) +#define WERR_PRINTER_DRIVER_IN_USE W_ERROR(ERRprinterdriverinuse) +#define WERR_SPOOL_FILE_NOT_FOUND W_ERROR(ERRspoolfilenotfound) +#define WERR_SPL_NO_STARTDOC W_ERROR(ERRnostartdoc) +#define WERR_SPL_NO_ADDJOB W_ERROR(ERRnoaddjob) +#define WERR_PRINT_PROCESSOR_ALREADY_INSTALLED W_ERROR(ERRprintprocessoralreadyinstalled) +#define WERR_PRINT_MONITOR_ALREADY_INSTALLED W_ERROR(ERRprintmonitoralreadyinstalled) +#define WERR_INVALID_PRINT_MONITOR W_ERROR(ERRinvalidprintmonitor) +#define WERR_PRINT_MONITOR_IN_USE W_ERROR(ERRprintmonitorinuse) +#define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued) + + /* DFS errors */ #ifndef NERR_BASE diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f005ac21f39..6a21121f436 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1153,6 +1153,7 @@ static void init_creds(struct ntuser_creds *creds, char* username, @param user Username, unix string @param domain User's domain @param password User's password, unencrypted unix string. + @param retry BOOL. Did this connection fail with a retryable error ? */ NTSTATUS cli_full_connection(struct cli_state **output_cli, @@ -1161,7 +1162,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr *dest_ip, int port, char *service, char *service_type, char *user, char *domain, - char *password, int flags) + char *password, int flags, + BOOL *retry) { struct ntuser_creds creds; NTSTATUS nt_status; @@ -1171,6 +1173,9 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr ip; extern pstring global_myname; + if (retry) + *retry = False; + if (!my_name) my_name = global_myname; @@ -1185,6 +1190,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return NT_STATUS_UNSUCCESSFUL; } + cli_set_timeout(cli, 10000); /* 10 seconds. */ + if (dest_ip) ip = *dest_ip; else @@ -1201,6 +1208,9 @@ again: return NT_STATUS_UNSUCCESSFUL; } + if (retry) + *retry = True; + if (!cli_session_request(cli, &calling, &called)) { char *p; DEBUG(1,("session request to %s failed (%s)\n", diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index cb1779f5906..5f477c78f79 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -392,6 +392,8 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, NTSTATUS result; char *ipc_username, *ipc_domain, *ipc_password; struct in_addr dc_ip; + int i; + BOOL retry = True; ZERO_STRUCT(dc_ip); @@ -446,10 +448,22 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index, DEBUG(5, ("connecting to %s from %s with username [%s]\\[%s]\n", new_conn->controller, global_myname, ipc_domain, ipc_username)); - result = cli_full_connection(&(new_conn->cli), global_myname, new_conn->controller, - &dc_ip, 0, "IPC$", - "IPC", ipc_username, ipc_domain, - ipc_password, 0); + for (i = 0; retry && (i < 3); i++) { + + if (!secrets_named_mutex(new_conn->controller, 10)) { + DEBUG(0,("cm_open_connection: mutex grab failed for %s\n", new_conn->controller)); + continue; + } + + result = cli_full_connection(&(new_conn->cli), global_myname, new_conn->controller, + &dc_ip, 0, "IPC$", "IPC", ipc_username, ipc_domain, + ipc_password, 0, &retry); + + secrets_named_mutex_release(new_conn->controller); + + if (NT_STATUS_IS_OK(result)) + break; + } SAFE_FREE(ipc_username); SAFE_FREE(ipc_domain); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 5aa8d2359f1..e23140bdb00 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -723,7 +723,7 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd) &server_ip, 0, "IPC$", "IPC", username, domain, - password, 0); + password, 0, NULL); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status))); diff --git a/source3/smbd/change_trust_pw.c b/source3/smbd/change_trust_pw.c index 4b2944a96f2..5da735e8751 100644 --- a/source3/smbd/change_trust_pw.c +++ b/source3/smbd/change_trust_pw.c @@ -50,7 +50,7 @@ static NTSTATUS modify_trust_password( char *domain, char *remote_machine, NULL, 0, "IPC$", "IPC", "", "", - "", 0))) { + "", 0, NULL))) { DEBUG(0,("modify_trust_password: Connection to %s failed!\n", remote_machine)); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/utils/net.c b/source3/utils/net.c index b3b72e24658..d38ca58622a 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -121,7 +121,7 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip, server_ip, opt_port, "IPC$", "IPC", opt_user_name, opt_workgroup, - opt_password, 0); + opt_password, 0, NULL); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -151,7 +151,7 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c, server_ip, opt_port, "IPC$", "IPC", "", "", - "", 0); + "", 0, NULL); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 2e8317f05a3..940187407cf 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -722,7 +722,7 @@ static struct cli_state *connect_one(char *share) &ip, 0, share, "?????", username, global_myworkgroup, - password, 0))) { + password, 0, NULL))) { return c; } else { DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); diff --git a/source3/utils/smbtree.c b/source3/utils/smbtree.c index b733f8112f3..940120d644f 100644 --- a/source3/utils/smbtree.c +++ b/source3/utils/smbtree.c @@ -100,7 +100,7 @@ static struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", user_info->username, lp_workgroup(), user_info->password, - CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK); + CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, NULL); if (NT_STATUS_IS_OK(nt_status)) { return cli; -- 2.34.1