/* * 用户信息注册,conn_ed---从该连接套接字上接收信息 * */ void use_register(int conn_fd) { char buf[32]; char name[32]; //用户名 char passwd1[32]; //分别保存两次输入密码 char passwd2[32]; char string[40]; //缓存区 int flag = 1; //循环标志,1时执行,0退出 memset(string, 0, sizeof(string)); send_data(conn_fd, "r\n"); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); if (buf[0] == 'b') { do { send_data(conn_fd, "u\n"); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); input_userinfo(conn_fd, "\n\n\t\t用户名:"); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); if (buf[0] == 'n') { printf("该用户已存在\n"); continue; } printf("恭喜您,该用户名可以使用,请继续操作\n"); printf("请输入密码:"); get_passwd(passwd1); printf("\n请再次输入密码:"); get_passwd(passwd2); if (strcmp(passwd1, passwd2) != 0) { printf("两次输入不一致,请重新输入\n"); continue; } else { flag = 0; } passwd1[strlen(passwd1)] = '\n'; passwd1[strlen(passwd1) + 1] = '\0'; send_data(conn_fd, "p\n"); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); send_data(conn_fd, passwd1); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); if (buf[0] == 'y') { printf("注册成功\n"); return; } }while (flag); } }
/*********************************************************** * check user has permission to send mail * ************************************************************/ int MailCheck(char *address) { if(!is_emailaddr(address)) { USEREC user; if (get_passwd(&user, address) <= 0) { strncpy(username, address, IDLEN); return WEB_USER_NOT_FOUND; } if(isExceedMailLimit(&user)) return WEB_ERROR; } #ifdef USE_IDENT else { if(curuser.ident!=7) return WEB_USER_NOT_IDENT; } #endif return WEB_OK; }
/******************************************************************* * 張貼文章 * * 佈告、信件 通用 * * return: WebRespondType *******************************************************************/ int PostArticle(char *pbuf, BOARDHEADER * board, POST_FILE * pf) { BOOL tonews = FALSE; char *p; unsigned char flag = 0x00; FILE *fp; int sign_num, URLParaType = request_rec->URLParaType; char fname[PATHLEN], post_path[PATHLEN], address[STRLEN], post_source[STRLEN], subject[STRLEN]; char buffer[STRLEN * 3]; if (URLParaType == PostSend || URLParaType == TreaSend) { if (PSCorrect == gLogin) /* guest */ { if (!strstr(_STR_BOARD_GUEST, board->filename)) return WEB_GUEST_NOT_ALLOW; else get_passwd(&curuser, username); } if ((curuser.userlevel < board->level)) { sprintf(WEBBBS_ERROR_MESSAGE, "%s 無權張貼文章於 %s 一般區<BR>理由: 使用者等級 < %d", username, board->filename, board->level); return WEB_ERROR; } if ((board->brdtype & BRD_IDENT) && (curuser.ident != 7)) { sprintf(WEBBBS_ERROR_MESSAGE, "%s 無權張貼文章於 %s 一般區<BR>理由: 未通過身份認證", username, board->filename); return WEB_ERROR; } #if 0 make_treasure_folder(direct, title, NULL) #endif /* treapost */ if (URLParaType == TreaSend) { if (!HAS_PERM(PERM_SYSOP) && strcmp(username, board->owner)) { sprintf(WEBBBS_ERROR_MESSAGE, "%s 無權張貼文章於 %s 精華區", username, board->filename); return WEB_ERROR; } settreafile(post_path, board->filename, pf->POST_NAME); } } else /* Send Mail */ {
void BMailProtocolConfigView::SetTo(MailAddonSettings& settings) { const BMessage* archive = &settings.Settings(); BString host = archive->FindString("server"); if (archive->HasInt32("port")) host << ':' << archive->FindInt32("port"); SetTextControl(this,"host", host.String()); SetTextControl(this,"user", archive->FindString("username")); char *password = get_passwd(archive, "cpasswd"); if (password) { SetTextControl(this,"pass", password); delete[] password; } else SetTextControl(this,"pass", archive->FindString("password")); if (archive->HasInt32("flavor")) { BMenuField *menu = (BMenuField *)(FindView("flavor")); if (menu != NULL) { if (BMenuItem *item = menu->Menu()->ItemAt(archive->FindInt32("flavor"))) item->SetMarked(true); } } if (archive->HasInt32("auth_method")) { BMenuField *menu = (BMenuField *)(FindView("auth_method")); if (menu != NULL) { if (BMenuItem *item = menu->Menu()->ItemAt(archive->FindInt32("auth_method"))) { item->SetMarked(true); if (item->Command() != 'none') { enable_control("user"); enable_control("pass"); } } } } BCheckBox *box = (BCheckBox *)(FindView("leave_mail_on_server")); if (box != NULL) box->SetValue(archive->FindBool("leave_mail_on_server") ? B_CONTROL_ON : B_CONTROL_OFF); box = (BCheckBox *)(FindView("delete_remote_when_local")); if (box != NULL) { box->SetValue(archive->FindBool("delete_remote_when_local") ? B_CONTROL_ON : B_CONTROL_OFF); if (archive->FindBool("leave_mail_on_server")) box->SetEnabled(true); else box->SetEnabled(false); } if (fBodyDownloadConfig) fBodyDownloadConfig->SetTo(settings); }
int is_ident_ok(const char *userid) { USEREC usr; if (get_passwd(&usr, userid) > 0 && usr.ident == 7) return 1; return 0; }
void user_land(int conn_fd) { char name[32]; char passwd[32]; char buf[SIZE]; int i; send_data(conn_fd, "l\n"); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); if (buf[0] == BEGIN) { while(1) { send_data(conn_fd, "u\n"); sleep(1); system("clear"); my_recv(conn_fd, buf, sizeof(buf)); input_userinfo(conn_fd, "\n\n\t\t用户名:"); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); if (buf[0] == 'n') { printf("该用户不存在,请重新输入\n"); continue; } printf("\t\t密码:"); get_passwd(passwd); send_data(conn_fd, "p\n"); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); send_data(conn_fd, passwd); sleep(1); my_recv(conn_fd, buf, sizeof(buf)); if (buf[0] == INVALID_USERINFO) { printf("密码错误,请重新输入\n"); continue; } else { break; } } system("clear"); printf("\n\n\tftp服务器欢迎您,请选择操作\n"); sleep(1); user_choose(conn_fd); } }
static int set_passwd_ident_ok(const char *name, char cond) { USEREC usr; if (get_passwd(&usr, name) > 0) { usr.ident = cond; if (update_passwd(&usr) > 0) return 0; } return -1; }
char *validate_passwd(char *user, char *pass) { char *cryptpass; cryptpass=get_passwd(user); #ifdef VISIBLE_PASSWD dbgtcos( "info validate_passwd(): pass=%s crypt=%s.\n", crypt (pass, PASS_ID), cryptpass); #endif if ( strcmp(crypt (pass, PASS_ID), cryptpass) == 0 ) return LOGIN_OK; return LOGIN_NOPASS; }
void FolderConfigWindow::_LoadFolders() { StatusWindow* status = new StatusWindow( B_TRANSLATE("Fetching IMAP folders, have patience...")); status->Show(); BString server; fSettings.FindString("server", &server); int32 ssl; fSettings.FindInt32("flavor", &ssl); bool useSSL = false; if (ssl == 1) useSSL = true; BString username; fSettings.FindString("username", &username); BString password; char* passwd = get_passwd(&fSettings, "cpasswd"); if (passwd != NULL) { password = passwd; delete[] passwd; } fIMAPFolders.Connect(server, username, password, useSSL); fFolderList.clear(); fIMAPFolders.GetFolders(fFolderList); for (unsigned int i = 0; i < fFolderList.size(); i++) { FolderInfo& info = fFolderList[i]; CheckBoxItem* item = new CheckBoxItem(info.folder, info.subscribed); fFolderListView->AddItem(item); item->SetListView(fFolderListView); } uint64 used, total; if (fIMAPFolders.GetQuota(used, total) == B_OK) { char buffer[256]; BString quotaString = "Server storage: "; quotaString += string_for_size(used, buffer, 256); quotaString += " / "; quotaString += string_for_size(total, buffer, 256); quotaString += " used."; fQuotaView->SetText(quotaString); } status->PostMessage(B_QUIT_REQUESTED); }
/* * log_in - show login UI, get username and password * - initialize login_user * return : status */ int log_in(void) { int ret; struct simple_frame frame; char username[USER_NAME_LEN + 1]; char password[USER_PASSWD_LEN + 1]; memset(username, 0, USER_NAME_LEN + 1); memset(password, 0, USER_PASSWD_LEN + 1); memset(&frame, 0, sizeof(frame)); memset(&login_user, 0, sizeof(login_user)); frame.item_num = 3; frame.items[0].pos.row = 1; frame.items[0].pos.col = 5; snprintf(frame.items[0].title, MAX_TITLE_LEN, "%s", "登 陆"); frame.items[1].pos.row = 2; frame.items[1].pos.col = 1; snprintf(frame.items[1].title, MAX_TITLE_LEN, "%s", "用户名:"); frame.items[2].pos.row = 4; frame.items[2].pos.col = 1; snprintf(frame.items[2].title, MAX_TITLE_LEN, "%s", "密 码:"); while (1) { show_simple_frame(&frame); while (get_string(2, 5, username) != SUCCESS); while (get_passwd(4, 5, password) != SUCCESS); tax_file_find_user(username, &login_user); ret = strcoll(password, login_user.passwd); if (ret != 0) { display_warn("用户名或密码错误!"); memset(username, 0, USER_NAME_LEN + 1); memset(password, 0, USER_PASSWD_LEN + 1); continue; } else if (ret == 0) { break; } } show_current_ui(0); return SUCCESS; }
status_t POP3Protocol::Connect() { status_t error = Open(fSettings.FindString("server"), fSettings.FindInt32("port"), fSettings.FindInt32("flavor")); if (error != B_OK) return error; char* password = get_passwd(&fSettings, "cpasswd"); error = Login(fSettings.FindString("username"), password, fSettings.FindInt32("auth_method")); delete[] password; return error; }
int create_account(char *username) { struct passwd *pw; int opt, type; char pwbuf[PWLEN + 1]; int ret; type = 0; if ((pw=newacc(username)) == 0) { fprintf(stderr, "Account not created\n"); return EXIT_FAILURE; } initdir(pw->pw_dir, pw->pw_uid, pw->pw_gid); if ((ret = get_passwd(pwbuf, type)) == -1) return EXIT_FAILURE; pw->pw_passwd = ret ? passwd_stub : nil_passwd; if (!lock_passwd()) { fprintf(stderr,"unable to lock password database (%s)\n",strerror(errno)); return PasswdBusy; } if ((opt = addpwent(pw)) == 0) { if (pw->pw_passwd && *pw->pw_passwd) { struct spwd spw; spw.sp_namp = pw->pw_name; spw.sp_pwdp = pwbuf; spw.sp_lstchg = time(0); spw.sp_max = 0; spw.sp_min = 0; spw.sp_warn = 0; spw.sp_inact = 0; spw.sp_expire = 0; spw.sp_flag = 0; if ((opt = addshent(&spw))) { fputs("cannot create shadow entry\n",stderr); delpw_name(pw->pw_name); } } } else { fputs("cannot create password entry\n", stderr); } unlock_passwd(); return opt; }
/******************************************************************* * check userlogin status * * return: ps_correct *******************************************************************/ int CheckUserPassword(char *username, char *password) { if (strlen(username) == 0) return nLogin; else if (!strcmp(username, "guest")) return gLogin; else { bzero(&curuser, sizeof(USEREC)); if (!get_passwd(&curuser, username) || !checkpasswd(curuser.passwd, password)) { return Error; } } return Correct; }
_EXPORT status_t get_pop_account(mail_pop_account* account, int32 index) { BMailAccounts accounts; BMailAccountSettings* accountSettings = accounts.AccountAt(index); if (accountSettings == NULL) return B_BAD_INDEX; const BMessage& settings = accountSettings->InboundSettings(); strcpy(account->pop_name, settings.FindString("username")); strcpy(account->pop_host, settings.FindString("server")); strcpy(account->real_name, accountSettings->RealName()); strcpy(account->reply_to, accountSettings->ReturnAddress()); const char* encryptedPassword = get_passwd(&settings, "cpasswd"); const char* password = encryptedPassword; if (password == NULL) password = settings.FindString("password"); strcpy(account->pop_password, password); delete[] encryptedPassword; return B_OK; }
int CheckMail(USEREC *urc, const char *to, BOOL strict) { char dotdir[PATHLEN]; int total; USEREC urcTmp, *u = (urc) ? urc : &urcTmp; int flexbility = (strict) ? 0 : 10; if (get_passwd(u, to) <= 0) return -1; if (u->userlevel == PERM_SYSOP) return 0; setmailfile(dotdir, to, DIR_REC); total = get_num_records(dotdir, FH_SIZE); if ((u->userlevel >= PERM_BM && total >= SPEC_MAX_KEEP_MAIL+flexbility) || (u->userlevel < PERM_BM && total >= MAX_KEEP_MAIL+flexbility)) { return -2; } return 0; }
/******************************************************************* * 根據 URLParaType 執行 GET 的要求 * * * return WebRespondType *******************************************************************/ int DoGetRequest(REQUEST_REC * rc, BOARDHEADER * board, POST_FILE * pf) { char *p, *boardname; int URLParaType = rc->URLParaType; char fname[PATHLEN]; boardname = board->filename; if (URLParaType == Redirect) { /* redirect target must set in ParseURI() */ return WEB_REDIRECT; } if (PSCorrect != Correct && (URLParaType == MailList || URLParaType == MailRead || URLParaType == SkinModify)) { return WEB_USER_NOT_LOGIN; } if (URLParaType == PostList || URLParaType == PostRead || URLParaType == TreaList || URLParaType == TreaRead || URLParaType == SkinModify || URLParaType == Board) { int perm; if (get_board(board, boardname) <= 0 || board->filename[0] == '\0') return WEB_BOARD_NOT_FOUND; if ((perm = CheckBoardPerm(board, &curuser)) != WEB_OK) return perm; if (board->brdtype & BRD_WEBSKIN) /* Board has custom html skin */ { char *skin, web_board_dir[PATHLEN]; if (URLParaType == SkinModify) { if (strlen(pf->POST_NAME) != 0) { xstrncpy(web_board_dir, pf->POST_NAME, PATHLEN); skin = strrchr(web_board_dir, '/') + 1; setskinfile(pf->POST_NAME, boardname, skin); } } else if (!strstr(skin_file->filename, HTML_BoardModify)) { /* set specfic skin file to custom file */ xstrncpy(web_board_dir, skin_file->filename, PATHLEN); skin = strrchr(web_board_dir, '/') + 1; setskinfile(skin_file->filename, boardname, skin); } } else { if (strstr(skin_file->filename, HTML_SkinModify)) return WEB_FILE_NOT_FOUND; } } if (strstr(skin_file->filename, HTML_BoardModify) && (!HAS_PERM(PERM_SYSOP) || PSCorrect != Correct)) { return WEB_FILE_NOT_FOUND; } switch (URLParaType) { case TreaRead: case PostRead: if (GetPostInfo(board, pf) != WEB_OK) return WEB_FILE_NOT_FOUND; break; case TreaList: case PostList: pf->total_rec = get_num_records(pf->POST_NAME, FH_SIZE); break; case MailList: if (PSCorrect == Correct) pf->total_rec = get_num_records(pf->POST_NAME, FH_SIZE); else pf->total_rec = 0; break; case MailRead: if (PSCorrect == Correct) { int RESULT = GetPostInfo(board, pf); if (RESULT != WEB_OK) return RESULT; } break; case UserList: case BoardList: case TreaBoardList: case UserData: case SkinModify: /* do nothing here.. */ break; case UserQuery: /* put USER_REC in curuser for query */ if (!get_passwd(&curuser, username)) { bzero(&curuser, sizeof(USEREC)); return WEB_USER_NOT_FOUND; } break; case Board: /* cuscom webboard */ case Mail: /* ?? */ #if 0 fprintf(fp_out, "DoGetRequest Board,Mail:[%s]", skin_file->filename); fflush(fp_out); #endif if (CacheState(skin_file->filename, NULL) < 0 && !isfile(skin_file->filename)) { return WEB_FILE_NOT_FOUND; } break; default: #if 0 fprintf(fp_out, "DoGetRequest default:[%s]\r\n", skin_file->filename); fflush(fp_out); #endif xstrncpy(fname, skin_file->filename, sizeof(fname)); if (isBadURI(fname)) { BBS_SUBDIR[0] = 0x00; return WEB_BAD_REQUEST; } sprintf(skin_file->filename, "%s%s", HTML_PATH, fname + 1); if (CacheState(skin_file->filename, NULL) == -1) /* file not in cache */ { if (isdir(skin_file->filename)) { p = skin_file->filename + strlen(skin_file->filename) - 1; if (*p == '/') { strcat(skin_file->filename, DEFAULT_HTML); } else { sprintf(skin_file->filename, "%s/", fname); return WEB_REDIRECT; } } else { if ((p = strrchr(fname + 1, '/')) == NULL) p = fname; if (!strcmp(p, "/boards") || !strcmp(p, "/treasure") || !strcmp(p, "/mail") || !strcmp(p, "/users")) { sprintf(skin_file->filename, "%s/", fname); return WEB_REDIRECT; } } if (!isfile(skin_file->filename)) { BBS_SUBDIR[0] = 0x00; return WEB_FILE_NOT_FOUND; } } #ifdef WEB_LOGIN_CHECK return WebLoginCheck(); #endif } return WEB_OK; }
int pam_sm_chauthtok( pam_handle_t *pamh, int flags, int argc, const char **argv) { char *user; int err, result = PAM_AUTH_ERR; char *newpass = NULL, *vnewpass = NULL; char *oldpass = NULL; int i; int debug = 0; uid_t pw_uid; krb5_module_data_t *kmd = NULL; char *pam_service; int promptforold = 0; int promptfornew = 0; pam_repository_t *rep_data = NULL; for (i = 0; i < argc; i++) { if (strcmp(argv[i], "debug") == 0) debug = 1; else syslog(LOG_ERR, dgettext(TEXT_DOMAIN, "PAM-KRB5 (password): illegal option %s"), argv[i]); } if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): start: flags = %x", flags); err = pam_get_item(pamh, PAM_REPOSITORY, (void **)&rep_data); if (rep_data != NULL) { if (strcmp(rep_data->type, KRB5_REPOSITORY_NAME) != 0) { if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (auth): wrong" "repository found (%s), returning " "PAM_IGNORE", rep_data->type); return (PAM_IGNORE); } } if (flags & PAM_PRELIM_CHECK) { /* Nothing to do here */ if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): prelim check"); return (PAM_IGNORE); } /* make sure PAM framework is telling us to update passwords */ if (!(flags & PAM_UPDATE_AUTHTOK)) { syslog(LOG_ERR, dgettext(TEXT_DOMAIN, "PAM-KRB5 (password): bad flags: %d"), flags); return (PAM_SYSTEM_ERR); } if ((err = pam_get_data(pamh, KRB5_DATA, (const void **)&kmd)) != PAM_SUCCESS) { if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): get mod data failed %d", err); kmd = NULL; } if (flags & PAM_CHANGE_EXPIRED_AUTHTOK) { /* let's make sure we know the krb5 pw has expired */ if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): kmd age status %d", kmd ? kmd->age_status : -99); if (!kmd || kmd->age_status != PAM_NEW_AUTHTOK_REQD) return (PAM_IGNORE); } err = pam_get_item(pamh, PAM_SERVICE, (void **)&pam_service); if (err != PAM_SUCCESS) { syslog(LOG_ERR, "PAM-KRB5 (password): error getting SERVICE"); return (PAM_SYSTEM_ERR); } err = pam_get_item(pamh, PAM_USER, (void **)&user); if (err != PAM_SUCCESS) { syslog(LOG_ERR, "PAM-KRB5 (password): error getting USER"); return (PAM_SYSTEM_ERR); } if (user == NULL || user == '\0') { syslog(LOG_ERR, "PAM-KRB5 (password): username is empty"); return (PAM_SYSTEM_ERR); } if (!get_pw_uid(user, &pw_uid)) { syslog(LOG_ERR, "PAM-KRB5 (password): can't get uid for %s", user); return (PAM_AUTHTOK_ERR); } /* * if root key exists in the keytab, it's a random key so no * need to prompt for pw and we just return IGNORE */ if ((strcmp(user, ROOT_UNAME) == 0) && key_in_keytab(user, debug)) { if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): " "key for '%s' in keytab, returning IGNORE", user); result = PAM_IGNORE; goto out; } if ((err = pam_get_item(pamh, PAM_AUTHTOK, (void **) &newpass)) < 0) return (err); if ((err = pam_get_item(pamh, PAM_OLDAUTHTOK, (void **) &oldpass)) < 0) return (err); if (!newpass && !oldpass) { promptforold = 1; promptfornew = 1; } else { /* * OLDAUTHTOK not set, we're probably the first password * module but the AUTHTOK is probably set from an auth mod */ if (newpass && !oldpass) { oldpass = newpass; newpass = NULL; promptfornew = 1; } result = krb5_verifypw(pamh, user, oldpass, DONT_DISP_POLICY, debug); if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): verifypw first %d", result); /* * If this fails and is not bad passwd, then it might * be a non-rpcsec_gss KDC so drop thru. * * (note in S9 change pw should work on non-rpcsec_gss KDCs * such as MIT & MS) */ if (result != 0) promptforold = 1; } if (promptforold) { oldpass = get_passwd(pamh, dgettext(TEXT_DOMAIN, "Old Kerberos password: "******"Need the old password" " to proceed \n")); free(oldpass); return (PAM_AUTHTOK_ERR); } result = krb5_verifypw(pamh, user, oldpass, DISP_POLICY, debug); if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): verifypw prforold %d", result); /* * If it's a bad password, we are done. * Else, continue and try the pwch with oldpass. */ if (result == 2) { display_msg(pamh, PAM_ERROR_MSG, dgettext(TEXT_DOMAIN, "Old Kerberos" " password incorrect\n")); (void) memset(oldpass, 0, strlen(oldpass)); free(oldpass); return (PAM_AUTHTOK_ERR); } } if (promptfornew) { newpass = get_passwd(pamh, dgettext(TEXT_DOMAIN, "New Kerberos password: "******"Need a password to proceed \n")); result = PAM_AUTHTOK_ERR; goto out; } vnewpass = get_passwd(pamh, dgettext(TEXT_DOMAIN, "Re-enter new Kerberos password: "******"Need a password to proceed \n")); result = PAM_AUTHTOK_ERR; goto out; } if (strcmp(newpass, vnewpass)) { display_msg(pamh, PAM_ERROR_MSG, dgettext(TEXT_DOMAIN, "Passwords do not match \n")); result = PAM_AUTHTOK_ERR; goto out; } } result = krb5_changepw(pamh, user, oldpass, newpass, debug); if (result == PAM_SUCCESS) { display_msg(pamh, PAM_TEXT_INFO, dgettext(TEXT_DOMAIN, "Kerberos password " "successfully changed\n")); get_set_creds(pamh, kmd, user, newpass, debug); (void) pam_set_item(pamh, PAM_AUTHTOK, newpass); (void) pam_set_item(pamh, PAM_OLDAUTHTOK, oldpass); } out: if (promptforold && oldpass) { (void) memset(oldpass, 0, strlen(oldpass)); free(oldpass); } if (newpass) { (void) memset(newpass, 0, strlen(newpass)); free(newpass); } if (vnewpass) { (void) memset(vnewpass, 0, strlen(vnewpass)); free(vnewpass); } if (debug) syslog(LOG_DEBUG, "PAM-KRB5 (password): out: returns %d", result); return (result); }
OPENVPN_EXPORT openvpn_plugin_handle_t openvpn_plugin_open_v2 (unsigned int *type_mask, const char *argv[], const char *envp[], struct openvpn_plugin_string_list **return_list) { ldap_context_t *context; const char *daemon_string = NULL; const char *log_redirect = NULL; const char *configfile = NULL; int rc = 0; uint8_t allow_core_files = 0; /* Are we in daemonized mode? If so, are we redirecting the logs? */ daemon_string = get_env ("daemon", envp); use_syslog = 0; if( daemon_string && daemon_string[0] == '1'){ log_redirect = get_env ("daemon_log_redirect", envp); if( !(log_redirect && log_redirect[0] == '1')) use_syslog = 1; } /* * Allocate our context */ context = ldap_context_new( ); if( !context ){ LOGERROR( "Failed to initialize ldap_context, no memory available?" ); goto error; } /* * Intercept the --auth-user-pass-verify callback. */ *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY); while ( ( rc = getopt ( string_array_len (argv), (char **)argv, ":H:D:c:t:WZC" ) ) != - 1 ){ switch( rc ) { case 'H': context->config->ldap->uri = strdup(optarg); break; case 'Z': context->config->ldap->ssl = strdup("start_tls"); break; case 'D': context->config->ldap->binddn = strdup(optarg); break; case 'W': context->config->ldap->bindpw = get_passwd("BindPW Password: "******"Password is %s: length: %d\n", config->bindpw, strlen(config->bindpw) ); break; case 'c': configfile = optarg; break; case 't': context->config->ldap->timeout = atoi( optarg ); break; case 'C': LOGDEBUG("Core file generation requested"); allow_core_files = 1; break; case '?': LOGERROR("Unknown Option -%c !!", optopt ); break; case ':': LOGERROR ("Missing argument for option -%c !!", optopt ); break; default: LOGERROR ("?? getopt returned character code 0%o ??", rc); abort(); } } #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE) if (allow_core_files){ LOGDEBUG ("Setting core file"); unlimit_core_size(); } #endif /** * Parse configuration file is -c filename is provided * If not provided, use a default config file OCONFIG * This file must exists even though it might be empty */ if( configfile == NULL) { configfile = OCONFIG; } if( config_parse_file( configfile, context->config ) ){ goto error; } /** * Set default config values */ config_set_default( context->config ); /* when ldap userconf is define, we need to hook onto those callbacks */ if( config_is_pf_enabled( context->config )){ *type_mask |= OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ENABLE_PF); } #ifdef ENABLE_LDAPUSERCONF *type_mask |= OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT); #else if( config_is_redirect_gw_enabled( context->config ) ){ *type_mask |= OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2); } #endif /* * Get verbosity level from environment */ const char *verb_string = get_env ("verb", envp); if (verb_string) context->verb = atoi (verb_string); if( DODEBUG( context->verb ) ) config_dump( context->config ); /* set up mutex/cond */ pthread_mutex_init (&action_mutex, NULL); pthread_cond_init (&action_cond, NULL); /* start our authentication thread */ pthread_attr_setdetachstate(&action_thread_attr, PTHREAD_CREATE_JOINABLE); rc = pthread_create(&action_thread, &action_thread_attr, action_thread_main_loop, context); switch( rc ){ case EAGAIN: LOGERROR( "pthread_create returned EAGAIN: lacking resources" ); break; case EINVAL: LOGERROR( "pthread_create returned EINVAL: invalid attributes" ); break; case EPERM: LOGERROR( "pthread_create returned EPERM: no permission to create thread" ); break; case 0: break; default: LOGERROR( "pthread_create returned an unhandled value: %d", rc ); } if( rc == 0) return (openvpn_plugin_handle_t) context; /* Failed to initialize, free resources */ pthread_attr_destroy( &action_thread_attr ); pthread_mutex_destroy( &action_mutex ); pthread_cond_destroy( &action_cond ); error: if ( context ){ ldap_context_free (context); } return NULL; }
/* * Main program for daemon. */ int main (int argc, char **argv) { int opt; int result = -1; struct stat st; /* check options.chroot_directory */ FILE *fd; /* Check *.pem files */ char *command = NULL; char *cat = NULL; char *server = NULL; char buf[SIZE]; char **c = NULL; int i = 0; char **arg = NULL; /* Use when creuvux is run with option from command line */ int arg_inc = 0; int mode_script = -1; /* if mode_script = 1, script mode is enable */ char *zErrMsg = 0; int rc = -1; /* Ensure that standart files descriptor 0, 1 and 2 are open or directed to /dev/null */ crv_sanitise_stdfd(); /* Initialize configuration options to their default values. */ initialize_client_options(&options); while ((opt = getopt(argc, argv, "f:c:hv")) != -1) { switch(opt) { case 'h': /* Print Help */ fprintf(stdout, "%s\n", "Help:"); usage (NULL); exit(EXIT_SUCCESS); case 'v': /* Print version */ fprintf (stderr, "%s%s\n", "creuvux version ", CREUVUX_VERSION); fprintf (stderr, "%s\n", "Before reporting bugs ([email protected]) please check " "the development CHANGELOG to make sure it hasn't already " "been fixed in devel."); exit(1); case 'f': /* Config File */ crv_free(options.config); options.config = crv_strdup(optarg); break; case 'c': /* Get command */ mode_script = 1; if (NULL == (c = malloc (SIZE * sizeof *c))) exit(EXIT_FAILURE); for (i = 2; argv[i]; i++) c[i-2] = crv_strdup(argv[i]); for (i = 0; c[i]; i++) printf("-> %s\n", c[i]); break; case '?': default: usage(NULL); exit(EXIT_FAILURE); } } argc -= optind; argv += optind; /* Read configuration file and set options */ result = read_client_conf (options.config); if (result == -1) return (-1); /* Check if passphrase isn't NULL */ if (options.passphrase == NULL) { fprintf(stdout, "%s", "Enter your passphrase:"); fflush(stdin); get_passwd (); fprintf(stdout, "%s", "\n"); } /* if (optind < argc) { fprintf( stderr, "%s%s\n", "Extra argument ", argv[optind]); exit(1); } */ /* * Check Configuration */ /* Check upload_directory */ if ((stat(options.download_directory, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Missing download directory: %s\n", options.download_directory); exit(1); } /* Check config directory */ if ((stat(options.path, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Option CREUVUX_PATH is missing: %s\n", options.path); exit(1); } result = crv_chdir(options.path); if (result == -1) { fprintf( stderr, "%s%s%s\n", "main(): crv_chdir(", options.path,") failed"); exit(1); } /* Check existence of tmp directory */ if ((stat( "./tmp", &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Directory %stmp/ is missing\n", options.tmp_directory); exit(1); } /* Check server.pem */ fd = crv_fopen("client.pem", "r"); if (fd == NULL) { fprintf( stderr, "%s\n", "Missing server.pem."); return (-1); } fclose(fd); /* Check rootcert.pem */ fd = crv_fopen("rootcert.pem", "r"); if (fd == NULL) { fprintf( stderr, "%s\n", "Missing rootcert.pem"); return (-1); } fclose(fd); /* ignore SIGPIPE */ signal (SIGPIPE, SIG_IGN); options.gui = 0; welcom(); if (options.debug == 1) { fprintf(stderr, "%s\n", "#################"); fprintf(stderr, "%s\n", "# MODE DEBUG ON #"); fprintf(stderr, "%s\n", "#################"); fprintf(stderr, "# | \n"); fprintf(stderr, "# |-> CREUVUX_PATH :'%s'\n", options.path); fprintf(stderr, "# |-> CREUVUX_SEC :'%d'\n", options.sec); fprintf(stderr, "# |-> CREUVUX_PWD :'%s'\n", options.passphrase); fprintf(stderr, "# |-> CREUVUX_DATA :'%s'\n", options.download_directory); fprintf(stderr, "# |-> LISTING_DIR :'%s'\n", options.listing_directory); fprintf(stderr, "# |-> TMP_DIR :'%s'\n", options.tmp_directory); if ( options.address_family == AF_INET) fprintf(stderr, "%s", "# |-> CREUVUX_ADDR :'IPv4'\n"); else if ( options.address_family == AF_INET6) fprintf(stderr, "%s", "# |-> CREUVUX_ADDR :'IPv6'\n"); if (options.compression == 1) fprintf(stderr, "%s", "# |-> CREUVUX_COMPRESSION :'Yes'\n"); else if (options.compression == -1) fprintf(stderr, "%s", "# |-> CREUVUX_COMPRESSION :'No'\n"); fprintf(stderr, "%s\n\n", "#################"); } /* * Deux fonctions: * -> Envoie de fichiers * -> Téléchargement de fichiers */ // Download /* fprintf(stdout, "File: %s\n", c[i]); char *sha1 = NULL; sha1 = crv_sha1(c[i]); printf("Sha1 (%s) = %s\n", c[i], sha1); upload(c[i]); //Get("/home/creuvard/file.crv"); */ server = give_server(); if (server == NULL) { fprintf(stderr, "%s\n", "You must choose server id"); return; } cat = choice_cat(); if (cat == NULL) { fprintf(stderr, "%s", "Creuvux fail to fetch categories list"); return (-1); } fprintf(stdout, "Catégorie: %s\n", cat); for (i = 0; c[i]; i++) { printf("-> %s\n", c[i]); upload(c[i], cat, server); printf("DEBUG avant fin loop\n"); } printf("DEBUG (avant fin main function\n"); // Send //upload(c[i]); Free_options(); return (0); }
int main(int argc, char **argv) { struct sockaddr_in config, peer; struct epoll_event ev, events[EP_SIZE]; struct conn_status status[MAX_FD], *curr; in_port_t port = L_PORT; int listenfd, epfd, connfd; int i, flag, nfds, current_fd; socklen_t len; char buffer[FILE_BUFFER]; // init sockinit(&config); sockset(&config, port, NULL); memset(status, 0, sizeof(status)); memset(buffer, 0, sizeof(buffer)); signal(SIGPIPE, SIG_IGN); // create server listenfd = create_server(&config); if (listenfd < 0) { perror("xtrans: server create failed."); exit(EXIT_FAILURE); } // create epoll fd epfd = ep_ini(); if (epfd < 0) { perror("xtrans: epoll init failed."); exit(EXIT_FAILURE); } // add listen fd to epoll ev.events = EPOLLIN; ev.data.fd = listenfd; if (ep_add(epfd, listenfd, &ev) == -1) { perror("xtrans: add epoll event failed."); exit(EXIT_FAILURE); } // main loop for(;;) { nfds = ep_col(epfd, events); for (i = 0; i < nfds; i++) { current_fd = events[i].data.fd; if (current_fd == listenfd) { connfd = accept(listenfd, (SA *)&peer, &len); if (connfd == -1) { continue; } memcpy(&(status[connfd].client), &peer, sizeof(struct sockaddr_in)); ev.events = EPOLLIN; ev.data.fd = connfd; if (ep_add(epfd, connfd, &ev) == -1) { continue; } flag = welcome(connfd, &(status[connfd])); if (flag >= 0) { x_log(LOG_CONN, &(status[connfd])); } else { x_log(LOG_DISC, &(status[connfd])); terminate(epfd, connfd, &(status[connfd])); } } else if (events[i].events & EPOLLIN) { curr = &(status[current_fd]); switch (curr->status) { case STATUS_INIT: memset(&(curr->username), 0, sizeof(char)*12); flag = readln(current_fd, curr->username, 1); if (flag < 0) { terminate(epfd, current_fd, curr); x_log(LOG_DISC, curr); } flag = get_username(current_fd, curr); if (flag < 0) { terminate(epfd, current_fd, curr); x_log(LOG_DISC, curr); } break; case STATUS_NAME: memset(&(curr->passwd), 0, sizeof(char)*32); flag = readln(current_fd, curr->passwd, 1); if (flag < 0) { terminate(epfd, current_fd, curr); x_log(LOG_DISC, curr); } flag = get_passwd(current_fd, curr); if (flag < 0) { terminate(epfd, current_fd, curr); x_log(LOG_DISC, curr); } flag = auth(curr->username, curr->passwd); if (flag < 0) { flag = auth_failed(current_fd, curr); terminate(epfd, current_fd, curr); x_log(LOG_REFS, curr); } else { flag = auth_success(current_fd, curr); if (flag < 0) { x_log(LOG_DISC, curr); } else { x_log(LOG_LOGI, curr); } } break; case STATUS_SUCC: flag = readFd(current_fd, buffer, 1024); if (flag < 0) { terminate(epfd, current_fd, curr); x_log(LOG_DISC, curr); } curr->recvb = flag; terminate(epfd, current_fd, curr); x_log(LOG_FINS, curr); break; default: perror("xtrans: status not define, default action triggered."); terminate(epfd, current_fd, curr); } } } } return 0; }
int change_passwd(struct passwd * pw) { struct spwd *sp = NULL; struct spwd spw; char pwbuf[PWLEN]; int opt, ret; printf("changing password for %s\n", pw->pw_name); if (pw->pw_passwd && *pw->pw_passwd) sp=getspnam(pw->pw_name); ret = 0; if (getuid() != 0) { if ((ret = chk_passwd(pw, sp)) == -1) { fputs("Sorry!\n",stderr); return EXIT_FAILURE; } } if (get_passwd(pwbuf, ret) == -1) return EXIT_FAILURE; if (!lock_passwd()) { fprintf(stderr,"unable to lock password database (%s)\n",strerror(errno)); return PasswdBusy; } /*- * there are 4 normal cases covered here: * 1: user did not previously have a password and now does. * 2: user did not previously have a password and still doesn't. * 3: user previously had a password and now doesn't. * 4: user previously had a password and still does. * * plus the additional user should have had a password but * there was none in /etc/shadow! * * #1 -- update password & shadow files. * #2 -- do nothing. * #3 -- update password & shadow files. * #4 -- update shadow only. * in #1, the shadow file must be updated first for consistency. * in #3, the password file must be updated first for consistency. */ opt = Success; if (*pwbuf) { /* user put a password in */ if (!sp) { spw.sp_namp = pw->pw_name; spw.sp_pwdp = pwbuf; spw.sp_lstchg = time(0); spw.sp_max = 0; spw.sp_min = 0; spw.sp_warn = 0; spw.sp_inact = 0; spw.sp_expire = 0; spw.sp_flag = 0; sp = &spw; } else { sp->sp_pwdp = pwbuf; sp->sp_lstchg = time(0); } if (!(pw->pw_passwd && *pw->pw_passwd)) { if ((opt=addshent(&spw)) != Success) { unlock_passwd(); return opt; } pw->pw_passwd = passwd_stub; opt = chgpw_name(pw->pw_name,pw); } else { sp->sp_pwdp = pwbuf; opt = addshent(sp); } } else if (pw->pw_passwd && *pw->pw_passwd) { if ((opt=delsh_name(pw->pw_name)) != Success) { fputs("Warning: password,shadow files may be inconsistant\n",stderr); // unlock_passwd(); // return opt; } pw->pw_passwd = nil_passwd; opt=chgpw_name(pw->pw_name,pw); } unlock_passwd(); return opt; }
static void restore_fileheader(FILEHEADER *fhr, const char *direct, const char *fname) { time_t t; struct tm *tmp; char dirpath[PATHLEN], buf[512], *p, *sp, *sp2; USEREC urc; memset(fhr, 0, sizeof(FILEHEADER)); if (!fhr || !fname) return; strcpy(fhr->filename, fname); t = strtol(fname + 2, NULL, 10); tmp = localtime(&t); if (tmp) sprintf(fhr->date, "%02d/%02d/%02d", tmp->tm_year - 11, tmp->tm_mon + 1, tmp->tm_mday); else strcpy(fhr->date, "00/00/00"); setdotfile(dirpath, direct, fname); get_record(dirpath, buf, sizeof(buf), 1); p = strtok_r(buf, " ", &sp); p = strtok_r(NULL, " ", &sp); if (p) { strcpy(fhr->owner, p); if (!strchr(fhr->owner, '.')) { if (get_passwd(&urc, fhr->owner) > 0) fhr->ident = urc.ident; } else { p = strtok_r(fhr->owner, "@.", &sp2); sprintf(buf, "#%s", p); strcpy(fhr->owner, buf); } } else { strcpy(fhr->owner, "UNKNOWN"); } if (sp && (((p = strstr (sp, "標題:")) && (p = p + 5)) || ((p = strstr (sp, "標題:")) && (p = p + 6)) || ((p = strstr (sp, "標 題:")) && (p = p + 7)) || ((p = strstr (sp, "Title:")) && (p = p + 6)) || ((p = strstr (sp, "Subject:")) && (p = p + 8)))) { while (*p == ' ') p++; if (*p != '\n') { strtok (p, "\n"); strcpy (fhr->title, p); } } else { strcpy(fhr->title, "UNKNOWN"); } if (get_only_postno(direct, 0, fhr) == -1) { bbslog("ERROR", "Getting only postno. (%s)", direct); fprintf(stderr, "ERROR: Getting only postno. (%s)", direct); exit(1); } /* * Mark readed for bbspop3d */ if (strstr(direct, "mail")) fhr->accessed |= FILE_READ; }
/* * user can modify his list for grouply mail sending */ static int set_group() { char strName[STRLEN]; int num_send = 0; clear(); prints(_msg_max_group, MAX_MAILGROUPS); for (;;) { /* show the list for grouply mail sending */ show_array(mgatop); getdata(1, 0, _msg_ask_group_add, genbuf, 2, ECHONOSP | LOWCASE, NULL); switch (genbuf[0]) { case 'a': if (num_send >= MAX_MAILGROUPS) { prints(_msg_mail_group_max_prompt, MAX_MAILGROUPS); getkey(); } else { if (getdata(2, 0, _msg_receiver, strName, sizeof(strName), ECHONOSP, NULL)) { #if EMAIL_LIMIT if (curuser.ident != 7 && strchr(strName, '@')) { prints("\n%s", _msg_sorry_email); clrtoeol(); getkey(); } else #endif if (strchr(strName, '@') || get_passwd(NULL, strName) > 0) { if (!cmp_array(mgatop, strName, strcmp)) { add_array(mgatop, strName, malloc_str); num_send++; } } } } break; case 'f': { int i; load_friend(&friend_cache, curuser.userid); for (i = 0; i < friend_cache->number; i++) { if (!friend_cache->datap[i]) continue; if (num_send >= MAX_MAILGROUPS) { prints(_msg_mail_group_max_prompt, MAX_MAILGROUPS); getkey(); break; } if (!cmp_array(mgatop, friend_cache->datap[i], strcmp)) { add_array(mgatop, friend_cache->datap[i], malloc_str); num_send++; } } } break; case 'd': if (getdata(2, 0, _msg_delete, genbuf, IDLEN, ECHONOSP, NULL)) { mgatop = cmpd_array(mgatop, genbuf, strcmp); num_send--; } break; case 'q': return -1; case 'e': default: if (num_send == 0) return -1; clrtobot(); return 0; } } }
void main(int argc, char *argv[]) { char aha[] = "0abcdefghijklmnopqrstuvwxyz"; DIR *dirp; struct dirent *de; char path[PATHLEN]; USEREC user; char id[IDLEN + 2]; int uid; FILE *rptfile; int fd; int total_user=0, total_missed=0, total_mismatch=0; time_t curtime; int i; if (argc != 2) { printf("usage: %s all | userid\n", argv[0]); printf(" * all 列出所有使用者\n"); printf(" * userid 列出單一使用者\n"); return; } init_bbsenv(); if (strcmp(argv[1], "all")) { uid=get_passwd(NULL, argv[1]); if (uid>0) { printf("%s: requested user '%s', the uid is %d.\n", argv[0], argv[1], uid); } else { printf("%s: requested user '%s' doesn't exist.\n", argv[0], argv[1]); } return; } rptfile=fopen("entire_uid_list", "w"); //sprintf(upath, "%s.new", USERIDX); //sprintf(ppath, "%s.new", PASSFILE); fprintf(rptfile, "Date: %s", ctime(&curtime)); fprintf(rptfile, "----------------------------------\n"); for (i = 0; i < 27; i++) { sprintf(path, "home/%c", aha[i]); if (!(dirp = opendir(path))) continue; readdir(dirp); /* skip . & .. */ readdir(dirp); while ((de = readdir(dirp)) != NULL) { if (de->d_name[0] == '\0') continue; memset(id, '\0', sizeof(id)); strncpy(id, de->d_name, sizeof(id) - 1); sprintf(path, "home/%c/%s/passwds", aha[i], id); if ((fd = open(path, O_RDONLY)) < 0) { fprintf(rptfile, "Error:[%s] passwd file missed.\n", id); total_missed++; } else { if (read(fd, &user, sizeof(user)) != sizeof(user)) { fprintf(rptfile, "Error:[%s] passwd file size mismatch.\n", id); total_mismatch++; } else { total_user++; fprintf(rptfile, "%10d %s\n", user.uid, user.userid); } close(fd); } } closedir(dirp); } fprintf(rptfile, "\n########## ENTIRE USERS ##########\n"); fprintf(rptfile, "# total users:%d\n", total_user); fprintf(rptfile, "# passwd missed: %d\n", total_missed); fprintf(rptfile, "# passwd size mismatch: %d\n", total_mismatch); fclose(rptfile); /* ----------------------------------- */ return; }
/** * \fn int main (int argc, char **argv) * \brief Fonction principale. * * \param argv Argument passés en ligne de commande * \return -1 en cas d'erreur, et 0 si tout va bien. */ int main (int argc, char **argv) { /* extern char *optarg; */ /* extern int optind; */ int opt; /* update flag: * '0' -> Don't Create/Update database, * '1' -> Create/Update database */ int update = 0; int result = -1; /* check options.chroot_directory */ struct stat st; /* Check *.pem files */ FILE *fd; char path[SIZE]; /* Ensure that standart files descriptor 0, 1 and 2 are open or directed to /dev/null */ crv_sanitise_stdfd(); /* Initialize configuration options to their default values. */ initialize_server_options(&options); while ((opt = getopt(argc, argv, "f:hvsuga")) != -1) { switch(opt) { case 'h': /* Print Help */ fprintf(stdout, "%s\n", "Help:"); usage (NULL); exit(1); case 'v': /* Print version */ fprintf (stderr, "%s%s\n", "creuvuxd version ", CREUVUX_VERSION); fprintf (stderr, "%s\n", "Before reporting bugs ([email protected]) please check " "the development CHANGELOG to make sure it hasn't already " "been fixed in devel."); exit(1);; case 'f': /* Config File */ crv_free(options.config); options.config = crv_strdup(optarg); break; case 'u': /* create Database */ update = 1; break; case '?': default: usage(NULL); exit(1); } } argc -= optind; argv += optind; /* Read configuration file and set options */ result = read_server_conf (options.config); if (result == -1) { Free_options(); return (-1); } /* Check if passphrase isn't NULL */ if (options.passphrase == NULL) { fprintf(stdout, "%s", "Enter your passphrase:"); fflush(stdin); get_passwd (); fprintf(stdout, "%s", "\n"); } /* Change user id for options checking */ result = crv_drop_priv_temp (options.user); if (result == -1) { fprintf(stderr, "%s", "Change User ID failed\n"); Free_options(); return (-1); } /* Check if files creuvux.log, creuvux.stat and listing.xml exist */ result = check_env(options.chroot_directory); if (result == -1) { fprintf( stderr, "%s%s%s\n", "main(): check_env(", options.chroot_directory, ") failed"); Free_options(); return (-1); } if (optind < argc) { fprintf( stderr, "%s%s\n", "Extra argument ", argv[optind]); Free_options(); exit(EXIT_FAILURE); } /* * Check Configuration */ /* Chech User */ if (getpwnam(options.user) == NULL) { fprintf(stderr, "Privilege separation user %s does not exist", options.user); Free_options(); exit(1); } /* Check chroot_directory */ if ((stat(options.chroot_directory, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Missing privilege separation directoty: %s\n", options.chroot_directory); Free_options(); exit(1); } /* Check upload_directory */ (void)crv_strncpy(path, options.chroot_directory, sizeof(path)); (void)crv_strncat(path, options.upload_directory, sizeof(path)); if ((stat(path, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Missing upload directory (in chroot jail ->'%s'): %s\n", options.chroot_directory, options.upload_directory); Free_options(); exit(1); } memset(path, 0, sizeof(path)); /* Check public_directory */ (void)crv_strncpy(path, options.chroot_directory, sizeof(path)); (void)crv_strncat(path, options.public_directory, sizeof(path)); if ((stat(path, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Missing public directory (in chroot jail): %s\n", options.public_directory); Free_options(); exit(1); } memset(path, 0, sizeof(path)); /* Check config directory */ if ((stat(options.path, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Option CREUVUX_PATH is missing: %s\n", options.path); Free_options(); exit(1); } /* Change directory to options.path (default: /etc/creuvuxd/ ) */ result = crv_chdir(options.path); if (result == -1) { fprintf( stderr, "%s%s%s\n", "main(): crv_chdir(", options.path,") failed"); Free_options(); exit(1); } /* Check server.pem */ fd = crv_fopen("server.pem", "r"); if (fd == NULL) { fprintf( stderr, "%s\n", "Missing server.pem."); Free_options(); return (-1); } fclose(fd); /* Check rootcert.pem */ fd = crv_fopen("rootcert.pem", "r"); if (fd == NULL) { fprintf( stderr, "%s\n", "Missing rootcert.pem"); Free_options(); return (-1); } fclose(fd); /* Check group.conf */ fd = crv_fopen("group.conf", "r"); if (fd == NULL) { fprintf( stderr, "%s\n", "Missing group"); Free_options(); return (-1); } fclose(fd); /* Create database */ if (update == 1) { sqlite3 *db = NULL; char *zErrMsg = 0; int rc = -1; /* Restore privilege */ result = crv_restore_priv(); if (result == -1) { fprintf(stderr, "%s", "Creuvuxd can't restore privilege\n"); Free_options(); return (-1); } /* Drop privilege */ /* Chroot process */ /* A décommenter */ result = crv_drop_priv_perm_and_chroot (options.user , options.chroot_directory ); if (result == -1) { fprintf( stderr, "%s%s%s%s%s", "\nmain(): drop_priv_perm_and_chroot(", options.user, ",", options.chroot_directory, ") failed\n"); fprintf( stderr, "%s", "main(): Please check you are ROOT\n"); Free_options(); return (-1); } fprintf(stdout, "%s", "Sqlite DB creation "); fflush(stdout); rc = sqlite3_open( ".creuvux.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s", sqlite3_errmsg(db)); sqlite3_close(db); Free_options(); return (-1); } fprintf(stdout, "%s\n", " [Ok] "); fprintf(stdout, "%s\n", "Listing direcory and update database..."); /* * Multiple TABLE CREATION (Fichiers, Categories, Descr, Grp_User, Grp_Sha1, Descr) */ /* * TABLE Files */ rc = sqlite3_exec(db, "create table Files (Sha1 TEXT NOT NULL, Name TEXT NOT NULL, Size NUMERIC NOT NULL, Path TEXT NOT NULL);" , NULL, 0, &zErrMsg); if( rc!=SQLITE_OK ){ fprintf(stderr, "SQL (Table=Files) error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } list_directory_and_create_db(options.chroot_directory, db); //list_directory_and_create_db( "/", db); sqlite3_close(db); Free_options(); return (0); } /* ignore SIGPIPE */ signal (SIGPIPE, SIG_IGN); signal(SIGCHLD, crv_sigchld_handler); /* Restore privilege */ result = crv_restore_priv(); if (result == -1) { fprintf(stderr, "%s", "Creuvuxd can't restore privilege\n"); Free_options(); return (-1); } if (options.debug == 1) { fprintf(stderr, "%s\n", "#################"); fprintf(stderr, "%s\n", "# MODE DEBUG ON #"); fprintf(stderr, "%s\n", "#################"); fprintf(stderr, "# \t| \n"); fprintf(stderr, "# \t|-> CREUVUX_USER :'******'\n", options.user); fprintf(stderr, "# \t|-> CREUVUX_PATH :'%s'\n", options.path); fprintf(stderr, "# \t|-> CREUVUX_DEBIT :'%d'\n", options.bandwidth); fprintf(stderr, "# \t|-> CREUVUX_PORT :'%d'\n", options.num_ports); fprintf(stderr, "# \t|-> CREUVUX_ADDR :'%s'\n", options.listen_addrs); fprintf(stderr, "# \t|-> CREUVUX_HOST :'%s'\n", options.host); fprintf(stderr, "# \t|-> CREUVUX_PID :'%s'\n", options.pid); fprintf(stderr, "# \t|-> CREUVUX_SEC :'%d'\n", options.sec); fprintf(stderr, "# \t|-> CREUVUX_PWD :'%s'\n", options.passphrase); fprintf(stderr, "# \t|-> CREUVUX_CHROOT :'%s'\n", options.chroot_directory); fprintf(stderr, "# \t|-> CREUVUX_UPDIR :'%s'\n", options.upload_directory); fprintf(stderr, "# \t|-> CREUVUX_PUBLIC :'%s'\n", options.public_directory); fprintf(stderr, "# \t|-> CREUVUX_IPDB :'%s'\n", options.ipdb); fprintf(stderr, "# \t|-> CREUVUX_PORTDB :'%d'\n", options.portdb); fprintf(stderr, "# \t|-> CREUVUX_DBNAME :'%s'\n", options.dbname); fprintf(stderr, "# \t|-> CREUVUX_DBUSER :'******'\n", options.dbuser); fprintf(stderr, "# \t|-> CREUVUX_DBPASSW :'%s'\n", options.dbpassw); fprintf(stderr, "# \t|-> CREUVUX_MAX_SIZE:'%lld'\n", options.db_max); fprintf(stderr, "# \t`-> CREUVUX_MIN_SIZE:'%lld'\n", options.db_min); fprintf(stderr, "%s\n\n", "#################"); } else if (options.debug == -1) { int fd_pid; char str[12]; /* Put pid_file */ if (options.pid == NULL) { fprintf(stderr, "%s", "creuvuxd failed, CREUVUXD_PID is NULL\n"); Free_options(); exit(EXIT_FAILURE); } fd_pid = open( options.pid, O_RDWR | O_CREAT, 0640); if (fd_pid < 0) { fprintf(stderr, "creuvuxd can't open PID file\n"); Free_options(); exit(EXIT_FAILURE); } if (lockf (fd_pid, F_TLOCK, (off_t) 0) < 0) { fprintf(stderr, "%s", "creuvuxd is already running\n"); Free_options(); exit(EXIT_FAILURE); } fprintf(stdout, "%s\n", "Mode Daemon"); crv_daemon_mode(); snprintf (str, 12, "%d\n", getpid()); (void)write (fd_pid, str, strlen(str)); } server_accept_loop ( ); Free_options(); fprintf(stderr, "%s", "Creuvuxd Received terminating signal\n"); return 0; }
/* * Parse a set of parameters for an interface. * returns NULL or error message */ const char * parse_parms(char *line, boolean_t safe) /* 1=from secure file */ { #define PARS(str) (strcasecmp(tgt, str) == 0) #define PARSEQ(str) (strncasecmp(tgt, str"=", sizeof (str)) == 0) /* * This macro checks for conflicting configurations options * For eg one can set either the IS_NO_SOL_OUT flag bit or the IS_SOL_OUT flag * bit, but not both. */ #define CKF(g, b) {if (0 != (parm.parm_int_state & ((g) & ~(b)))) break; \ parm.parm_int_state |= (b); } struct parm parm; struct intnet *intnetp; struct r1net *r1netp; struct tgate *tg; uint32_t addr, mask; char delim, *val0 = 0, *tgt, *val, *p; const char *msg; char buf[PARMS_MAXLINELEN], buf2[PARMS_MAXLINELEN]; int i; /* "subnet=x.y.z.u/mask[,metric]" must be alone on the line */ if (strncasecmp(line, "subnet=", sizeof ("subnet=") - 1) == 0 && *(val = &line[sizeof ("subnet=") -1 ]) != '\0') { if (0 > parse_quote(&val, ",", &delim, buf, sizeof (buf))) return (bad_str(line)); intnetp = rtmalloc(sizeof (*intnetp), "parse_parms subnet"); intnetp->intnet_metric = 1; if (delim == ',') { intnetp->intnet_metric = (int)strtol(val+1, &p, 0); if (*p != '\0' || intnetp->intnet_metric <= 0 || val+1 == p || intnetp->intnet_metric >= HOPCNT_INFINITY) { free(intnetp); return (bad_str(line)); } } if (!getnet(buf, &intnetp->intnet_addr, &intnetp->intnet_mask) || intnetp->intnet_mask == HOST_MASK || intnetp->intnet_addr == RIP_DEFAULT) { free(intnetp); return (bad_str(line)); } intnetp->intnet_addr = htonl(intnetp->intnet_addr); intnetp->intnet_next = intnets; intnets = intnetp; return (NULL); } /* * "ripv1_mask=x.y.z.u/mask1,mask2" must be alone on the line. * This requires that x.y.z.u/mask1 be considered a subnet of * x.y.z.u/mask2, as if x.y.z.u/mask2 were a class-full network. */ if (!strncasecmp(line, "ripv1_mask=", sizeof ("ripv1_mask=") - 1) && *(val = &line[sizeof ("ripv1_mask=")-1]) != '\0') { if (0 > parse_quote(&val, ",", &delim, buf, sizeof (buf)) || delim == '\0') return (bad_str(line)); if ((i = (int)strtol(val+1, &p, 0)) <= 0 || i > 32 || *p != '\0') return (bad_str(line)); r1netp = rtmalloc(sizeof (*r1netp), "parse_parms ripv1_mask"); r1netp->r1net_mask = HOST_MASK << (32-i); if (!getnet(buf, &r1netp->r1net_net, &r1netp->r1net_match) || r1netp->r1net_net == RIP_DEFAULT || r1netp->r1net_mask > r1netp->r1net_match) { free(r1netp); return (bad_str(line)); } r1netp->r1net_next = r1nets; r1nets = r1netp; return (NULL); } (void) memset(&parm, 0, sizeof (parm)); /* * Support of the following for Solaris backward compatibility * norip <ifname> * noripin <ifname> * noripout <ifname> */ if (strncasecmp("norip", line, 5) == 0) { char cmd[64], ifname[64]; int n; n = sscanf(line, "%63s %63s\n", cmd, ifname); if (n != 2) { /* Not enough parameters */ return (bad_str(line)); } /* * Get the interface name and turn on the appropriate * interface flags */ (void) strlcpy(parm.parm_name, ifname, sizeof (parm.parm_name)); if (strcasecmp("norip", cmd) == 0) { parm.parm_int_state |= IS_NO_RIP; } else if (strcasecmp("noripin", cmd) == 0) { parm.parm_int_state |= IS_NO_RIP_IN; } else if (strcasecmp("noripout", cmd) == 0) { parm.parm_int_state |= IS_NO_RIP_OUT; } else { /* Bad command */ return (bad_str(line)); } /* * Look for duplication, and if new, * link to the rest of the parm entries. */ return (insert_parm(&parm)); } for (;;) { tgt = line + strspn(line, " ,\n\r"); if (*tgt == '\0' || *tgt == '#') break; line = tgt+strcspn(tgt, "= #,\n\r"); delim = *line; if (delim == '=') { val0 = ++line; if (0 > parse_quote(&line, " #,", &delim, buf, sizeof (buf))) return (bad_str(tgt)); } if (delim != '\0') { for (;;) { *line = '\0'; if (delim == '#') break; ++line; if (!isspace(delim) || ((delim = *line), !isspace(delim))) break; } } if (PARSEQ("if")) { if (parm.parm_name[0] != '\0' || strlen(buf) > IF_NAME_LEN) return (bad_str(tgt)); (void) strlcpy(parm.parm_name, buf, sizeof (parm.parm_name)); } else if (PARSEQ("addr")) { /* * This is a bad idea, because the address based * sets of parameters cannot be checked for * consistency with the interface name parameters. * The parm_net stuff is needed to allow several * -F settings. */ if (!getnet(val0, &addr, &mask) || parm.parm_name[0] != '\0') return (bad_str(tgt)); parm.parm_net = addr; parm.parm_mask = mask; parm.parm_name[0] = '\n'; } else if (PARSEQ("passwd")) { /* * since cleartext passwords are so weak allow * them anywhere */ msg = get_passwd(tgt, val0, &parm, RIP_AUTH_PW, 1); if (msg) { *val0 = '\0'; return (bad_str(msg)); } } else if (PARSEQ("md5_passwd")) { msg = get_passwd(tgt, val0, &parm, RIP_AUTH_MD5, safe); if (msg) { *val0 = '\0'; return (bad_str(msg)); } } else if (PARS("no_ag")) { parm.parm_int_state |= (IS_NO_AG | IS_NO_SUPER_AG); } else if (PARS("no_host")) { parm.parm_int_state |= IS_NO_HOST; } else if (PARS("no_super_ag")) { parm.parm_int_state |= IS_NO_SUPER_AG; } else if (PARS("no_ripv1_in")) { parm.parm_int_state |= IS_NO_RIPV1_IN; } else if (PARS("no_ripv2_in")) { parm.parm_int_state |= IS_NO_RIPV2_IN; } else if (PARS("ripv2_out")) { if (parm.parm_int_state & IS_NO_RIPV2_OUT) return (bad_str(tgt)); parm.parm_int_state |= IS_NO_RIPV1_OUT; } else if (PARS("ripv2")) { if ((parm.parm_int_state & IS_NO_RIPV2_OUT) || (parm.parm_int_state & IS_NO_RIPV2_IN)) return (bad_str(tgt)); parm.parm_int_state |= (IS_NO_RIPV1_IN | IS_NO_RIPV1_OUT); } else if (PARS("no_rip")) { CKF(IS_PM_RDISC, IS_NO_RIP); } else if (PARS("no_rip_mcast")) { parm.parm_int_state |= IS_NO_RIP_MCAST; } else if (PARS("no_rdisc")) { CKF((GROUP_IS_SOL_OUT|GROUP_IS_ADV_OUT), IS_NO_RDISC); } else if (PARS("no_solicit")) { CKF(GROUP_IS_SOL_OUT, IS_NO_SOL_OUT); } else if (PARS("send_solicit")) { CKF(GROUP_IS_SOL_OUT, IS_SOL_OUT); } else if (PARS("no_rdisc_adv")) { CKF(GROUP_IS_ADV_OUT, IS_NO_ADV_OUT); } else if (PARS("rdisc_adv")) { CKF(GROUP_IS_ADV_OUT, IS_ADV_OUT); } else if (PARS("bcast_rdisc")) { parm.parm_int_state |= IS_BCAST_RDISC; } else if (PARS("passive")) { CKF((GROUP_IS_SOL_OUT|GROUP_IS_ADV_OUT), IS_NO_RDISC); parm.parm_int_state |= IS_NO_RIP | IS_PASSIVE; } else if (PARSEQ("rdisc_pref")) { if (parm.parm_rdisc_pref != 0 || (parm.parm_rdisc_pref = (int)strtol(buf, &p, 0), *p != '\0') || (buf == p)) return (bad_str(tgt)); } else if (PARS("pm_rdisc")) { if (IS_RIP_OUT_OFF(parm.parm_int_state)) return (bad_str(tgt)); parm.parm_int_state |= IS_PM_RDISC; } else if (PARSEQ("rdisc_interval")) { if (parm.parm_rdisc_int != 0 || (parm.parm_rdisc_int = (int)strtoul(buf, &p, 0), *p != '\0') || (buf == p) || parm.parm_rdisc_int < MIN_MAXADVERTISEINTERVAL || parm.parm_rdisc_int > MAX_MAXADVERTISEINTERVAL) return (bad_str(tgt)); } else if (PARSEQ("fake_default")) { if (parm.parm_d_metric != 0 || IS_RIP_OUT_OFF(parm.parm_int_state) || (parm.parm_d_metric = (int)strtoul(buf, &p, 0), *p != '\0') || (buf == p) || parm.parm_d_metric > HOPCNT_INFINITY-1) return (bad_str(tgt)); } else if (PARSEQ("trust_gateway")) { /* look for trust_gateway=x.y.z|net/mask|...) */ p = buf; if (0 > parse_quote(&p, "|", &delim, buf2, sizeof (buf2)) || !gethost(buf2, &addr)) return (bad_str(tgt)); tg = rtmalloc(sizeof (*tg), "parse_parms trust_gateway"); (void) memset(tg, 0, sizeof (*tg)); tg->tgate_addr = addr; i = 0; /* The default is to trust all routes. */ while (delim == '|') { p++; if (i >= MAX_TGATE_NETS || 0 > parse_quote(&p, "|", &delim, buf2, sizeof (buf2)) || !getnet(buf2, &tg->tgate_nets[i].net, &tg->tgate_nets[i].mask) || tg->tgate_nets[i].net == RIP_DEFAULT || tg->tgate_nets[i].mask == 0) { free(tg); return (bad_str(tgt)); } i++; } tg->tgate_next = tgates; tgates = tg; parm.parm_int_state |= IS_DISTRUST; } else if (PARS("redirect_ok")) { parm.parm_int_state |= IS_REDIRECT_OK; } else if (PARSEQ("rip_neighbor")) { if (parm.parm_name[0] == '\0' || gethost(buf, &parm.parm_ripout_addr) != 1) return (bad_str(tgt)); } else { return (bad_str(tgt)); /* error */ } } return (insert_parm(&parm)); #undef PARS #undef PARSEQ #undef CKF }
int ParseKMP(char *cmd, REQUEST_REC *r) { char kmp[STRLEN], proto[STRLEN], data[STRLEN], arg1[STRLEN], arg2[STRLEN], arg3[STRLEN], arg4[STRLEN]; int result; *proto = *data = *arg1 = *arg2 = *arg3 = *arg4 = 0x00; sscanf(cmd, "%s\t%s\t%s\t%s\t%s\t%s", kmp, proto, arg1, arg2, arg3, arg4); #if 0 fprintf(fp_out, "[%s]\r\n", cmd); fprintf(fp_out, "arg1=%s, arg2=%s, arg3=%s, arg4=%s\r\n", arg1, arg2, arg3, arg4); fflush(fp_out); #endif if(!strcmp(proto, "USERNEW")) { sprintf(data, "ID=%s&PASSWORD=%s&PASSWORD1=%s&NICKNAME=%s&EMAIL=%s", arg1, arg2, arg2, arg3, arg4); result = NewUser(data, &curuser); if(result != WEB_OK) { if(strstr(WEBBBS_ERROR_MESSAGE, "帳號已存在") != NULL) fprintf(fp_out, "622 使用者帳號已存在\r\n"); else fprintf(fp_out, "721 註冊失敗\r\n"); } else fprintf(fp_out, "800 OK!!\r\n"); } else if(!strcmp(proto, "USERQUERY")) { if (!get_passwd(&curuser, arg1)) { bzero(&curuser, sizeof(USEREC)); fprintf(fp_out, "621 使用者帳號不存在\r\n"); } else { USER_INFO *quinf; char user_status[1024]; if ((quinf = search_ulist(cmp_userid, curuser.userid)) && !(quinf->invisible)) { sprintf(user_status, "線上狀態: %s, 呼喚鈴: %s.", modestring(quinf, 1), (quinf->pager != PAGER_QUIET) ? MSG_ON : MSG_OFF); } else sprintf(user_status, "目前不在線上"); fprintf(fp_out, "800 OK!!\r\n"); fprintf(fp_out, "%s\t%s\t%d\t%d\t%d\t%d\t%d\t%s\t%s\r\n", curuser.userid, curuser.username, curuser.userlevel, curuser.ident, curuser.numlogins, curuser.numposts, (int)curuser.lastlogin, curuser.lasthost, user_status); } } else if(!strcmp(proto, "USERDATA")) { if(!get_passwd(&curuser, arg1)) bzero(&curuser, sizeof(USEREC)); if(CheckUserPassword(arg1, arg2)!=Correct) fprintf(fp_out, "724 密碼錯誤\r\n"); else { fprintf(fp_out, "800 OK!!\r\n"); fprintf(fp_out, "%d\t%s\t%s\t%d\t%d\t%d\t%s\t%d\t%s\r\n", curuser.uid, curuser.userid, curuser.username, curuser.userlevel, curuser.numlogins, curuser.numposts, curuser.lasthost, curuser.lastctype, curuser.email); } } else if(!strcmp(proto, "USERPLAN")) { if (!get_passwd(&curuser, arg1)) { bzero(&curuser, sizeof(USEREC)); fprintf(fp_out, "621 使用者帳號不存在\r\n"); } else { char userfile[PATHLEN]; sethomefile(userfile, curuser.userid, UFNAME_PLANS); if(isfile(userfile)) { fprintf(fp_out, "800 OK!!\r\n"); ShowArticle(userfile, FALSE, FALSE); } else { fprintf(fp_out, "761 使用者無名片檔\r\n"); } } } else if(!strcmp(proto, "USERLIST")) { int start = 0, end = 0; if(*arg1) start = atoi(arg1); if(*arg2) end = atoi(arg2); #if 0 fprintf(fp_out, "%p %p", post_file, &post_file); fflush(fp_out); #else post_file->list_start = start; post_file->list_end = end; ShowUserList("KMP", post_file); #endif } #if 0 else if(!strcmp(proto, "USERLOGIN")) { result = user_login(&cutmp, &curuser, CTYPE_WEBBBS, arg1, arg2, r->fromhost); if (result == ULOGIN_OK) { memcpy(&uinfo, cutmp, sizeof(USER_INFO)); break; } else if (result == ULOGIN_PASSFAIL) { outs(_msg_formosa_27); continue; } outs(_msg_formosa_44); } #endif return WEB_OK; }
int main(int argc, char **argv) { enum { NNP = CHAR_MAX + 1, RUID, EUID, RGID, EGID, REUID, REGID, CLEAR_GROUPS, KEEP_GROUPS, INIT_GROUPS, GROUPS, INHCAPS, AMBCAPS, LISTCAPS, CAPBSET, SECUREBITS, PDEATHSIG, SELINUX_LABEL, APPARMOR_PROFILE }; static const struct option longopts[] = { { "dump", no_argument, NULL, 'd' }, { "nnp", no_argument, NULL, NNP }, { "no-new-privs", no_argument, NULL, NNP }, { "inh-caps", required_argument, NULL, INHCAPS }, { "ambient-caps", required_argument, NULL, AMBCAPS }, { "list-caps", no_argument, NULL, LISTCAPS }, { "ruid", required_argument, NULL, RUID }, { "euid", required_argument, NULL, EUID }, { "rgid", required_argument, NULL, RGID }, { "egid", required_argument, NULL, EGID }, { "reuid", required_argument, NULL, REUID }, { "regid", required_argument, NULL, REGID }, { "clear-groups", no_argument, NULL, CLEAR_GROUPS }, { "keep-groups", no_argument, NULL, KEEP_GROUPS }, { "init-groups", no_argument, NULL, INIT_GROUPS }, { "groups", required_argument, NULL, GROUPS }, { "bounding-set", required_argument, NULL, CAPBSET }, { "securebits", required_argument, NULL, SECUREBITS }, { "pdeathsig", required_argument, NULL, PDEATHSIG, }, { "selinux-label", required_argument, NULL, SELINUX_LABEL }, { "apparmor-profile", required_argument, NULL, APPARMOR_PROFILE }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; static const ul_excl_t excl[] = { /* keep in same order with enum definitions */ {CLEAR_GROUPS, KEEP_GROUPS, INIT_GROUPS, GROUPS}, {0} }; int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT; int c; struct privctx opts; struct passwd *pw = NULL; int dumplevel = 0; int total_opts = 0; int list_caps = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); memset(&opts, 0, sizeof(opts)); while ((c = getopt_long(argc, argv, "+dhV", longopts, NULL)) != -1) { err_exclusive_options(c, longopts, excl, excl_st); total_opts++; switch (c) { case 'd': dumplevel++; break; case NNP: if (opts.nnp) errx(EXIT_FAILURE, _("duplicate --no-new-privs option")); opts.nnp = 1; break; case RUID: if (opts.have_ruid) errx(EXIT_FAILURE, _("duplicate ruid")); opts.have_ruid = 1; pw = get_passwd(optarg, &opts.ruid, _("failed to parse ruid")); if (pw) { passwd_copy(&opts.passwd, pw); opts.have_passwd = 1; } break; case EUID: if (opts.have_euid) errx(EXIT_FAILURE, _("duplicate euid")); opts.have_euid = 1; opts.euid = get_user(optarg, _("failed to parse euid")); break; case REUID: if (opts.have_ruid || opts.have_euid) errx(EXIT_FAILURE, _("duplicate ruid or euid")); opts.have_ruid = opts.have_euid = 1; pw = get_passwd(optarg, &opts.ruid, _("failed to parse reuid")); opts.euid = opts.ruid; if (pw) { passwd_copy(&opts.passwd, pw); opts.have_passwd = 1; } break; case RGID: if (opts.have_rgid) errx(EXIT_FAILURE, _("duplicate rgid")); opts.have_rgid = 1; opts.rgid = get_group(optarg, _("failed to parse rgid")); break; case EGID: if (opts.have_egid) errx(EXIT_FAILURE, _("duplicate egid")); opts.have_egid = 1; opts.egid = get_group(optarg, _("failed to parse egid")); break; case REGID: if (opts.have_rgid || opts.have_egid) errx(EXIT_FAILURE, _("duplicate rgid or egid")); opts.have_rgid = opts.have_egid = 1; opts.rgid = opts.egid = get_group(optarg, _("failed to parse regid")); break; case CLEAR_GROUPS: if (opts.clear_groups) errx(EXIT_FAILURE, _("duplicate --clear-groups option")); opts.clear_groups = 1; break; case KEEP_GROUPS: if (opts.keep_groups) errx(EXIT_FAILURE, _("duplicate --keep-groups option")); opts.keep_groups = 1; break; case INIT_GROUPS: if (opts.init_groups) errx(EXIT_FAILURE, _("duplicate --init-groups option")); opts.init_groups = 1; break; case GROUPS: if (opts.have_groups) errx(EXIT_FAILURE, _("duplicate --groups option")); parse_groups(&opts, optarg); break; case PDEATHSIG: if (opts.pdeathsig) errx(EXIT_FAILURE, _("duplicate --keep-pdeathsig option")); parse_pdeathsig(&opts, optarg); break; case LISTCAPS: list_caps = 1; break; case INHCAPS: if (opts.caps_to_inherit) errx(EXIT_FAILURE, _("duplicate --inh-caps option")); opts.caps_to_inherit = optarg; break; case AMBCAPS: if (opts.ambient_caps) errx(EXIT_FAILURE, _("duplicate --ambient-caps option")); opts.ambient_caps = optarg; break; case CAPBSET: if (opts.bounding_set) errx(EXIT_FAILURE, _("duplicate --bounding-set option")); opts.bounding_set = optarg; break; case SECUREBITS: if (opts.have_securebits) errx(EXIT_FAILURE, _("duplicate --securebits option")); parse_securebits(&opts, optarg); break; case SELINUX_LABEL: if (opts.selinux_label) errx(EXIT_FAILURE, _("duplicate --selinux-label option")); opts.selinux_label = optarg; break; case APPARMOR_PROFILE: if (opts.apparmor_profile) errx(EXIT_FAILURE, _("duplicate --apparmor-profile option")); opts.apparmor_profile = optarg; break; case 'h': usage(); case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; default: errtryhelp(EXIT_FAILURE); } } if (dumplevel) { if (total_opts != dumplevel || optind < argc) errx(EXIT_FAILURE, _("--dump is incompatible with all other options")); dump(dumplevel); return EXIT_SUCCESS; } if (list_caps) { if (total_opts != 1 || optind < argc) errx(EXIT_FAILURE, _("--list-caps must be specified alone")); list_known_caps(); return EXIT_SUCCESS; } if (argc <= optind) errx(EXIT_FAILURE, _("No program specified")); if ((opts.have_rgid || opts.have_egid) && !opts.keep_groups && !opts.clear_groups && !opts.init_groups && !opts.have_groups) errx(EXIT_FAILURE, _("--[re]gid requires --keep-groups, --clear-groups, --init-groups, or --groups")); if (opts.init_groups && !opts.have_ruid) errx(EXIT_FAILURE, _("--init-groups requires --ruid or --reuid")); if (opts.init_groups && !opts.have_passwd) errx(EXIT_FAILURE, _("uid %ld not found, --init-groups requires an user that " "can be found on the system"), (long) opts.ruid); if (opts.nnp && prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) err(EXIT_FAILURE, _("disallow granting new privileges failed")); if (opts.selinux_label) do_selinux_label(opts.selinux_label); if (opts.apparmor_profile) do_apparmor_profile(opts.apparmor_profile); if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) err(EXIT_FAILURE, _("keep process capabilities failed")); /* We're going to want CAP_SETPCAP, CAP_SETUID, and CAP_SETGID if * possible. */ bump_cap(CAP_SETPCAP); bump_cap(CAP_SETUID); bump_cap(CAP_SETGID); if (capng_apply(CAPNG_SELECT_CAPS) != 0) err(SETPRIV_EXIT_PRIVERR, _("activate capabilities")); if (opts.have_ruid || opts.have_euid) { do_setresuid(&opts); /* KEEPCAPS doesn't work for the effective mask. */ if (capng_apply(CAPNG_SELECT_CAPS) != 0) err(SETPRIV_EXIT_PRIVERR, _("reactivate capabilities")); } if (opts.have_rgid || opts.have_egid) do_setresgid(&opts); if (opts.have_groups) { if (setgroups(opts.num_groups, opts.groups) != 0) err(SETPRIV_EXIT_PRIVERR, _("setgroups failed")); } else if (opts.init_groups) { if (initgroups(opts.passwd.pw_name, opts.passwd.pw_gid) != 0) err(SETPRIV_EXIT_PRIVERR, _("initgroups failed")); } else if (opts.clear_groups) { gid_t x = 0; if (setgroups(0, &x) != 0) err(SETPRIV_EXIT_PRIVERR, _("setgroups failed")); } if (opts.have_securebits && prctl(PR_SET_SECUREBITS, opts.securebits, 0, 0, 0) != 0) err(SETPRIV_EXIT_PRIVERR, _("set process securebits failed")); if (opts.bounding_set) { do_caps(CAP_TYPE_BOUNDING, opts.bounding_set); errno = EPERM; /* capng doesn't set errno if we're missing CAP_SETPCAP */ if (capng_apply(CAPNG_SELECT_BOUNDS) != 0) err(SETPRIV_EXIT_PRIVERR, _("apply bounding set")); } if (opts.caps_to_inherit) { do_caps(CAP_TYPE_INHERITABLE, opts.caps_to_inherit); if (capng_apply(CAPNG_SELECT_CAPS) != 0) err(SETPRIV_EXIT_PRIVERR, _("apply capabilities")); } if (opts.ambient_caps) { do_caps(CAP_TYPE_AMBIENT, opts.ambient_caps); } /* Clear or set parent death signal */ if (opts.pdeathsig && prctl(PR_SET_PDEATHSIG, opts.pdeathsig < 0 ? 0 : opts.pdeathsig) != 0) err(SETPRIV_EXIT_PRIVERR, _("set parent death signal failed")); execvp(argv[optind], argv + optind); errexec(argv[optind]); }