static void http_download(WEBBLK *webblk, char *filename) { char buffer[HTTP_PATH_LENGTH]; char tbuf[80]; int fd, length; char *filetype; char fullname[HTTP_PATH_LENGTH]; struct stat st; MIMETAB *mime_type = mime_types; strlcpy( fullname, http_serv.httproot, sizeof(fullname) ); strlcat( fullname, filename, sizeof(fullname) ); http_verify_path(webblk,fullname); if(stat(fullname,&st)) http_error(webblk, "404 File Not Found","", strerror(errno)); if(!S_ISREG(st.st_mode)) http_error(webblk, "404 File Not Found","", "The requested file is not a regular file"); fd = HOPEN(fullname,O_RDONLY|O_BINARY,0); if (fd == -1) http_error(webblk, "404 File Not Found","", strerror(errno)); hprintf(webblk->sock,"HTTP/1.0 200 OK\n"); if ((filetype = strrchr(filename,'.'))) for(mime_type++;mime_type->suffix && strcasecmp(mime_type->suffix,filetype + 1); mime_type++); if(mime_type->type) hprintf(webblk->sock,"Content-Type: %s\n", mime_type->type); hprintf(webblk->sock,"Expires: %s\n", http_timestring(tbuf,sizeof(tbuf),time(NULL)+HTML_STATIC_EXPIRY_TIME)); hprintf(webblk->sock,"Content-Length: %d\n\n", (int)st.st_size); while ((length = read(fd, buffer, sizeof(buffer))) > 0) hwrite(webblk->sock,buffer, length); close(fd); http_exit(webblk); }
static uint32_t map_share_comment(struct fss_sc_smap *sc_smap, const struct fss_sc *sc) { char *time_str; time_str = http_timestring(sc_smap, sc->create_ts); if (time_str == NULL) { return HRES_ERROR_V(HRES_E_OUTOFMEMORY); } sc_smap->sc_share_comment = talloc_asprintf(sc_smap, "Shadow copy of %s taken %s", sc_smap->share_name, time_str); if (sc_smap->sc_share_comment == NULL) { return HRES_ERROR_V(HRES_E_OUTOFMEMORY); } return 0; }
static BOOL ads_cleanup_expired_creds(krb5_context context, krb5_ccache ccache, krb5_creds *credsp) { krb5_error_code retval; const char *cc_type = krb5_cc_get_type(context, ccache); DEBUG(3, ("ads_cleanup_expired_creds: Ticket in ccache[%s:%s] expiration %s\n", cc_type, krb5_cc_get_name(context, ccache), http_timestring(credsp->times.endtime))); /* we will probably need new tickets if the current ones will expire within 10 seconds. */ if (credsp->times.endtime >= (time(NULL) + 10)) return False; /* heimdal won't remove creds from a file ccache, and perhaps we shouldn't anyway, since internally we use memory ccaches, and a FILE one probably means that we're using creds obtained outside of our exectuable */ if (strequal(cc_type, "FILE")) { DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a %s ccache\n", cc_type)); return False; } retval = krb5_cc_remove_cred(context, ccache, 0, credsp); if (retval) { DEBUG(1, ("ads_cleanup_expired_creds: krb5_cc_remove_cred failed, err %s\n", error_message(retval))); /* If we have an error in this, we want to display it, but continue as though we deleted it */ } return True; }
static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdstyle) { uid_t uid; time_t tmp; /* TODO: check if entry is a user or a workstation */ if (!sam_pwent) return -1; if (verbosity) { char temp[44]; const uint8_t *hours; printf ("Unix username: %s\n", pdb_get_username(sam_pwent)); printf ("NT username: %s\n", pdb_get_nt_username(sam_pwent)); printf ("Account Flags: %s\n", pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent), NEW_PW_FORMAT_SPACE_PADDED_LEN)); printf ("User SID: %s\n", sid_string_tos(pdb_get_user_sid(sam_pwent))); printf ("Primary Group SID: %s\n", sid_string_tos(pdb_get_group_sid(sam_pwent))); printf ("Full Name: %s\n", pdb_get_fullname(sam_pwent)); printf ("Home Directory: %s\n", pdb_get_homedir(sam_pwent)); printf ("HomeDir Drive: %s\n", pdb_get_dir_drive(sam_pwent)); printf ("Logon Script: %s\n", pdb_get_logon_script(sam_pwent)); printf ("Profile Path: %s\n", pdb_get_profile_path(sam_pwent)); printf ("Domain: %s\n", pdb_get_domain(sam_pwent)); printf ("Account desc: %s\n", pdb_get_acct_desc(sam_pwent)); printf ("Workstations: %s\n", pdb_get_workstations(sam_pwent)); printf ("Munged dial: %s\n", pdb_get_munged_dial(sam_pwent)); tmp = pdb_get_logon_time(sam_pwent); printf ("Logon time: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_logoff_time(sam_pwent); printf ("Logoff time: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_kickoff_time(sam_pwent); printf ("Kickoff time: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_pass_last_set_time(sam_pwent); printf ("Password last set: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_pass_can_change_time(sam_pwent); printf ("Password can change: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_pass_must_change_time(sam_pwent); printf ("Password must change: %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); tmp = pdb_get_bad_password_time(sam_pwent); printf ("Last bad password : %s\n", tmp ? http_timestring(talloc_tos(), tmp) : "0"); printf ("Bad password count : %d\n", pdb_get_bad_password_count(sam_pwent)); hours = pdb_get_hours(sam_pwent); pdb_sethexhours(temp, hours); printf ("Logon hours : %s\n", temp); } else if (smbpwdstyle) { char lm_passwd[33]; char nt_passwd[33]; uid = nametouid(pdb_get_username(sam_pwent)); pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); printf("%s:%lu:%s:%s:%s:LCT-%08X:\n", pdb_get_username(sam_pwent), (unsigned long)uid, lm_passwd, nt_passwd, pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32_t)convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sam_pwent))); } else { uid = nametouid(pdb_get_username(sam_pwent)); printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid, pdb_get_fullname(sam_pwent)); } return 0; }
static void *http_request(void* arg) { WEBBLK *webblk; int authok = !http_serv.httpauth; char line[HTTP_PATH_LENGTH]; char *url = NULL; char *pointer; char *strtok_str = NULL; CGITAB *cgient; int content_length = 0; int sock = (int) (uintptr_t) arg; if(!(webblk = malloc(sizeof(WEBBLK)))) http_exit(webblk); memset(webblk,0,sizeof(WEBBLK)); webblk->sock = sock; while (hgets(line, sizeof(line), webblk->sock)) { if (*line == '\r' || *line == '\n') break; if((pointer = strtok_r(line," \t\r\n",&strtok_str))) { if(!strcasecmp(pointer,"GET")) { if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) { webblk->request_type = REQTYPE_GET; url = strdup(pointer); } } else if(!strcasecmp(pointer,"POST")) { if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) { webblk->request_type = REQTYPE_POST; url = strdup(pointer); } } else if(!strcasecmp(pointer,"PUT")) { http_error(webblk,"400 Bad Request", "", "This server does not accept PUT requests"); } else if(!strcasecmp(pointer,"Authorization:")) { if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) authok = http_authenticate(webblk,pointer, strtok_r(NULL," \t\r\n",&strtok_str)); } else if(!strcasecmp(pointer,"Cookie:")) { if((pointer = strtok_r(NULL,"\r\n",&strtok_str))) http_interpret_variable_string(webblk, pointer, VARTYPE_COOKIE); } else if(!strcasecmp(pointer,"Content-Length:")) { if((pointer = strtok_r(NULL," \t\r\n",&strtok_str))) content_length = atoi(pointer); } } } webblk->request = url; if(webblk->request_type == REQTYPE_POST && content_length != 0) { char *post_arg; if((pointer = post_arg = malloc(content_length + 1))) { int i; for(i = 0; i < content_length; i++) { *pointer = hgetc(webblk->sock); if(*pointer != '\n' && *pointer != '\r') pointer++; } *pointer = '\0'; http_interpret_variable_string(webblk, post_arg, VARTYPE_POST); free(post_arg); } } if (!authok) { http_error(webblk, "401 Authorization Required", "WWW-Authenticate: Basic realm=\"HERCULES\"\n", "You must be authenticated to use this service"); } if (!url) { http_error(webblk,"400 Bad Request", "", "You must specify a GET or POST request"); } /* anything following a ? in the URL is part of the get arguments */ if ((pointer=strchr(url,'?'))) { *pointer++ = 0; http_interpret_variable_string(webblk, pointer, VARTYPE_GET); } while(url[0] == '/' && url[1] == '/') url++; webblk->baseurl = url; if(!strcasecmp("/",url)) url = HTTP_WELCOME; if(strncasecmp("/cgi-bin/",url,9)) http_download(webblk,url); else url += 9; while(*url == '/') url++; #if 0 http_dump_cgi_variables(webblk); #endif for(cgient = cgidir; cgient->path; cgient++) { if(!strcmp(cgient->path, url)) { char tbuf[80]; hprintf(webblk->sock,"HTTP/1.0 200 OK\nConnection: close\n"); hprintf(webblk->sock,"Date: %s\n", http_timestring(tbuf,sizeof(tbuf),time(NULL))); (cgient->cgibin) (webblk); http_exit(webblk); } } #if defined(OPTION_DYNAMIC_LOAD) { zz_cgibin dyncgi; if( (dyncgi = HDL_FINDSYM(webblk->baseurl)) ) { char tbuf[80]; hprintf(webblk->sock,"HTTP/1.0 200 OK\nConnection: close\n"); hprintf(webblk->sock,"Date: %s\n", http_timestring(tbuf,sizeof(tbuf),time(NULL))); dyncgi(webblk); http_exit(webblk); } } #endif /*defined(OPTION_DYNAMIC_LOAD)*/ http_error(webblk, "404 File Not Found","", "The requested file was not found"); return NULL; }
static NTSTATUS cmd_eventlog_reporteventsource(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS status, result; struct policy_handle handle; struct dcerpc_binding_handle *b = cli->binding_handle; uint16_t num_of_strings = 1; uint32_t data_size = 0; struct lsa_String servername, sourcename; struct lsa_String *strings; uint8_t *data = NULL; uint32_t record_number = 0; time_t time_written = 0; if (argc != 2) { printf("Usage: %s logname\n", argv[0]); return NT_STATUS_OK; } status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle); if (!NT_STATUS_IS_OK(status)) { return status; } strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings); if (!strings) { return NT_STATUS_NO_MEMORY; } init_lsa_String(&strings[0], "test event written by rpcclient\n"); init_lsa_String(&servername, NULL); init_lsa_String(&sourcename, "rpcclient"); status = dcerpc_eventlog_ReportEventAndSourceW(b, mem_ctx, &handle, time(NULL), EVENTLOG_INFORMATION_TYPE, 0, /* event_category */ 0, /* event_id */ &sourcename, num_of_strings, data_size, &servername, NULL, /* user_sid */ &strings, data, 0, /* flags */ &record_number, &time_written, &result); if (!NT_STATUS_IS_OK(status)) { goto done; } if (!NT_STATUS_IS_OK(result)) { status = result; goto done; } printf("entry: %d written at %s\n", record_number, http_timestring(talloc_tos(), time_written)); done: dcerpc_eventlog_CloseEventLog(b, mem_ctx, &handle, &result); return status; }
static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, struct samu *sampass, const auth_usersupplied_info *user_info) { uint32 acct_ctrl = pdb_get_acct_ctrl(sampass); char *workstation_list; time_t kickoff_time; DEBUG(4,("sam_account_ok: Checking SMB password for user %s\n",pdb_get_username(sampass))); /* Quit if the account was disabled. */ if (acct_ctrl & ACB_DISABLED) { DEBUG(1,("sam_account_ok: Account for user '%s' was disabled.\n", pdb_get_username(sampass))); return NT_STATUS_ACCOUNT_DISABLED; } /* Quit if the account was locked out. */ if (acct_ctrl & ACB_AUTOLOCK) { DEBUG(1,("sam_account_ok: Account for user %s was locked out.\n", pdb_get_username(sampass))); return NT_STATUS_ACCOUNT_LOCKED_OUT; } /* Quit if the account is not allowed to logon at this time. */ if (! logon_hours_ok(sampass)) { return NT_STATUS_INVALID_LOGON_HOURS; } /* Test account expire time */ kickoff_time = pdb_get_kickoff_time(sampass); if (kickoff_time != 0 && time(NULL) > kickoff_time) { DEBUG(1,("sam_account_ok: Account for user '%s' has expired.\n", pdb_get_username(sampass))); DEBUG(3,("sam_account_ok: Account expired at '%ld' unix time.\n", (long)kickoff_time)); return NT_STATUS_ACCOUNT_EXPIRED; } if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP) && !(pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) { time_t must_change_time = pdb_get_pass_must_change_time(sampass); time_t last_set_time = pdb_get_pass_last_set_time(sampass); /* check for immediate expiry "must change at next logon" * for a user account. */ if (((acct_ctrl & (ACB_WSTRUST|ACB_SVRTRUST)) == 0) && (last_set_time == 0)) { DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n", pdb_get_username(sampass))); return NT_STATUS_PASSWORD_MUST_CHANGE; } /* check for expired password */ if (must_change_time < time(NULL) && must_change_time != 0) { DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n", pdb_get_username(sampass))); DEBUG(1,("sam_account_ok: Password expired at '%s' (%ld) unix time.\n", http_timestring(must_change_time), (long)must_change_time)); return NT_STATUS_PASSWORD_EXPIRED; } } /* Test workstation. Workstation list is comma separated. */ workstation_list = talloc_strdup(mem_ctx, pdb_get_workstations(sampass)); if (!workstation_list) return NT_STATUS_NO_MEMORY; if (*workstation_list) { BOOL invalid_ws = True; fstring tok; const char *s = workstation_list; const char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name); if (machine_name == NULL) return NT_STATUS_NO_MEMORY; while (next_token(&s, tok, ",", sizeof(tok))) { DEBUG(10,("sam_account_ok: checking for workstation match %s and %s\n", tok, user_info->wksta_name)); if(strequal(tok, user_info->wksta_name)) { invalid_ws = False; break; } if (tok[0] == '+') { DEBUG(10,("sam_account_ok: checking for workstation %s in group: %s\n", machine_name, tok + 1)); if (user_in_group(machine_name, tok + 1)) { invalid_ws = False; break; } } } if (invalid_ws) return NT_STATUS_INVALID_WORKSTATION; } if (acct_ctrl & ACB_DOMTRUST) { DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", pdb_get_username(sampass))); return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT; } if (acct_ctrl & ACB_SVRTRUST) { if (!(user_info->logon_parameters & MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT)) { DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", pdb_get_username(sampass))); return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT; } } if (acct_ctrl & ACB_WSTRUST) { if (!(user_info->logon_parameters & MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT)) { DEBUG(2,("sam_account_ok: Wksta trust account %s denied by server\n", pdb_get_username(sampass))); return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT; } } return NT_STATUS_OK; }
/** * @brief Setup the CGI framework. * * Setup the cgi framework, handling the possibility that this program * is either run as a true CGI program with a gateway to a web server, or * is itself a mini web server. **/ void cgi_setup(const char *rootdir, int auth_required) { bool authenticated = False; char line[1024]; char *url=NULL; char *p; char *lang; if (chdir(rootdir)) { cgi_setup_error("500 Server Error", "", "chdir failed - the server is not configured correctly"); } /* Handle the possibility we might be running as non-root */ sec_init(); if ((lang=getenv("HTTP_ACCEPT_LANGUAGE"))) { /* if running as a cgi program */ web_set_lang(lang); } /* maybe we are running under a web server */ if (getenv("CONTENT_LENGTH") || getenv("REQUEST_METHOD")) { if (auth_required) { cgi_web_auth(); } return; } inetd_server = True; if (!check_access(1, lp_hostsallow(-1), lp_hostsdeny(-1))) { cgi_setup_error("403 Forbidden", "", "Samba is configured to deny access from this client\n<br>Check your \"hosts allow\" and \"hosts deny\" options in smb.conf "); } /* we are a mini-web server. We need to read the request from stdin and handle authentication etc */ while (fgets(line, sizeof(line)-1, stdin)) { if (line[0] == '\r' || line[0] == '\n') break; if (strnequal(line,"GET ", 4)) { got_request = True; url = SMB_STRDUP(&line[4]); } else if (strnequal(line,"POST ", 5)) { got_request = True; request_post = 1; url = SMB_STRDUP(&line[5]); } else if (strnequal(line,"PUT ", 4)) { got_request = True; cgi_setup_error("400 Bad Request", "", "This server does not accept PUT requests"); } else if (strnequal(line,"Authorization: ", 15)) { authenticated = cgi_handle_authorization(&line[15]); } else if (strnequal(line,"Content-Length: ", 16)) { content_length = atoi(&line[16]); } else if (strnequal(line,"Accept-Language: ", 17)) { web_set_lang(&line[17]); } /* ignore all other requests! */ } if (auth_required && !authenticated) { cgi_auth_error(); } if (!url) { cgi_setup_error("400 Bad Request", "", "You must specify a GET or POST request"); } /* trim the URL */ if ((p = strchr_m(url,' ')) || (p=strchr_m(url,'\t'))) { *p = 0; } while (*url && strchr_m("\r\n",url[strlen(url)-1])) { url[strlen(url)-1] = 0; } /* anything following a ? in the URL is part of the query string */ if ((p=strchr_m(url,'?'))) { query_string = p+1; *p = 0; } string_sub(url, "/swat/", "", 0); if (url[0] != '/' && strstr(url,"..")==0) { cgi_download(url); } printf("HTTP/1.0 200 OK\r\nConnection: close\r\n"); printf("Date: %s\r\n", http_timestring(time(NULL))); baseurl = ""; pathinfo = url+1; }
/*************************************************************************** handle a file download ***************************************************************************/ static void cgi_download(char *file) { SMB_STRUCT_STAT st; char buf[1024]; int fd, l, i; char *p; char *lang; /* sanitise the filename */ for (i=0;file[i];i++) { if (!isalnum((int)file[i]) && !strchr_m("/.-_", file[i])) { cgi_setup_error("404 File Not Found","", "Illegal character in filename"); } } if (sys_stat(file, &st) != 0) { cgi_setup_error("404 File Not Found","", "The requested file was not found"); } if (S_ISDIR(st.st_mode)) { snprintf(buf, sizeof(buf), "%s/index.html", file); if (!file_exist(buf, &st) || !S_ISREG(st.st_mode)) { cgi_setup_error("404 File Not Found","", "The requested file was not found"); } } else if (S_ISREG(st.st_mode)) { snprintf(buf, sizeof(buf), "%s", file); } else { cgi_setup_error("404 File Not Found","", "The requested file was not found"); } fd = web_open(buf,O_RDONLY,0); if (fd == -1) { cgi_setup_error("404 File Not Found","", "The requested file was not found"); } printf("HTTP/1.0 200 OK\r\n"); if ((p=strrchr_m(buf, '.'))) { if (strcmp(p,".gif")==0) { printf("Content-Type: image/gif\r\n"); } else if (strcmp(p,".jpg")==0) { printf("Content-Type: image/jpeg\r\n"); } else if (strcmp(p,".png")==0) { printf("Content-Type: image/png\r\n"); } else if (strcmp(p,".css")==0) { printf("Content-Type: text/css\r\n"); } else if (strcmp(p,".txt")==0) { printf("Content-Type: text/plain\r\n"); } else { printf("Content-Type: text/html\r\n"); } } printf("Expires: %s\r\n", http_timestring(time(NULL)+EXPIRY_TIME)); lang = lang_tdb_current(); if (lang) { printf("Content-Language: %s\r\n", lang); } printf("Content-Length: %d\r\n\r\n", (int)st.st_size); while ((l=read(fd,buf,sizeof(buf)))>0) { if (fwrite(buf, 1, l, stdout) != l) { break; } } close(fd); exit(0); }
/* * Given the username/password, do a kinit, store the ticket in * cache_name if specified, and return the PAC_LOGON_INFO (the * structure containing the important user information such as * groups). */ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, const char *name, const char *pass, time_t time_offset, time_t *expire_time, time_t *renew_till_time, const char *cache_name, bool request_pac, bool add_netbios_addr, time_t renewable_time, const char *impersonate_princ_s, struct PAC_LOGON_INFO **_logon_info) { krb5_error_code ret; NTSTATUS status = NT_STATUS_INVALID_PARAMETER; DATA_BLOB tkt, tkt_wrapped, ap_rep, sesskey1; const char *auth_princ = NULL; const char *local_service = NULL; const char *cc = "MEMORY:kerberos_return_pac"; struct auth_session_info *session_info; struct gensec_security *gensec_server_context; struct gensec_settings *gensec_settings; size_t idx = 0; struct auth4_context *auth_context; struct loadparm_context *lp_ctx; struct PAC_LOGON_INFO *logon_info = NULL; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); ZERO_STRUCT(tkt); ZERO_STRUCT(ap_rep); ZERO_STRUCT(sesskey1); if (!name || !pass) { return NT_STATUS_INVALID_PARAMETER; } if (cache_name) { cc = cache_name; } if (!strchr_m(name, '@')) { auth_princ = talloc_asprintf(mem_ctx, "%s@%s", name, lp_realm()); } else { auth_princ = name; } NT_STATUS_HAVE_NO_MEMORY(auth_princ); local_service = talloc_asprintf(mem_ctx, "%s$@%s", lp_netbios_name(), lp_realm()); NT_STATUS_HAVE_NO_MEMORY(local_service); ret = kerberos_kinit_password_ext(auth_princ, pass, time_offset, expire_time, renew_till_time, cc, request_pac, add_netbios_addr, renewable_time, &status); if (ret) { DEBUG(1,("kinit failed for '%s' with: %s (%d)\n", auth_princ, error_message(ret), ret)); /* status already set */ goto out; } DEBUG(10,("got TGT for %s in %s\n", auth_princ, cc)); if (expire_time) { DEBUGADD(10,("\tvalid until: %s (%d)\n", http_timestring(talloc_tos(), *expire_time), (int)*expire_time)); } if (renew_till_time) { DEBUGADD(10,("\trenewable till: %s (%d)\n", http_timestring(talloc_tos(), *renew_till_time), (int)*renew_till_time)); } /* we cannot continue with krb5 when UF_DONT_REQUIRE_PREAUTH is set, * in that case fallback to NTLM - gd */ if (expire_time && renew_till_time && (*expire_time == 0) && (*renew_till_time == 0)) { return NT_STATUS_INVALID_LOGON_TYPE; } ret = cli_krb5_get_ticket(mem_ctx, local_service, time_offset, &tkt, &sesskey1, 0, cc, NULL, impersonate_princ_s); if (ret) { DEBUG(1,("failed to get ticket for %s: %s\n", local_service, error_message(ret))); if (impersonate_princ_s) { DEBUGADD(1,("tried S4U2SELF impersonation as: %s\n", impersonate_princ_s)); } status = krb5_to_nt_status(ret); goto out; } /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tmp_ctx, tkt, TOK_ID_KRB_AP_REQ); if (tkt_wrapped.data == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } auth_context = talloc_zero(tmp_ctx, struct auth4_context); if (auth_context == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } auth_context->generate_session_info_pac = kerberos_fetch_pac; lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_context()); if (lp_ctx == NULL) { status = NT_STATUS_INVALID_SERVER_STATE; DEBUG(10, ("loadparm_init_s3 failed\n")); goto out; } gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx); if (lp_ctx == NULL) { status = NT_STATUS_NO_MEMORY; DEBUG(10, ("lpcfg_gensec_settings failed\n")); goto out; } gensec_settings->backends = talloc_zero_array(gensec_settings, struct gensec_security_ops *, 2); if (gensec_settings->backends == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } gensec_init(); gensec_settings->backends[idx++] = &gensec_gse_krb5_security_ops; status = gensec_server_start(tmp_ctx, gensec_settings, auth_context, &gensec_server_context); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, (__location__ "Failed to start server-side GENSEC to validate a Kerberos ticket: %s\n", nt_errstr(status))); goto out; } talloc_unlink(tmp_ctx, lp_ctx); talloc_unlink(tmp_ctx, gensec_settings); talloc_unlink(tmp_ctx, auth_context); status = gensec_start_mech_by_oid(gensec_server_context, GENSEC_OID_KERBEROS5); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, (__location__ "Failed to start server-side GENSEC krb5 to validate a Kerberos ticket: %s\n", nt_errstr(status))); goto out; } /* Do a client-server update dance */ status = gensec_update(gensec_server_context, tmp_ctx, NULL, tkt_wrapped, &ap_rep); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("gensec_update() failed: %s\n", nt_errstr(status))); goto out; } /* Now return the PAC information to the callers. We ingore * the session_info and instead pick out the PAC via the * private_data on the auth_context */ status = gensec_session_info(gensec_server_context, tmp_ctx, &session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Unable to obtain PAC via gensec_session_info\n")); goto out; } logon_info = talloc_get_type_abort(gensec_server_context->auth_context->private_data, struct PAC_LOGON_INFO); if (logon_info == NULL) { DEBUG(1,("no PAC\n")); status = NT_STATUS_INVALID_PARAMETER; goto out; } *_logon_info = talloc_move(mem_ctx, &logon_info); out: talloc_free(tmp_ctx); if (cc != cache_name) { ads_kdestroy(cc); } data_blob_free(&tkt); data_blob_free(&ap_rep); data_blob_free(&sesskey1); return status; }
/* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, const char *principal, krb5_ccache ccache, krb5_data *outbuf, time_t *expire_time) { krb5_error_code retval; krb5_principal server; krb5_creds * credsp; krb5_creds creds; krb5_data in_data; BOOL creds_ready = False; int i = 0, maxtries = 3; retval = smb_krb5_parse_name(context, principal, &server); if (retval) { DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal)); return retval; } /* obtain ticket & session key */ ZERO_STRUCT(creds); if ((retval = krb5_copy_principal(context, server, &creds.server))) { DEBUG(1,("ads_krb5_mk_req: krb5_copy_principal failed (%s)\n", error_message(retval))); goto cleanup_princ; } if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { /* This can commonly fail on smbd startup with no ticket in the cache. * Report at higher level than 1. */ DEBUG(3,("ads_krb5_mk_req: krb5_cc_get_principal failed (%s)\n", error_message(retval))); goto cleanup_creds; } while (!creds_ready && (i < maxtries)) { if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { DEBUG(1,("ads_krb5_mk_req: krb5_get_credentials failed for %s (%s)\n", principal, error_message(retval))); goto cleanup_creds; } /* cope with ticket being in the future due to clock skew */ if ((unsigned)credsp->times.starttime > time(NULL)) { time_t t = time(NULL); int time_offset =(int)((unsigned)credsp->times.starttime-t); DEBUG(4,("ads_krb5_mk_req: Advancing clock by %d seconds to cope with clock skew\n", time_offset)); krb5_set_real_time(context, t + time_offset + 1, 0); } if (!ads_cleanup_expired_creds(context, ccache, credsp)) { creds_ready = True; } i++; } DEBUG(10,("ads_krb5_mk_req: Ticket (%s) in ccache (%s:%s) is valid until: (%s - %u)\n", principal, krb5_cc_get_type(context, ccache), krb5_cc_get_name(context, ccache), http_timestring((unsigned)credsp->times.endtime), (unsigned)credsp->times.endtime)); if (expire_time) { *expire_time = (time_t)credsp->times.endtime; } in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); if (retval) { DEBUG(1,("ads_krb5_mk_req: krb5_mk_req_extended failed (%s)\n", error_message(retval))); } krb5_free_creds(context, credsp); cleanup_creds: krb5_free_cred_contents(context, &creds); cleanup_princ: krb5_free_principal(context, server); return retval; }
/**************************************************************************** display sam_user_info_21 structure ****************************************************************************/ static void display_sam_user_info_21(SAM_USER_INFO_21 *usr) { fstring temp; unistr2_to_unix(temp, &usr->uni_user_name, sizeof(temp)-1); printf("\tUser Name :\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_full_name, sizeof(temp)-1); printf("\tFull Name :\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_home_dir, sizeof(temp)-1); printf("\tHome Drive :\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_dir_drive, sizeof(temp)-1); printf("\tDir Drive :\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_profile_path, sizeof(temp)-1); printf("\tProfile Path:\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_logon_script, sizeof(temp)-1); printf("\tLogon Script:\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_acct_desc, sizeof(temp)-1); printf("\tDescription :\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_workstations, sizeof(temp)-1); printf("\tWorkstations:\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_unknown_str, sizeof(temp)-1); printf("\tUnknown Str :\t%s\n", temp); unistr2_to_unix(temp, &usr->uni_munged_dial, sizeof(temp)-1); printf("\tRemote Dial :\t%s\n", temp); printf("\tLogon Time :\t%s\n", http_timestring(nt_time_to_unix(&usr->logon_time))); printf("\tLogoff Time :\t%s\n", http_timestring(nt_time_to_unix(&usr->logoff_time))); printf("\tKickoff Time :\t%s\n", http_timestring(nt_time_to_unix(&usr->kickoff_time))); printf("\tPassword last set Time :\t%s\n", http_timestring(nt_time_to_unix(&usr->pass_last_set_time))); printf("\tPassword can change Time :\t%s\n", http_timestring(nt_time_to_unix(&usr->pass_can_change_time))); printf("\tPassword must change Time:\t%s\n", http_timestring(nt_time_to_unix(&usr->pass_must_change_time))); printf("\tunknown_2[0..31]...\n"); /* user passwords? */ printf("\tuser_rid :\t%x\n" , usr->user_rid ); /* User ID */ printf("\tgroup_rid:\t%x\n" , usr->group_rid); /* Group ID */ printf("\tacb_info :\t%04x\n", usr->acb_info ); /* Account Control Info */ printf("\tunknown_3:\t%08x\n", usr->unknown_3); /* 0x00ff ffff */ printf("\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */ printf("\tunknown_5:\t%08x\n", usr->unknown_5); /* 0x0002 0000 */ printf("\tpadding1[0..7]...\n"); if (usr->ptr_logon_hrs) { printf("\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len); } }